Skip to content
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

Fix problem with scaling general loop blocks; add dumpers #99742

Conversation

BruceForstall
Copy link
Member

  1. Fix a problem where scaling block weights of a range of basic blocks that compose a general loop could encounter a block that is unreachable. This can happen for various kinds of blocks that the JIT doesn't like to remove even if unreachable. Simply skip scaling those blocks.

  2. Add dumpers for FlowGraphDfsTree and BlockToNaturalLoopMap. These can be called from the debugger (perhaps they should be called to output these things to the JitDump).

  3. Update fgDfsBlocksAndRemove() to dump any blocks that it did not remove, even if they were unreachable.

This was found as part of fixing JitOptRepeat: #94250

1. Fix a problem where scaling block weights of a range of
basic blocks that compose a general loop could encounter a
block that is unreachable. This can happen for various kinds
of blocks that the JIT doesn't like to remove even if unreachable.
Simply skip scaling those blocks.

2. Add dumpers for `FlowGraphDfsTree` and `BlockToNaturalLoopMap`.
These can be called from the debugger (perhaps they should be called
to output these things to the JitDump).

3. Update `fgDfsBlocksAndRemove()` to dump any blocks that it did
not remove, even if they were unreachable.

This was found as part of fixing JitOptRepeat: dotnet#94250
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 14, 2024
@BruceForstall
Copy link
Member Author

@jakobbotsch PTAL
cc @dotnet/jit-contrib

Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

BruceForstall added a commit to BruceForstall/runtime that referenced this pull request Mar 14, 2024
This includes various fixes that are being separately PR'ed:
1. dotnet#99744:
Introduce HandleKindDataIsInvariant helper
2. dotnet#99743:
Add basic support for TYP_MASK constants
3. dotnet#99742:
Fix problem with scaling general loop blocks; add dumpers
4. dotnet#99740:
Add edge likelihood dumping; fix one edge likelihood update case

Also:
1. Add support for running JitOptRepeat under JitStress. This is still
over-written by JitOptRepeat being forced on at 4 iterations.
Comment on lines +3923 to +3924
printf("%02u %02u -> " FMT_BB "[%u, %u]\n", i, rpoNum, block->bbNum, block->bbPreorderNum,
block->bbPostorderNum);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i and block->bbPostorderNum is the same thing here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is a dumper, so this can help verify that in the output.


// Should we call this using the phase method:
// DoPhase(this, PHASE_SET_BLOCK_WEIGHTS, &Compiler::optSetBlockWeights);
// ? It could be called multiple times.
optSetBlockWeights();

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully we'll just end up removing optSetBlockWeights entirely in favor of some profile maintenance that means that this call will just go away at some point.

Comment on lines +5312 to +5328
#ifdef DEBUG
// Did we actually remove all the blocks we said we were going to?
if (verbose)
{
if (m_dfsTree->GetPostOrderCount() != fgBBcount)
{
printf("%u unreachable blocks were not removed:\n", fgBBcount - m_dfsTree->GetPostOrderCount());
for (BasicBlock* block : Blocks())
{
if (!m_dfsTree->Contains(block))
{
printf(" " FMT_BB "\n", block->bbNum);
}
}
}
}
#endif // DEBUG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Luckily the blocks are still removed in the "graph" sense -- they don't have any preds/succs left anymore, so they don't interact with reachable blocks in any way. I.e. asserts like these are ok:

runtime/src/coreclr/jit/morph.cpp

Lines 13833 to 13835 in b60a541

for (BasicBlock* const pred : block->PredBlocks())
{
assert(m_dfsTree->Contains(pred)); // We should have removed dead blocks before this.

But yeah, we still have this annoying case to check for when iterating the block list.

@BruceForstall BruceForstall merged commit 33d737a into dotnet:main Mar 14, 2024
126 of 129 checks passed
@BruceForstall BruceForstall deleted the HandleUnreachableBlocksInGeneralLoopScaling branch March 14, 2024 21:26
@github-actions github-actions bot locked and limited conversation to collaborators Apr 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants