-
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: verify full profile consistency after importation #100869
Conversation
Move the full profile check down past the importer. Attempt local repair in the one place the importer may alter flow. If that is unable to guarantee consistency, mark the PGO data as inconsistent. Exempt blocks with EH preds (catches, etc) from imbound checking, as profile data propagation along EH edges is not modelled. Ensure the initial pass of likelihood adjustments pays attention to throws. And only mark throws as rare in the importer if we have not synthesized profile data (which may in fact tell us the throw is not cold). Contributes to dotnet#93020
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
@amanasifkhalid PTAL This causes a bit more churn than I expected... not always marking throws as cold in the importer alters inlining decisions in some cases. The change in |
Some stats from asp.net collection
So the vast majority of methods remain consistent through importation (not as impressive as it sounds, because many methods, especially inlinees, are single basic block...). |
Realized this is not doing as much checking as it should, so there could be more changes needed.. let me fix that. |
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.
Initial pass LGTM. I'll take another look once you update this.
// | ||
BasicBlock* const target = block->GetTarget(); | ||
assert(target->hasProfileWeight()); | ||
target->setBBProfileWeight(target->bbWeight + weight); |
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.
Maybe this is premature, but do you think we should consider changing the block weight API surface sooner rather than later? It might be useful as we do these profile fixups to have something like incrementBBProfileWeight
that asserts the increment amount is positive, and clears the BBF_RUN_RARELY
flag (until we decide to decouple the meaning of this flag from BB_ZERO_WEIGHT
) -- and maybe doesn't touch the BBF_PROF_WEIGHT
flag?
I'm happy to add some new helpers like this, if you think they'd be useful.
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.
Yes, we should do that -- want to get a bit more experience with the updates first, so we can see what patterns are common.
{ | ||
assert(fgProfileWeightsEqual(alternateNewWeight, 0)); | ||
} | ||
alternate->setBBProfileWeight(max(0.0, alternateNewWeight)); |
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.
Ditto my above comment -- maybe something like decrementBBProfileWeight
that does these underflow checks.
@amanasifkhalid take anther look when you can. Changes since your last review:
|
/azp run runtime-coreclr libraries-pgo, runtime-coreclr jitstress, runtime-coreclr pgostress, runtime-coreclr pgo |
Azure Pipelines successfully started running 4 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.
Changes LGTM -- thanks for summarizing them! I'll take another look once you get to the stress failures.
if (!fgPgoSynthesized) | ||
{ | ||
// Any block with a throw is rarely executed. | ||
block->bbSetRunRarely(); |
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.
Following up on the planned BasicBlock
interface changes, I imagine this pattern will come up enough that we'll want to move the check into bbSetRunRarely
(or do some similar cleanup).
Looks like some optional CI failures to sort through. |
jitstress failure is timeout in BinderTracingTest.ResolutionFlow (~ ##97735) libraries-pgo failures look unrelated (~ #98292 ?) pgostress is related, looks like one test case failing across a number of configs, with fully synthesized profile data.
|
In that test we end up re-importing a leave, which creates a dead callfinally/finallyret pair, but we don't clean that up and so downstream code sees some extra bogus preds with profile data after importation:
Here Since reimportation 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.
LGTM, assuming CI passes. Thanks!
I don't see any good reason to rerun the optional CI modes. |
Move the full profile check down past the importer. Attempt local repair for cases where the importer alters BBJ_COND. If that is unable to guarantee consistency, mark the PGO data as inconsistent. If the importer alters BBJ_SWITCH don't attempt repair, just mark the profile as inconsistent. If in an OSR method the original method entry is a loop header, and that is not the loop that triggered OSR, mark the profile as inconsistent. If the importer re-imports a LEAVE, there are still orphaned blocks left from the first importation, these can mess up profiles. In that case, mark the profile as inconsistent. Exempt blocks with EH preds (catches, etc) from inbound checking, as profile data propagation along EH edges is not modelled. Modify the post-phase checks to allow either small relative errors or small absolute errors, so that flow out of EH regions though intermediaries (say step blocks) does not trip the checker. Ensure the initial pass of likelihood adjustments pays attention to throws. And only mark throws as rare in the importer if we have not synthesized profile data (which may in fact tell us the throw is not cold). Contributes to dotnet#93020
Move the full profile check down past the importer. Attempt local repair
for cases where the importer alters BBJ_COND. If that is unable to guarantee
consistency, mark the PGO data as inconsistent.
If the importer alters BBJ_SWITCH don't attempt repair, just mark the profile
as inconsistent.
If in an OSR method the original method entry is a loop header, and that is
not the loop that triggered OSR, mark the profile as inconsistent.
If the importer re-imports a LEAVE, there are still orphaned blocks left from
the first importation, these can mess up profiles. In that case, mark the
profile as inconsistent.
Exempt blocks with EH preds (catches, etc) from inbound checking, as
profile data propagation along EH edges is not modelled.
Modify the post-phase checks to allow either small relative errors or small
absolute errors, so that flow out of EH regions though intermediaries (say
step blocks) does not trip the checker.
Ensure the initial pass of likelihood adjustments pays attention to
throws. And only mark throws as rare in the importer if we have not
synthesized profile data (which may in fact tell us the throw is not cold).
Contributes to #93020