diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 6a7298cf3d2373..6e40f8e4709207 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -6368,7 +6368,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 8c8376694281f6..4c60646e5c729d 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -5244,13 +5244,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(); @@ -5267,13 +5260,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) { @@ -5502,31 +5502,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