Skip to content

Commit 6ecede0

Browse files
JIT: Compact blocks in fgMoveBackwardJumpsToSuccessors (#102512)
Follow-up to #102461, and part of #9304. Compacting blocks after establishing an RPO-based layout, but before moving backward jumps to fall into their successors, can enable more opportunities for branch removal; see #9304 for one such example.
1 parent 994a410 commit 6ecede0

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6044,7 +6044,7 @@ class Compiler
60446044

60456045
bool fgCanCompactBlocks(BasicBlock* block, BasicBlock* bNext);
60466046

6047-
void fgCompactBlocks(BasicBlock* block, BasicBlock* bNext);
6047+
void fgCompactBlocks(BasicBlock* block, BasicBlock* bNext DEBUGARG(bool doDebugCheck = true));
60486048

60496049
BasicBlock* fgConnectFallThrough(BasicBlock* bSrc, BasicBlock* bDst);
60506050

src/coreclr/jit/fgopt.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -965,8 +965,10 @@ bool Compiler::fgCanCompactBlocks(BasicBlock* block, BasicBlock* bNext)
965965
// Arguments:
966966
// block - move all code into this block.
967967
// bNext - bbNext of `block`. This block will be removed.
968+
// doDebugCheck - in Debug builds, check flowgraph for correctness after compaction
969+
// (some callers might compact blocks during destructive flowgraph changes, and thus should skip checks)
968970
//
969-
void Compiler::fgCompactBlocks(BasicBlock* block, BasicBlock* bNext)
971+
void Compiler::fgCompactBlocks(BasicBlock* block, BasicBlock* bNext DEBUGARG(bool doDebugCheck /* = true */))
970972
{
971973
noway_assert(block != nullptr);
972974
noway_assert(bNext != nullptr);
@@ -1331,7 +1333,7 @@ void Compiler::fgCompactBlocks(BasicBlock* block, BasicBlock* bNext)
13311333
#endif
13321334

13331335
#if DEBUG
1334-
if (JitConfig.JitSlowDebugChecksEnabled() != 0)
1336+
if (doDebugCheck && (JitConfig.JitSlowDebugChecksEnabled() != 0))
13351337
{
13361338
// Make sure that the predecessor lists are accurate
13371339
fgDebugCheckBBlist();
@@ -4555,6 +4557,23 @@ void Compiler::fgMoveBackwardJumpsToSuccessors()
45554557
}
45564558
#endif // DEBUG
45574559

4560+
// Compact blocks before trying to move any jumps.
4561+
// This can unlock more opportunities for fallthrough behavior.
4562+
//
4563+
for (BasicBlock* block = fgFirstBB; block != fgFirstFuncletBB;)
4564+
{
4565+
if (fgCanCompactBlocks(block, block->Next()))
4566+
{
4567+
// We haven't fixed EH information yet, so don't do any correctness checks here
4568+
//
4569+
fgCompactBlocks(block, block->Next() DEBUGARG(/* doDebugCheck */ false));
4570+
}
4571+
else
4572+
{
4573+
block = block->Next();
4574+
}
4575+
}
4576+
45584577
EnsureBasicBlockEpoch();
45594578
BlockSet visitedBlocks(BlockSetOps::MakeEmpty(this));
45604579
BlockSetOps::AddElemD(this, visitedBlocks, fgFirstBB->bbNum);
@@ -4747,8 +4766,6 @@ void Compiler::fgDoReversePostOrderLayout()
47474766
}
47484767
}
47494768

4750-
fgMoveBackwardJumpsToSuccessors</* hasEH */ true>();
4751-
47524769
// Fix up call-finally pairs
47534770
//
47544771
for (int i = 0; i < callFinallyPairs.Height(); i++)
@@ -4758,6 +4775,8 @@ void Compiler::fgDoReversePostOrderLayout()
47584775
fgInsertBBafter(pair.callFinally, pair.callFinallyRet);
47594776
}
47604777

4778+
fgMoveBackwardJumpsToSuccessors</* hasEH */ true>();
4779+
47614780
// The RPO won't change the entry blocks of any EH regions, but reordering can change the last block in a region
47624781
// (for example, by pushing throw blocks unreachable via normal flow to the end of the region).
47634782
// First, determine the new EH region ends.

0 commit comments

Comments
 (0)