-
Notifications
You must be signed in to change notification settings - Fork 785
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discussion: Opportunities for cleaner IL generation #871
Comments
Some ideas, speaking as an observer: All of these could definitely be optimized away:
That's what the jit does so it has no performance impact, still looks strange in the IL though. I don't understand the purpose of:
Since it's a compilation error to have a "use" binding with something that's not IDisposable. Candidate for removal too? It's also unfortunate that 2 See also #635 |
@0x53A @asik Yes, in short we would accept high quality, well-tested PRs to improve the IL generated if there's some evidence it improves perf. That said, things like removing the extra "endfinally" is unlikely to improve perf in any mainline case we care about, and it's likely we would judge that the churn-risk associated with making the change may be too great. For example, a bug was injected into F# 4.0 because we accepted an optimization PR that looked ok at code review but actually applied the optimization in invalid situations. It's very expensive to hot-fix such bugs after they creep into shipping versions of F#. If you do delve into this, I expect most changes would be in IlxGen.fs. There is a fair bit of apparatus there already to simplify generated IL. I'll close this because we don't track IL improvement suggestions individually via github issues unless matched by a PR. Though we certainly welcome PRs! :) Best |
Closing - see above comment |
@dsyme Ok thanks for the feedback. I do think there would be some gain by clarified IL, but as you mentioned, that is more than offset by the risk. If I find ( and am able to fix ) anything that affects performance in a noticeable way, I will send a pr. |
Great! I'm converting this thread to what can be a long-running discussion about IL cleanliness (or we could use #635) The tradeoff is also with the complexity of the change. Clean IL is definitely a virtue :) If you find simple ways to remove ldnull/pop pairs, for example, that would be good: Even if you isolate the paths in IlxGen.fs where the ldnull is being generated but not eliminated, that would be useful. Also, ways to avoid the use of locals is very welcome since I believe some of the JIT optimizers use the number of locals in a target method as a decision about whether to inline or not. But locals in exception handling are less important - F# try/catch and try/finally have result values, unlike C#, so it's not to osurprising we use some extra locals for those. |
How about removing some of the "unbox.any" instructions? These appear quite costly if you are using interfaces a bit (In production code, when I have been optimizing inner loops, I have manually coded around it.) I would submit a PR for this, but there is a comment in the GenCoerce function that unbox.any is important in "stack merge points" (which I must confess my ignorance about). Anyway, here is an example of performance issue:
With output of
If I modify the fsharp compiler to remove the unbox.any then I get
This modified compiler passes all the standard .\appveyor-build.cmd tests, so I'm not sure what cases the comment is referring to, so some guidance would be appreciated. |
@manofstick that's a nice cleanup, with perf too, good work!.
i think that's a good requirement because a single issue (like this one) can become noise with multiple parallel discussion. Also the pr can show the code diff, can be commented and the discussion is separated from others, you can add your per test inside a the commit. and it's easy to clone a pr ( |
Closing old discussion, and the work to remove |
I have played around a bit with F# and decompilers, and in many cases F# generates complicated IL.
e.g.
this
compiles to
Edit:
Opportunities in this this simple program
All these would reduce the size of the method from 0x2f (47) to less than 32 instructions.
32 instructions is the magic upper limit for inlining.
The text was updated successfully, but these errors were encountered: