Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT: Add global search option to 3-opt layout #110089

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -6235,8 +6235,9 @@ class Compiler
void ConsiderEdge(FlowEdge* edge);
void AddNonFallthroughSuccs(unsigned blockPos);
void AddNonFallthroughPreds(unsigned blockPos);
bool RunGreedyThreeOptPass(unsigned startPos, unsigned endPos);

bool RunGreedyThreeOptPass(unsigned startPos, unsigned endPos);
bool RunGlobalThreeOptPass(unsigned startPos, unsigned endPos);
bool RunThreeOptPass(BasicBlock* startBlock, BasicBlock* endBlock);

public:
Expand Down
75 changes: 74 additions & 1 deletion src/coreclr/jit/fgopt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5437,6 +5437,78 @@ bool Compiler::ThreeOptLayout::RunGreedyThreeOptPass(unsigned startPos, unsigned
return modified;
}

//-----------------------------------------------------------------------------
// Compiler::ThreeOptLayout::RunGlobalThreeOptPass: Runs 3-opt for the given block range,
// trying every possible cut point until convergence.
//
// Parameters:
// startBlock - The first block of the range to reorder
// endBlock - The last block (inclusive) of the range to reorder
//
// Returns:
// True if we reordered anything, false otherwise
//
// Notes:
// The search for cut points is quadratic on the number of blocks in the region being reordered.
// This search is repeated until the cost model converges.
// This approach is impractically expensive unless the region is small, or already close to an optimal layout.
//
bool Compiler::ThreeOptLayout::RunGlobalThreeOptPass(unsigned startPos, unsigned endPos)
{
assert(startPos < endPos);
bool modified = false, foundPartition;

auto isValidCutPoint = [this](BasicBlock* block) -> bool {
// Don't split up call-finally pairs.
// Also, don't bother reordering handler blocks.
// Finally, don't reorder nested try regions -- we order each region individually.
return !block->isBBCallFinallyPairTail() && !block->hasHndIndex() && (block->bbTryIndex == currEHRegion);
};

JITDUMP("Using global strategy for finding cut points.\n");

do
{
foundPartition = false;
for (unsigned s2Start = startPos + 1; !foundPartition && (s2Start < endPos); s2Start++)
{
BasicBlock* const s2Block = blockOrder[s2Start];
if (!isValidCutPoint(s2Block))
{
continue;
}

for (unsigned s3Start = s2Start + 1; s3Start <= endPos; s3Start++)
{
BasicBlock* const s3Block = blockOrder[s3Start];
if (!isValidCutPoint(s3Block))
{
continue;
}

if (TrySwappingPartitions(startPos, s2Start, s3Start, endPos, endPos))
{
foundPartition = true;
modified = true;
break;
}
}
}
// Keep searching for cut points until the cost model converges
} while (foundPartition);

// Update ordinals, but only if we reordered anything, and if we will do another pass
if (modified && (currEHRegion != 0))
{
for (unsigned i = startPos; i <= endPos; i++)
{
ordinals[blockOrder[i]->bbNum] = i;
}
}

return modified;
}

//-----------------------------------------------------------------------------
// Compiler::ThreeOptLayout::RunThreeOptPass: Runs 3-opt for the given block range.
//
Expand Down Expand Up @@ -5465,7 +5537,8 @@ bool Compiler::ThreeOptLayout::RunThreeOptPass(BasicBlock* startBlock, BasicBloc
}

JITDUMP("Initial layout cost: %f\n", GetLayoutCost(startPos, endPos));
const bool modified = RunGreedyThreeOptPass(startPos, endPos);
const bool modified = JitConfig.JitDoGlobalThreeOpt() ? RunGlobalThreeOptPass(startPos, endPos)
: RunGreedyThreeOptPass(startPos, endPos);

// Write back to 'tempOrder' so changes to this region aren't lost next time we swap 'tempOrder' and 'blockOrder'
if (modified)
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,9 @@ RELEASE_CONFIG_INTEGER(JitEnableCrossBlockLocalAssertionProp, "JitEnableCrossBlo
// Do greedy RPO-based layout in Compiler::fgReorderBlocks.
RELEASE_CONFIG_INTEGER(JitDoReversePostOrderLayout, "JitDoReversePostOrderLayout", 1);

// Globally search for cut points in 3-opt layout instead of using the greedy strategy.
RELEASE_CONFIG_INTEGER(JitDoGlobalThreeOpt, "JitDoGlobalThreeOpt", 1);

// Enable strength reduction
RELEASE_CONFIG_INTEGER(JitEnableStrengthReduction, "JitEnableStrengthReduction", 1)

Expand Down
Loading