@@ -585,31 +585,31 @@ void SingleExitLoopTransformer::ensureSingleExitBlock() {
585
585
// appropriately and not deal with touching stale memory.
586
586
auto succs = current->getSuccessors ();
587
587
auto *succ = succs[edgeIdx].getBB ();
588
- // Skip if (1) already processed, (2) reached common pd, or (3)
589
- // block has in edges from outside the loop. In the last case, we will
590
- // need to clone the blocks.
588
+ // Skip if (1) already processed or (2) reached common pd.
591
589
if (blocksToBeMoved.count (succ) > 0 || succ == nearestCommonPD) {
592
590
continue ;
593
591
}
594
- // Clone `succ` if it is reachable by a node outside of this loop.
595
- if (!DI->properlyDominates (header, succ)) {
596
- // Backedge of a parent loop? This can happen when we have labeled
597
- // breaks in loops. We cannot clone the blocks in this case.
598
- if (DI->properlyDominates (succ, header)) {
599
- // Split this edge so that we don't mess up arguments passed in
600
- // from other predecessors of succ.
601
- if (succ->getNumArguments () > 0 ) {
602
- splitEdge (current->getTerminator (), edgeIdx, DI, LI);
603
- }
604
- continue ;
605
- }
606
- SILBasicBlock *clonedSucc = cloner.cloneBlock (succ);
607
- changeBranchTarget (current->getTerminator (), edgeIdx, clonedSucc,
608
- /* preserveArgs*/ true );
609
- worklist.insert (clonedSucc);
592
+
593
+ if (DI->properlyDominates (header, succ)) {
594
+ worklist.insert (succ);
610
595
continue ;
611
596
}
612
- worklist.insert (succ);
597
+ // If `succ` is not dominated by `header`, then `succ` is reachable from
598
+ // a node outside of this loop. We might have to clone `succ` in such
599
+ // cases.
600
+
601
+ // Before cloning make sure that header -> succ is *not* backedge of a
602
+ // parent loop. This can happen when we have labeled breaks in loops. We
603
+ // cannot clone the blocks in such cases. Simply continue. This is still
604
+ // OK for our purposes because we will find an equivalent value at the
605
+ // header for any value that escapes along this edge.
606
+ if (DI->properlyDominates (succ, header)) continue ;
607
+
608
+ // Clone the block and rewire the edge.
609
+ SILBasicBlock *clonedSucc = cloner.cloneBlock (succ);
610
+ changeBranchTarget (current->getTerminator (), edgeIdx, clonedSucc,
611
+ /* preserveArgs*/ true );
612
+ worklist.insert (clonedSucc);
613
613
}
614
614
}
615
615
}
@@ -983,9 +983,9 @@ SILBasicBlock *SingleExitLoopTransformer::createNewExitBlockWithDemux(
983
983
return newBlock;
984
984
};
985
985
986
- // Create a new exit block. Strictly, we don't need this block, but it makes
987
- // it slightly easier to implement the demux blocks. contractUncondEdges will
988
- // merge this block away if appropriate.
986
+ // Create a new exit block. Strictly, we don't always need this block, but it
987
+ // makes it slightly easier to implement the demux blocks. contractUncondEdges
988
+ // will merge this block away if appropriate.
989
989
SILBasicBlock *newExitBlock = createBlockOutsideLoop ();
990
990
991
991
SILBuilder builder (newExitBlock);
0 commit comments