JIT: Repair profile after tail-merging#110656
JIT: Repair profile after tail-merging#110656jakobbotsch wants to merge 2 commits intodotnet:mainfrom
Conversation
We can locally repair PGO data after tail-merging, which should keep global flow preservation. Also, we can do a best-effort repair in the throw-merging phase, but this one is not generally possible to repair locally.
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
|
cc @amanasifkhalid @AndyAyersMS Seems to have some pretty large diffs... but feels like a change to take on principle, since it is just correcting PGO data. Thoughts? |
|
Spot checked a few diffs in aspnet
|
amanasifkhalid
left a comment
There was a problem hiding this comment.
but feels like a change to take on principle, since it is just correcting PGO data. Thoughts?
I agree we ought to do it. I have this change locally somewhere as part of the profile consistency work -- thanks for getting to it first
src/coreclr/jit/fgehopt.cpp
Outdated
| // call means that there is no contribution from nonCanonicalBlock to any of its successors. | ||
| // Note that this might not be the case if we have profile data from e.g. synthesis, so this | ||
| // repair is best-effort only. | ||
| canonicalBlock->bbWeight += removedWeight; |
There was a problem hiding this comment.
I should probably add a helper for this, but the pattern we've been following for propagating profile data is like so:
if (canonicalBlock->hasProfileWeight())
{
canonicalBlock->setBBProfileWeight(canonicalBlock->bbWeight + removedWeight);
}There was a problem hiding this comment.
Updated to follow this pattern. Hopefully at some point hasProfileWeight will be always true and we can get rid of those checks.
There was a problem hiding this comment.
The block weight solver @AndyAyersMS implemented propagates the BBF_PROF_WEIGHT flag to all blocks reachable via normal flow here, so if we start using it relatively early on -- such as a replacement for the current fgComputeBlockWeights and optSetBlockWeights phases -- I imagine we can begin requiring blocks to have profile-derived weights at most flow modification sites.
| // repair is best-effort only. | ||
| if (canonicalBlock->hasProfileWeight()) | ||
| { | ||
| canonicalBlock->setBBProfileWeight(canonicalBlock->bbWeight + removedWeight); |
There was a problem hiding this comment.
If you enable profile consistency checks for throw merging, I suspect this will cause asserts; since we don't convert canonicalBlock into a BBJ_THROW block until morph, the post-phase checks will see new weight into canonicalBlock that isn't being propagated to its successors. If you add some logic to make fgPgoConsistent false here, I think you'll be able to enable profile checks after this phase without issue (though I'm ok with you leaving them off for now, I can enable them in another PR).
Also, sorry for creating merge conflicts here
There was a problem hiding this comment.
Right, the comment above explains the situation. In practice this local update keeps global consistency, but in synthetic cases it does not. That's why I kept the profile checking disabled for this phase. Do you prefer to move the disablement further in favor of setting fgPgoConsistent = false here? If so I'll do that.
There was a problem hiding this comment.
Up to you -- I have the checks enabled in a draft PR (#111047), so I'll have to rebase that on top of this one either way
There was a problem hiding this comment.
Let's just close this one in favor of #111047
|
Subsumed by #111047 |
We can locally repair PGO data after tail-merging, which should keep global flow preservation. Also, we can do a best-effort repair in the throw-merging phase, but this one is not generally possible to repair locally.
Motivated by a case I saw in diffs of #110404.
Before:
(return weight does not match entry weight)
After: