Skip to content

Commit dedb7d1

Browse files
authored
unblock cloning of loops where the header is a try begin (#108604)
1 parent 7f682ef commit dedb7d1

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

src/coreclr/jit/flowgraph.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5964,9 +5964,9 @@ bool FlowGraphNaturalLoop::CanDuplicate(INDEBUG(const char** reason))
59645964

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

src/coreclr/jit/loopcloning.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1929,7 +1929,6 @@ bool Compiler::optIsLoopClonable(FlowGraphNaturalLoop* loop, LoopCloneContext* c
19291929
loop->GetIndex());
19301930
return false;
19311931
}
1932-
19331932
assert(!requireIterable || !lvaVarAddrExposed(iterInfo->IterVar));
19341933

19351934
if (requireIterable)

src/coreclr/jit/optimizer.cpp

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2866,15 +2866,28 @@ bool Compiler::optCreatePreheader(FlowGraphNaturalLoop* loop)
28662866
{
28672867
BasicBlock* header = loop->GetHeader();
28682868

2869-
// If the header is already a try entry then we need to keep it as such
2870-
// since blocks from within the loop will be jumping back to it after we're
2871-
// done. Thus, in that case we insert the preheader in the enclosing try
2872-
// region.
2873-
unsigned headerEHRegion = header->hasTryIndex() ? header->getTryIndex() : EHblkDsc::NO_ENCLOSING_INDEX;
2874-
unsigned preheaderEHRegion = headerEHRegion;
2875-
if ((headerEHRegion != EHblkDsc::NO_ENCLOSING_INDEX) && bbIsTryBeg(header))
2869+
// If all loop backedges sources are within the same try region as the loop header,
2870+
// then the preheader can be in the same try region as the header.
2871+
//
2872+
// Otherwise the preheader must be in the enclosing try region.
2873+
//
2874+
unsigned preheaderEHRegion = EHblkDsc::NO_ENCLOSING_INDEX;
2875+
bool inSameRegionAsHeader = true;
2876+
if (header->hasTryIndex())
28762877
{
2877-
preheaderEHRegion = ehTrueEnclosingTryIndexIL(headerEHRegion);
2878+
preheaderEHRegion = header->getTryIndex();
2879+
for (FlowEdge* backEdge : loop->BackEdges())
2880+
{
2881+
BasicBlock* const backedgeSource = backEdge->getSourceBlock();
2882+
if (!bbInTryRegions(preheaderEHRegion, backedgeSource))
2883+
{
2884+
// Preheader should be in the true enclosing region of the header.
2885+
//
2886+
preheaderEHRegion = ehTrueEnclosingTryIndexIL(preheaderEHRegion);
2887+
inSameRegionAsHeader = false;
2888+
break;
2889+
}
2890+
}
28782891
}
28792892

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

28942907
BasicBlock* preheader = fgNewBBbefore(BBJ_ALWAYS, header, false);
28952908
preheader->SetFlags(BBF_INTERNAL);
2896-
fgSetEHRegionForNewPreheaderOrExit(preheader);
2909+
2910+
if (inSameRegionAsHeader)
2911+
{
2912+
fgExtendEHRegionBefore(header);
2913+
}
2914+
else
2915+
{
2916+
fgSetEHRegionForNewPreheaderOrExit(preheader);
2917+
}
2918+
28972919
preheader->bbCodeOffs = header->bbCodeOffs;
28982920

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

0 commit comments

Comments
 (0)