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: Simplify block insertion logic during loop compaction #107403

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 0 additions & 2 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7064,8 +7064,6 @@ class Compiler

void optCompactLoops();
void optCompactLoop(FlowGraphNaturalLoop* loop);
BasicBlock* optFindLoopCompactionInsertionPoint(FlowGraphNaturalLoop* loop, BasicBlock* top);
BasicBlock* optTryAdvanceLoopCompactionInsertionPoint(FlowGraphNaturalLoop* loop, BasicBlock* insertionPoint, BasicBlock* top, BasicBlock* bottom);
bool optCreatePreheader(FlowGraphNaturalLoop* loop);
void optSetWeightForPreheaderOrExit(FlowGraphNaturalLoop* loop, BasicBlock* block);

Expand Down
135 changes: 1 addition & 134 deletions src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2828,7 +2828,7 @@ void Compiler::optCompactLoop(FlowGraphNaturalLoop* loop)

if (insertionPoint == nullptr)
{
insertionPoint = optFindLoopCompactionInsertionPoint(loop, top);
insertionPoint = loop->GetLexicallyBottomMostBlock();
}

BasicBlock* previous = cur->Prev();
Expand All @@ -2842,8 +2842,6 @@ void Compiler::optCompactLoop(FlowGraphNaturalLoop* loop)
}

// Now physically move the blocks.
BasicBlock* moveBefore = insertionPoint->Next();

fgUnlinkRange(cur, lastNonLoopBlock);
fgMoveBlocksAfter(cur, lastNonLoopBlock, insertionPoint);
ehUpdateLastBlocks(insertionPoint, lastNonLoopBlock);
Expand All @@ -2855,137 +2853,6 @@ void Compiler::optCompactLoop(FlowGraphNaturalLoop* loop)
}
}

//-----------------------------------------------------------------------------
// optFindLoopCompactionInsertionPoint: Find a good insertion point at which to
// move blocks from the lexical range of "loop" that is not part of the loop.
//
// Parameters:
// loop - The loop
// top - Lexical top block of the loop.
//
// Returns:
// Non-null insertion point.
//
BasicBlock* Compiler::optFindLoopCompactionInsertionPoint(FlowGraphNaturalLoop* loop, BasicBlock* top)
{
// Find an insertion point for blocks we're going to move. Move them down
// out of the loop, and if possible find a spot that won't break up fall-through.
BasicBlock* bottom = loop->GetLexicallyBottomMostBlock();
BasicBlock* insertionPoint = bottom;
while (!insertionPoint->IsLast())
{
switch (insertionPoint->GetKind())
{
case BBJ_ALWAYS:
if (!insertionPoint->JumpsToNext())
{
// Found a branch that isn't to the next block, so we won't split up any fall-through.
return insertionPoint;
}
break;

case BBJ_COND:
if (!insertionPoint->FalseTargetIs(insertionPoint->Next()))
{
// Found a conditional branch that doesn't have a false branch to the next block,
// so we won't split up any fall-through.
return insertionPoint;
}
break;

case BBJ_CALLFINALLY:
if (!insertionPoint->isBBCallFinallyPair())
{
// Found a retless BBJ_CALLFINALLY block, so we won't split up any fall-through.
return insertionPoint;
}
break;

default:
// No fall-through to split up.
return insertionPoint;
}

// Keep looking for a better insertion point if we can.
BasicBlock* newInsertionPoint = optTryAdvanceLoopCompactionInsertionPoint(loop, insertionPoint, top, bottom);
if (newInsertionPoint == nullptr)
{
// Ran out of candidate insertion points, so just split up the fall-through.
break;
}

insertionPoint = newInsertionPoint;
}

return insertionPoint;
}

//-----------------------------------------------------------------------------
// optTryAdvanceLoopCompactionInsertionPoint: Advance the insertion point to
// avoid having to insert new blocks due to fallthrough.
//
// Parameters:
// loop - The loop
// insertionPoint - Current insertion point
// top - Lexical top block of the loop.
// bottom - Lexical bottom block of the loop.
//
// Returns:
// New insertion point.
//
BasicBlock* Compiler::optTryAdvanceLoopCompactionInsertionPoint(FlowGraphNaturalLoop* loop,
BasicBlock* insertionPoint,
BasicBlock* top,
BasicBlock* bottom)
{
BasicBlock* newInsertionPoint = insertionPoint->Next();

if (!BasicBlock::sameEHRegion(insertionPoint, newInsertionPoint))
{
// Don't cross an EH region boundary.
return nullptr;
}

// TODO-Quirk: Compatibility with old compaction
if (newInsertionPoint->KindIs(BBJ_ALWAYS, BBJ_COND))
{
BasicBlock* dest =
newInsertionPoint->KindIs(BBJ_ALWAYS) ? newInsertionPoint->GetTarget() : newInsertionPoint->GetTrueTarget();
if ((dest->bbNum >= top->bbNum) && (dest->bbNum <= bottom->bbNum) && !loop->ContainsBlock(dest))
{
return nullptr;
}
}

// TODO-Quirk: Compatibility with old compaction
for (BasicBlock* const predBlock : newInsertionPoint->PredBlocks())
{
if ((predBlock->bbNum >= top->bbNum) && (predBlock->bbNum <= bottom->bbNum) && !loop->ContainsBlock(predBlock))
{
// Don't make this forward edge a backwards edge.
return nullptr;
}
}

// Compaction runs on outer loops before inner loops. That means all
// unlexical blocks here are part of an ancestor loop (or trivial
// BBJ_ALWAYS exit blocks). To avoid breaking lexicality of ancestor loops
// we avoid moving any block past the bottom of an ancestor loop.
for (FlowGraphNaturalLoop* ancestor = loop->GetParent(); ancestor != nullptr; ancestor = ancestor->GetParent())
{
if (newInsertionPoint == ancestor->GetLexicallyBottomMostBlock())
{
return nullptr;
}
}

// Advancing the insertion point is ok, except that we can't split up any call finally
// pair, so if we've got such a pair recurse to see if we can move past the whole thing.
return newInsertionPoint->isBBCallFinallyPair()
? optTryAdvanceLoopCompactionInsertionPoint(loop, newInsertionPoint, top, bottom)
: newInsertionPoint;
}

//-----------------------------------------------------------------------------
// optCreatePreheader: Create (or find) a preheader for a natural loop.
//
Expand Down
Loading