-
Notifications
You must be signed in to change notification settings - Fork 5k
JIT: use root compiler instance for sufficient PGO observation #115119
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
During inlining, we evaluate some aspects of an inlinee's viability while importing its direct caller. If that caller is not the inline root we may make inconsistent observations of the overall state of PGO. So for PGO observations always consult the root compiler. For example, the root R may have decided to inline a small method A that did not have PGO (say because of minimal profiling or lack of PGO for always inlined R2R methods), and that method calls another method B; we want to evaluate the viability of B using the PGO state of R, not of A.
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
This PR refactors inlining behavior to ensure that PGO observations are based on the root compiler instance. Key changes include:
- Logging updates in inlinepolicy.cpp to reflect the PGO state of the root compiler.
- Modification in importercalls.cpp to use impInlineRoot()->fgHaveSufficientProfileWeights() for consistency.
- Additional debug messages in fginline.cpp to report the PGO data state.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
File | Description |
---|---|
src/coreclr/jit/inlinepolicy.cpp | Added and refined JITDUMP logging for inline candidate evaluation. |
src/coreclr/jit/importercalls.cpp | Updated to reference the root compiler PGO state. |
src/coreclr/jit/fginline.cpp | Introduced extra debug logging for PGO status in inliner. |
Comments suppressed due to low confidence (3)
src/coreclr/jit/inlinepolicy.cpp:1375
- [nitpick] Consider including additional context—such as the inline candidate identifier—in this debug log for clearer traceability of inlining decisions.
JITDUMP("Callee has trusted profile\n");
src/coreclr/jit/inlinepolicy.cpp:1410
- [nitpick] Consider appending the inline candidate’s identifier to this debug message to improve the clarity and usefulness when diagnosing inlining failures.
JITDUMP("Callee IL size %u exceeds maxCodeSize %u\n", m_CodeSize, maxCodeSize);
src/coreclr/jit/fginline.cpp:790
- [nitpick] Ensure that these verbose debug logs are appropriately gated for production builds to avoid unintended performance impacts.
JITDUMP("INLINER: pgo source is %s; pgo data is %sconsistent; %strusted; %ssufficient\n", compGetPgoSourceName(), fgPgoConsistent ? "" : "not ", fgHaveTrustedProfileWeights() ? "" : "not ", fgHaveSufficientProfileWeights() ? "" : "not ");
@dotnet/jit-contrib PTAL Likely will be difficult to see the impact via SPMI/PMI. |
@@ -9256,7 +9256,7 @@ void Compiler::impCheckCanInline(GenTreeCall* call, | |||
// Profile data allows us to avoid early "too many IL bytes" outs. | |||
// | |||
inlineResult->NoteBool(InlineObservation::CALLSITE_HAS_PROFILE_WEIGHTS, | |||
compiler->fgHaveSufficientProfileWeights()); | |||
compiler->impInlineRoot()->fgHaveSufficientProfileWeights()); |
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.
This is the actual change; the rest is just dumping more state
Lots of missed contexts (2% ish). I will collect a bespoke ASP.NET SPMI to get a clearer picture. |
Locally this seems to be too much (excluding ~800 contexts that don't replay with base)
However most of the big diffs are from OSR methods, and my bespoke SPMI artificially enhances the set of OSR methods.
Going to try restricting this to be non-OSR and see what that looks like |
Still seems quite impactful with OSR using the old behavior -- this is with a local release baseline to rule out possible compiler version issues
Next step might be to introduce some intermediate position, if the root compiler has sufficient PGO but the calling compiler doesn't -- the main impact here to the heuristic is the max IL size the inliner will consider. With sufficient PGO this is 1024, without it's 128. So maybe in this mixed mode we choose some value in between. |
@EgorBo FYI -- seems quite costly still. |
I think the change makes total sense. I guess we can just revert it if the dotnet/performance results won't look like it's worth it |
During inlining, we evaluate some aspects of an inlinee's viability while importing its direct caller. If that caller is not the inline root we may make inconsistent observations of the overall state of PGO. So for PGO observations always consult the root compiler.
For example, the root R may have decided to inline a small method A that did not have PGO (say because of minimal profiling or lack of PGO for always inlined R2R methods), and that method calls another method B; we want to evaluate the viability of B using the PGO state of R, not of A.