-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Jit: run throw helper merge phase before morph #35255
Jit: run throw helper merge phase before morph #35255
Conversation
Now that we have pred lists before morph, we can move the throw helper tail merge phase earlier in the phase list. This has two benefits: * we can now merge a few more cases, because morph can introduce unique temps for otherwise identical calls; * it saves some throughput, because we no longer need to morph duplicate calls. There is more opportunity here to reduce code size if we can find the right heuristic in morph to decide if throw helpers should be called or tail-called, though the overall benefit is small (~600 methods, ~2000k bytes). I left the current heuristic in place as I couldn't come up with anything better. Fixes dotnet#35135.
cc @dotnet/jit-contrib @benaadams Diffs on Bens' example:
Some hits across full FX as well:
The one big regression is block weight/RA related. |
Odd, a comment by @EgorBo was here but vanished. I'll recreate it...
Yes, it could, for reference equality checks. |
@AndyAyersMS |
Thank you; this is very helpful for throw helpers that take larger data types (e.g. |
@dotnet/jit-contrib ping... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just one question.
|
||
for (; !iter.Equal(end); iter++) | ||
{ | ||
BasicBlock* const nonCanonicalBlock = iter.Get(); | ||
BasicBlock* const canonicalBlock = iter.GetValue(); | ||
flowList* nextPredEdge = nullptr; | ||
bool updated = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this new local?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously updateCount
would overstate the number of cases transformed, so I added updated
to get the accounting right.
Admittedly we don't use this now more accurate the count for much. I had ambitions of using it to adjust optNoReturnCallCount
so that the tail call heuristic in morph would also see a more accurate value and hence make better decisions, but doing that made things worse overall (bigger code size).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, github shows diffs inaccurately, which that confused me and I didn't see that there was a semantic change. Previously we incremented updateCount
once per predecessor and now we increment updateCount
once per non-canonical block if there was a predecessor change. That makes sense.
Not sure what's up with the perf leg, am going to ignore it. |
Now that we have pred lists before morph, we can move the throw helper
tail merge phase earlier in the phase list.
This has two benefits:
temps for otherwise identical calls;
calls.
There is more opportunity here to reduce code size if we can find the right
heuristic in morph to decide if throw helpers should be called or tail-called,
though the overall benefit is small (~600 methods, ~2000 bytes). I left the
current heuristic in place as I couldn't come up with anything better.
Fixes #35135.