Skip to content

Commit f376329

Browse files
JIT: Reuse LSRA's block sequence for initial layout during block reordering (#110921)
Follow-up to #108903. If LSRA did not introduce new basic blocks, we can reuse its block sequence as the initial layout during block reordering, avoiding the overhead of recomputing a loop-aware RPO. Also, delete some unused flowgraph-related `Compiler` members.
1 parent a1ceab3 commit f376329

File tree

4 files changed

+37
-22
lines changed

4 files changed

+37
-22
lines changed

src/coreclr/jit/compiler.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5226,7 +5226,6 @@ class Compiler
52265226
BasicBlock* fgOSREntryBB = nullptr; // For OSR, the logical entry point (~ patchpoint)
52275227
BasicBlock* fgFirstFuncletBB = nullptr; // First block of outlined funclets (to allow block insertion before the funclets)
52285228
BasicBlockList* fgReturnBlocks = nullptr; // list of BBJ_RETURN blocks
5229-
unsigned fgEdgeCount = 0; // # of control flow edges between the BBs
52305229
unsigned fgBBcount = 0; // # of BBs in the method (in the linked list that starts with fgFirstBB)
52315230
#ifdef DEBUG
52325231
jitstd::vector<BasicBlock*>* fgBBOrder = nullptr; // ordered vector of BBs
@@ -5237,8 +5236,6 @@ class Compiler
52375236
bool fgMightHaveNaturalLoops = false;
52385237

52395238
unsigned fgBBNumMax = 0; // The max bbNum that has been assigned to basic blocks
5240-
unsigned fgDomBBcount = 0; // # of BBs for which we have dominator and reachability information
5241-
BasicBlock** fgBBReversePostorder; // Blocks in reverse postorder
52425239

52435240
FlowGraphDfsTree* m_dfsTree = nullptr;
52445241
// The next members are annotations on the flow graph used during the

src/coreclr/jit/fgdiagnostic.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -993,9 +993,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase, PhasePosition pos)
993993
{
994994
fprintf(fgxFile, "\n </blocks>");
995995

996-
fprintf(fgxFile, "\n <edges");
997-
fprintf(fgxFile, "\n edgeCount=\"%d\"", fgEdgeCount);
998-
fprintf(fgxFile, ">");
996+
fprintf(fgxFile, "\n <edges>");
999997
}
1000998

1001999
if (fgPredsComputed)

src/coreclr/jit/fgopt.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4687,27 +4687,35 @@ void Compiler::fgDoReversePostOrderLayout()
46874687
#endif // DEBUG
46884688

46894689
// Compute DFS of all blocks in the method, using profile data to determine the order successors are visited in.
4690-
// Then, identify any loops in the DFS tree so we can keep their bodies compact.
46914690
//
4692-
FlowGraphDfsTree* const dfsTree = fgComputeDfs</* useProfile */ true>();
4693-
FlowGraphNaturalLoops* const loops = FlowGraphNaturalLoops::Find(dfsTree);
4694-
BasicBlock** const rpoSequence = new (this, CMK_BasicBlock) BasicBlock*[dfsTree->GetPostOrderCount()];
4695-
unsigned index = dfsTree->GetPostOrderCount();
4696-
auto addToSequence = [rpoSequence, &index](BasicBlock* block) {
4697-
assert(index != 0);
4698-
rpoSequence[--index] = block;
4699-
};
4691+
FlowGraphDfsTree* const dfsTree = fgComputeDfs</* useProfile */ true>();
4692+
4693+
// If LSRA didn't create any new blocks, we can reuse its loop-aware RPO traversal,
4694+
// which is cached in Compiler::fgBBs.
4695+
// If the cache isn't available, we need to recompute the loop-aware RPO.
4696+
//
4697+
BasicBlock** rpoSequence = fgBBs;
47004698

4701-
fgVisitBlocksInLoopAwareRPO(dfsTree, loops, addToSequence);
4699+
if (rpoSequence == nullptr)
4700+
{
4701+
rpoSequence = new (this, CMK_BasicBlock) BasicBlock*[dfsTree->GetPostOrderCount()];
4702+
FlowGraphNaturalLoops* const loops = FlowGraphNaturalLoops::Find(dfsTree);
4703+
unsigned index = 0;
4704+
auto addToSequence = [rpoSequence, &index](BasicBlock* block) {
4705+
rpoSequence[index++] = block;
4706+
};
4707+
4708+
fgVisitBlocksInLoopAwareRPO(dfsTree, loops, addToSequence);
4709+
}
47024710

47034711
// Fast path: We don't have any EH regions, so just reorder the blocks
47044712
//
47054713
if (compHndBBtabCount == 0)
47064714
{
4707-
for (unsigned i = dfsTree->GetPostOrderCount() - 1; i != 0; i--)
4715+
for (unsigned i = 1; i < dfsTree->GetPostOrderCount(); i++)
47084716
{
4709-
BasicBlock* const block = rpoSequence[i];
4710-
BasicBlock* const blockToMove = rpoSequence[i - 1];
4717+
BasicBlock* const block = rpoSequence[i - 1];
4718+
BasicBlock* const blockToMove = rpoSequence[i];
47114719

47124720
if (!block->NextIs(blockToMove))
47134721
{
@@ -4756,10 +4764,10 @@ void Compiler::fgDoReversePostOrderLayout()
47564764

47574765
// Reorder blocks
47584766
//
4759-
for (unsigned i = dfsTree->GetPostOrderCount() - 1; i != 0; i--)
4767+
for (unsigned i = 1; i < dfsTree->GetPostOrderCount(); i++)
47604768
{
4761-
BasicBlock* const block = rpoSequence[i];
4762-
BasicBlock* const blockToMove = rpoSequence[i - 1];
4769+
BasicBlock* const block = rpoSequence[i - 1];
4770+
BasicBlock* const blockToMove = rpoSequence[i];
47634771

47644772
// Only reorder blocks within the same EH region -- we don't want to make them non-contiguous
47654773
//

src/coreclr/jit/lsra.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,18 @@ PhaseStatus LinearScan::doLinearScan()
13091309

13101310
compiler->compLSRADone = true;
13111311

1312+
// If edge resolution didn't create new blocks,
1313+
// cache the block sequence so it can be used as an initial layout during block reordering.
1314+
if (compiler->fgBBcount == bbSeqCount)
1315+
{
1316+
compiler->fgBBs = blockSequence;
1317+
}
1318+
else
1319+
{
1320+
assert(compiler->fgBBcount > bbSeqCount);
1321+
compiler->fgBBs = nullptr;
1322+
}
1323+
13121324
return PhaseStatus::MODIFIED_EVERYTHING;
13131325
}
13141326

0 commit comments

Comments
 (0)