-
Notifications
You must be signed in to change notification settings - Fork 5.3k
JIT: Optimize continuation sizes in MinOpts #123500
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
base: main
Are you sure you want to change the base?
Conversation
|
Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/jit-contrib |
|
/azp run Fuzzlyn |
|
Azure Pipelines successfully started running 1 pipeline(s). |
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.
Pull request overview
Purpose: This PR optimizes the size of async continuations in MinOpts (unoptimized) code by avoiding the capture of unnecessary JIT-created temporary variables. Previously, all locals (including JIT temps) were considered live across async calls in MinOpts. This change leverages the same invariant used by EnC and OSR: in MinOpts, the JIT only creates a specific set of long-lived state (IL locals and spilled IL stack entries).
Changes:
- Adds a new
lvLiveAcrossAsyncbit field toLclVarDscto mark locals that must be preserved across async suspension points in MinOpts - Updates async call setup to aggressively spill IL stack entries to temps and mark them with
lvLiveAcrossAsyncwhen compiling in MinOpts - Modifies
AsyncLiveness::IsLiveto check the new field when liveness information is unavailable, returning true only for IL locals or temps marked as live across async
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/coreclr/jit/compiler.h | Adds lvLiveAcrossAsync bit field to LclVarDsc and updates impSetupAsyncCall signature to accept numILArgs parameter |
| src/coreclr/jit/importercalls.cpp | Updates impSetupAsyncCall to spill IL stack entries around async calls in MinOpts and marks the resulting temps with lvLiveAcrossAsync; passes numILArgs from call signature to impSetupAsyncCall |
| src/coreclr/jit/async.cpp | Marks async ExecutionContext and SynchronizationContext variables with lvLiveAcrossAsync; updates AsyncLiveness::IsLive to check the new field when liveness is unavailable |
|
/azp run Fuzzlyn |
|
Azure Pipelines successfully started running 1 pipeline(s). |
e8324be to
3159721
Compare
Previously we considered all locals to be live across all async calls in MinOpts. This includes JIT created temps. We can avoid saving and restoring these locals based on the same invariant that EnC and OSR use: namely that the JIT creates only a very specific set of long-lived live state in MinOpts.
Unlike EnC and OSR we do have IL stack entries that can be live across async calls. This PR adds a bit to
LclVarDscto mark these locals and then aggressively spills to such temps around async calls when compiling in MinOpts.Fix #116370