diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 2bcbe0ee2bd31d..19c9793935679a 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -6377,7 +6377,7 @@ class Compiler void AddNonFallthroughPreds(unsigned blockPos); bool RunGreedyThreeOptPass(unsigned startPos, unsigned endPos); - bool RunThreeOptPass(); + bool RunThreeOpt(); public: ThreeOptLayout(Compiler* comp); diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp index 064c94d6af4107..b7118ffd719e3a 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -5246,13 +5246,6 @@ void Compiler::ThreeOptLayout::Run() assert(finalBlock != nullptr); assert(!finalBlock->isBBCallFinallyPair()); - // For methods with fewer than three candidate blocks, we cannot partition anything - if (finalBlock->IsFirst() || finalBlock->Prev()->IsFirst()) - { - JITDUMP("Not enough blocks to partition anything. Skipping 3-opt.\n"); - return; - } - // Get an upper bound on the number of hot blocks without walking the whole block list. // We will only consider blocks reachable via normal flow. const unsigned numBlocksUpperBound = compiler->m_dfsTree->GetPostOrderCount(); @@ -5269,13 +5262,20 @@ void Compiler::ThreeOptLayout::Run() } assert(numCandidateBlocks < numBlocksUpperBound); - blockOrder[numCandidateBlocks] = tempOrder[numCandidateBlocks] = block; + blockOrder[numCandidateBlocks] = block; // Repurpose 'bbPostorderNum' for the block's ordinal block->bbPostorderNum = numCandidateBlocks++; } - const bool modified = RunThreeOptPass(); + // For methods with fewer than three candidate blocks, we cannot partition anything + if (numCandidateBlocks < 3) + { + JITDUMP("Not enough blocks to partition anything. Skipping reordering.\n"); + return; + } + + const bool modified = RunThreeOpt(); if (modified) { @@ -5504,31 +5504,23 @@ bool Compiler::ThreeOptLayout::RunGreedyThreeOptPass(unsigned startPos, unsigned } //----------------------------------------------------------------------------- -// Compiler::ThreeOptLayout::RunThreeOptPass: Runs 3-opt on the candidate span of blocks. +// Compiler::ThreeOptLayout::RunThreeOpt: Runs 3-opt on the candidate span of blocks. // // Returns: // True if we reordered anything, false otherwise // -bool Compiler::ThreeOptLayout::RunThreeOptPass() +bool Compiler::ThreeOptLayout::RunThreeOpt() { - const unsigned startPos = 0; - const unsigned endPos = numCandidateBlocks - 1; - const unsigned numBlocks = (endPos - startPos + 1); - assert(startPos <= endPos); - - if (numBlocks < 3) - { - JITDUMP("Not enough blocks to partition anything. Skipping reordering.\n"); - return false; - } + // We better have enough blocks to create partitions + assert(numCandidateBlocks > 2); + const unsigned startPos = 0; + const unsigned endPos = numCandidateBlocks - 1; JITDUMP("Initial layout cost: %f\n", GetLayoutCost(startPos, endPos)); const bool modified = RunGreedyThreeOptPass(startPos, endPos); - // Write back to 'tempOrder' so changes to this region aren't lost next time we swap 'tempOrder' and 'blockOrder' if (modified) { - memcpy(tempOrder + startPos, blockOrder + startPos, sizeof(BasicBlock*) * numBlocks); JITDUMP("Final layout cost: %f\n", GetLayoutCost(startPos, endPos)); } else