diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 72f2a5d4df848..1c1969f98cd55 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -5226,7 +5226,6 @@ class Compiler BasicBlock* fgOSREntryBB = nullptr; // For OSR, the logical entry point (~ patchpoint) BasicBlock* fgFirstFuncletBB = nullptr; // First block of outlined funclets (to allow block insertion before the funclets) BasicBlockList* fgReturnBlocks = nullptr; // list of BBJ_RETURN blocks - unsigned fgEdgeCount = 0; // # of control flow edges between the BBs unsigned fgBBcount = 0; // # of BBs in the method (in the linked list that starts with fgFirstBB) #ifdef DEBUG jitstd::vector* fgBBOrder = nullptr; // ordered vector of BBs @@ -5237,8 +5236,6 @@ class Compiler bool fgMightHaveNaturalLoops = false; unsigned fgBBNumMax = 0; // The max bbNum that has been assigned to basic blocks - unsigned fgDomBBcount = 0; // # of BBs for which we have dominator and reachability information - BasicBlock** fgBBReversePostorder; // Blocks in reverse postorder FlowGraphDfsTree* m_dfsTree = nullptr; // The next members are annotations on the flow graph used during the diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp index 9003430bb0bcc..642d2d70bb1fb 100644 --- a/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/coreclr/jit/fgdiagnostic.cpp @@ -993,9 +993,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase, PhasePosition pos) { fprintf(fgxFile, "\n "); - fprintf(fgxFile, "\n "); + fprintf(fgxFile, "\n "); } if (fgPredsComputed) diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp index 834a53be776a6..4002c90614529 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -4687,27 +4687,35 @@ void Compiler::fgDoReversePostOrderLayout() #endif // DEBUG // Compute DFS of all blocks in the method, using profile data to determine the order successors are visited in. - // Then, identify any loops in the DFS tree so we can keep their bodies compact. // - FlowGraphDfsTree* const dfsTree = fgComputeDfs(); - FlowGraphNaturalLoops* const loops = FlowGraphNaturalLoops::Find(dfsTree); - BasicBlock** const rpoSequence = new (this, CMK_BasicBlock) BasicBlock*[dfsTree->GetPostOrderCount()]; - unsigned index = dfsTree->GetPostOrderCount(); - auto addToSequence = [rpoSequence, &index](BasicBlock* block) { - assert(index != 0); - rpoSequence[--index] = block; - }; + FlowGraphDfsTree* const dfsTree = fgComputeDfs(); + + // If LSRA didn't create any new blocks, we can reuse its loop-aware RPO traversal, + // which is cached in Compiler::fgBBs. + // If the cache isn't available, we need to recompute the loop-aware RPO. + // + BasicBlock** rpoSequence = fgBBs; - fgVisitBlocksInLoopAwareRPO(dfsTree, loops, addToSequence); + if (rpoSequence == nullptr) + { + rpoSequence = new (this, CMK_BasicBlock) BasicBlock*[dfsTree->GetPostOrderCount()]; + FlowGraphNaturalLoops* const loops = FlowGraphNaturalLoops::Find(dfsTree); + unsigned index = 0; + auto addToSequence = [rpoSequence, &index](BasicBlock* block) { + rpoSequence[index++] = block; + }; + + fgVisitBlocksInLoopAwareRPO(dfsTree, loops, addToSequence); + } // Fast path: We don't have any EH regions, so just reorder the blocks // if (compHndBBtabCount == 0) { - for (unsigned i = dfsTree->GetPostOrderCount() - 1; i != 0; i--) + for (unsigned i = 1; i < dfsTree->GetPostOrderCount(); i++) { - BasicBlock* const block = rpoSequence[i]; - BasicBlock* const blockToMove = rpoSequence[i - 1]; + BasicBlock* const block = rpoSequence[i - 1]; + BasicBlock* const blockToMove = rpoSequence[i]; if (!block->NextIs(blockToMove)) { @@ -4756,10 +4764,10 @@ void Compiler::fgDoReversePostOrderLayout() // Reorder blocks // - for (unsigned i = dfsTree->GetPostOrderCount() - 1; i != 0; i--) + for (unsigned i = 1; i < dfsTree->GetPostOrderCount(); i++) { - BasicBlock* const block = rpoSequence[i]; - BasicBlock* const blockToMove = rpoSequence[i - 1]; + BasicBlock* const block = rpoSequence[i - 1]; + BasicBlock* const blockToMove = rpoSequence[i]; // Only reorder blocks within the same EH region -- we don't want to make them non-contiguous // diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 4d4460b9dea94..c764a7259fba3 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -1309,6 +1309,18 @@ PhaseStatus LinearScan::doLinearScan() compiler->compLSRADone = true; + // If edge resolution didn't create new blocks, + // cache the block sequence so it can be used as an initial layout during block reordering. + if (compiler->fgBBcount == bbSeqCount) + { + compiler->fgBBs = blockSequence; + } + else + { + assert(compiler->fgBBcount > bbSeqCount); + compiler->fgBBs = nullptr; + } + return PhaseStatus::MODIFIED_EVERYTHING; }