Skip to content

Commit

Permalink
unblock cloning of loops where the header is a try begin (#108604)
Browse files Browse the repository at this point in the history
  • Loading branch information
AndyAyersMS authored Oct 15, 2024
1 parent 7f682ef commit dedb7d1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/coreclr/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5964,9 +5964,9 @@ bool FlowGraphNaturalLoop::CanDuplicate(INDEBUG(const char** reason))

Compiler* comp = m_dfsTree->GetCompiler();
BasicBlockVisit result = VisitLoopBlocks([=](BasicBlock* block) {
if (comp->bbIsTryBeg(block))
if (!BasicBlock::sameEHRegion(block, GetHeader()))
{
INDEBUG(*reason = "Loop has a `try` begin");
INDEBUG(*reason = "Loop not entirely within one EH region");
return BasicBlockVisit::Abort;
}

Expand Down
1 change: 0 additions & 1 deletion src/coreclr/jit/loopcloning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1929,7 +1929,6 @@ bool Compiler::optIsLoopClonable(FlowGraphNaturalLoop* loop, LoopCloneContext* c
loop->GetIndex());
return false;
}

assert(!requireIterable || !lvaVarAddrExposed(iterInfo->IterVar));

if (requireIterable)
Expand Down
40 changes: 31 additions & 9 deletions src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2866,15 +2866,28 @@ bool Compiler::optCreatePreheader(FlowGraphNaturalLoop* loop)
{
BasicBlock* header = loop->GetHeader();

// If the header is already a try entry then we need to keep it as such
// since blocks from within the loop will be jumping back to it after we're
// done. Thus, in that case we insert the preheader in the enclosing try
// region.
unsigned headerEHRegion = header->hasTryIndex() ? header->getTryIndex() : EHblkDsc::NO_ENCLOSING_INDEX;
unsigned preheaderEHRegion = headerEHRegion;
if ((headerEHRegion != EHblkDsc::NO_ENCLOSING_INDEX) && bbIsTryBeg(header))
// If all loop backedges sources are within the same try region as the loop header,
// then the preheader can be in the same try region as the header.
//
// Otherwise the preheader must be in the enclosing try region.
//
unsigned preheaderEHRegion = EHblkDsc::NO_ENCLOSING_INDEX;
bool inSameRegionAsHeader = true;
if (header->hasTryIndex())
{
preheaderEHRegion = ehTrueEnclosingTryIndexIL(headerEHRegion);
preheaderEHRegion = header->getTryIndex();
for (FlowEdge* backEdge : loop->BackEdges())
{
BasicBlock* const backedgeSource = backEdge->getSourceBlock();
if (!bbInTryRegions(preheaderEHRegion, backedgeSource))
{
// Preheader should be in the true enclosing region of the header.
//
preheaderEHRegion = ehTrueEnclosingTryIndexIL(preheaderEHRegion);
inSameRegionAsHeader = false;
break;
}
}
}

if (!bbIsHandlerBeg(header) && (loop->EntryEdges().size() == 1))
Expand All @@ -2893,7 +2906,16 @@ bool Compiler::optCreatePreheader(FlowGraphNaturalLoop* loop)

BasicBlock* preheader = fgNewBBbefore(BBJ_ALWAYS, header, false);
preheader->SetFlags(BBF_INTERNAL);
fgSetEHRegionForNewPreheaderOrExit(preheader);

if (inSameRegionAsHeader)
{
fgExtendEHRegionBefore(header);
}
else
{
fgSetEHRegionForNewPreheaderOrExit(preheader);
}

preheader->bbCodeOffs = header->bbCodeOffs;

JITDUMP("Created new preheader " FMT_BB " for " FMT_LP "\n", preheader->bbNum, loop->GetIndex());
Expand Down

0 comments on commit dedb7d1

Please sign in to comment.