@@ -420,11 +420,13 @@ class BasicBlockCloner : public SILClonerWithScopes<BasicBlockCloner> {
420
420
" times during SESE cloning." );
421
421
}
422
422
423
- // / Clone the body of `loop` starting from `startBlock` and nest the cloned
424
- // / fragment into the parent loop. If `startBlock` is the same as the header
425
- // / of `loop`, we clone the entire loop including the back edge. Otherwise,
426
- // / we clone one iteration of the loop body without the back edge.
427
- SILLoop *cloneLoop (SILLoopInfo *LI, SILLoop *loop, SILBasicBlock *startBlock) {
423
+ // / Utility to unroll one iteration of the loop or to clone the entire loop.
424
+ // / - If `startBlock` is the same as the header of `loop`, we clone the
425
+ // / entire loop including the back edge.
426
+ // / - Otherwise, we unroll one iteration of the loop body starting from
427
+ // / `startBlock' to the latch.
428
+ // / The unrolled or cloned version is nested into the parent loop.
429
+ SILLoop *cloneOrUnrollLoop (SILLoopInfo *LI, SILLoop *loop, SILBasicBlock *startBlock) {
428
430
llvm::DenseMap<SILLoop*, SILLoop*> loopClones;
429
431
// This is for convenience as top-level loops have nullptr for parent loop.
430
432
loopClones[nullptr ] = nullptr ;
@@ -515,6 +517,8 @@ class BasicBlockCloner : public SILClonerWithScopes<BasicBlockCloner> {
515
517
// A helper class to transform a loop to have a single exit from the header.
516
518
class SingleExitLoopTransformer {
517
519
public:
520
+ // Convert the given loop into a SESE form. Returns false if the loop was
521
+ // already in SESE form. Otherwise, returns true.
518
522
static bool doIt (GraphFunctionDeviceInfo *deviceInfo, SILLoopInfo *LI,
519
523
DominanceInfo *DI, SILLoop *loop, PostDominanceInfo *PDI) {
520
524
SingleExitLoopTransformer transformer (deviceInfo, LI, DI, loop, PDI);
@@ -528,7 +532,7 @@ class SingleExitLoopTransformer {
528
532
#ifndef NDEBUG
529
533
{
530
534
// Verify that the loop is OK after all the transformations.
531
- llvm::DenseSet<const SILLoop*> nestedLoops;
535
+ llvm::DenseSet<const SILLoop *> nestedLoops;
532
536
loop->verifyLoopNest (&nestedLoops);
533
537
}
534
538
#endif
@@ -742,9 +746,9 @@ void SingleExitLoopTransformer::ensureSingleExitBlock() {
742
746
// break;
743
747
// }
744
748
// }
749
+ // The unrelated loops are those that are not contained within each other.
745
750
SmallPtrSet<SILBasicBlock *, 32 > unrelatedPreheaders;
746
751
for (auto *otherLoop : *LI) {
747
- // If loop and otherLoop are not nested into either, remember the preheader.
748
752
if (!otherLoop->contains (loop) && !loop->contains (otherLoop)) {
749
753
unrelatedPreheaders.insert (otherLoop->getLoopPreheader ());
750
754
}
@@ -808,8 +812,8 @@ void SingleExitLoopTransformer::ensureSingleExitBlock() {
808
812
// If `succ` is a preheader of an unrelated loop, we will have to clone
809
813
// the entire loop now so that we can also incrementally update LoopInfo.
810
814
if (succBlockLoop) {
811
- SILLoop *clonedLoop =
812
- cloner. cloneLoop ( LI, succBlockLoop, succBlockLoop->getHeader ());
815
+ SILLoop *clonedLoop = cloner. cloneOrUnrollLoop (
816
+ LI, succBlockLoop, succBlockLoop->getHeader ());
813
817
changeBranchTarget (clonedSucc->getTerminator (), 0 ,
814
818
clonedLoop->getHeader (), /* preserveArgs*/ true );
815
819
// Note that all the nodes of `clonedLoop` should be moved into the
@@ -1501,7 +1505,7 @@ void SingleExitLoopTransformer::unrollLoopBodyOnce() {
1501
1505
}
1502
1506
1503
1507
// Clone everything starting from the old header.
1504
- cloner.cloneLoop (LI, loop, header);
1508
+ cloner.cloneOrUnrollLoop (LI, loop, header);
1505
1509
1506
1510
// Get the clone for old header.
1507
1511
SILBasicBlock *clonedOldHeader = cloner.remapBasicBlock (header);
0 commit comments