-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
[release/6.0] JIT: fix scalability issue in redundant branch optimizer #68972
Conversation
In methods with long skinny dominator trees and lots of redundant branches the jit can spend too much time trying to optimize the branches. Place a limit on the number of redundant branches with matching VNs that the jit will consider for a given branch. Fixes #66067.
Tagging subscribers to this area: @JulieLeeMSFT Issue DetailsBackport of #66259 to release/6.0 /cc @AndyAyersMS Customer ImpactTestingRiskIMPORTANT: If this change touches code that ships in a NuGet package, please make certain that you have added any necessary package authoring and gotten it explicitly reviewed.
|
@dotnet/jit-contrib need an approver |
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.
Approved. Can you add a little more detail on why the problem occurs and perhaps include a small IL snippet (if available) on what causes the issue? We will take for consideration in 6.0.x.
cc @JulieLeeMSFT
Added. |
Another ARM64 failure, this time the console log was simply
and the "run" took less than one second:
|
That one is dotnet/arcade#9284 |
@jakobbotsch @AndyAyersMS Please add the |
Backport of #66259 to release/6.0
/cc @AndyAyersMS
Customer Impact
We have now gotten two reports of poor experiences with updating from 5.0 to 6.0 (#68953 and #66076) because a particular IL pattern can cause the JIT to spend an inordinately long time trying to optimize a method.
So far, the problematic patterns seem to come from dynamically generated IL. The problem can be worked around by disabling JIT optimization, but this may not be easy/practical in many cases.
In the case from #68953, there was a method with 38821 bytes of IL, 3782 basic blocks, and 816 recurrences of the IL pattern:
Because we're optimizing this method, this IL sequence gets expanded inline, and turns into a null check on
arg1
followed by a check of the method table and eventually a helper call. The redundant branch optimizer then searches through 28196 pairs of these null checks looking to see if the leading member of the pair makes the trailing member of the pair redundant. It fails in every case.With this fix, the optimizer only considers 3322 such pairs.
Testing
Verified the fix on the customer repro cases. Saw a handful of methods with slightly different codegen via SPMI. From the PR:
SPMI typically runs through ~2M method instances.
Risk
The core algorithm has potentially quadratic behavior. The fix limits the scope of the optimization to a limited number of occurrences so that the quadratic factor doesn't ever grow too large.
Risk is low. We are foregoing a small number of optimizations.