@@ -411,8 +411,6 @@ class LoopInterchangeTransform {
411
411
bool adjustLoopLinks ();
412
412
void adjustLoopPreheaders ();
413
413
bool adjustLoopBranches ();
414
- void updateIncomingBlock (BasicBlock *CurrBlock, BasicBlock *OldPred,
415
- BasicBlock *NewPred);
416
414
417
415
Loop *OuterLoop;
418
416
Loop *InnerLoop;
@@ -455,6 +453,7 @@ struct LoopInterchange : public FunctionPass {
455
453
AU.addPreserved <DominatorTreeWrapperPass>();
456
454
AU.addPreserved <LoopInfoWrapperPass>();
457
455
AU.addPreserved <ScalarEvolutionWrapperPass>();
456
+ AU.addPreservedID (LCSSAID);
458
457
}
459
458
460
459
bool runOnFunction (Function &F) override {
@@ -1297,9 +1296,8 @@ static void moveBBContents(BasicBlock *FromBB, Instruction *InsertBefore) {
1297
1296
FromBB->getTerminator ()->getIterator ());
1298
1297
}
1299
1298
1300
- void LoopInterchangeTransform::updateIncomingBlock (BasicBlock *CurrBlock,
1301
- BasicBlock *OldPred,
1302
- BasicBlock *NewPred) {
1299
+ static void updateIncomingBlock (BasicBlock *CurrBlock, BasicBlock *OldPred,
1300
+ BasicBlock *NewPred) {
1303
1301
for (PHINode &PHI : CurrBlock->phis ()) {
1304
1302
unsigned Num = PHI.getNumIncomingValues ();
1305
1303
for (unsigned i = 0 ; i < Num; ++i) {
@@ -1330,6 +1328,52 @@ static void updateSuccessor(BranchInst *BI, BasicBlock *OldBB,
1330
1328
}
1331
1329
}
1332
1330
1331
+ // Move Lcssa PHIs to the right place.
1332
+ static void moveLCSSAPhis (BasicBlock *InnerExit, BasicBlock *InnerLatch,
1333
+ BasicBlock *OuterLatch) {
1334
+ SmallVector<PHINode *, 8 > LcssaInnerExit;
1335
+ for (PHINode &P : InnerExit->phis ())
1336
+ LcssaInnerExit.push_back (&P);
1337
+
1338
+ SmallVector<PHINode *, 8 > LcssaInnerLatch;
1339
+ for (PHINode &P : InnerLatch->phis ())
1340
+ LcssaInnerLatch.push_back (&P);
1341
+
1342
+ // Lcssa PHIs for values used outside the inner loop are in InnerExit.
1343
+ // If a PHI node has users outside of InnerExit, it has a use outside the
1344
+ // interchanged loop and we have to preserve it. We move these to
1345
+ // InnerLatch, which will become the new exit block for the innermost
1346
+ // loop after interchanging. For PHIs only used in InnerExit, we can just
1347
+ // replace them with the incoming value.
1348
+ for (PHINode *P : LcssaInnerExit) {
1349
+ bool hasUsersOutside = false ;
1350
+ for (auto UI = P->use_begin (), E = P->use_end (); UI != E;) {
1351
+ Use &U = *UI;
1352
+ ++UI;
1353
+ auto *Usr = cast<Instruction>(U.getUser ());
1354
+ if (Usr->getParent () != InnerExit) {
1355
+ hasUsersOutside = true ;
1356
+ continue ;
1357
+ }
1358
+ U.set (P->getIncomingValueForBlock (InnerLatch));
1359
+ }
1360
+ if (hasUsersOutside)
1361
+ P->moveBefore (InnerLatch->getFirstNonPHI ());
1362
+ else
1363
+ P->eraseFromParent ();
1364
+ }
1365
+
1366
+ // If the inner loop latch contains LCSSA PHIs, those come from a child loop
1367
+ // and we have to move them to the new inner latch.
1368
+ for (PHINode *P : LcssaInnerLatch)
1369
+ P->moveBefore (InnerExit->getFirstNonPHI ());
1370
+
1371
+ // Now adjust the incoming blocks for the LCSSA PHIs.
1372
+ // For PHIs moved from Inner's exit block, we need to replace Inner's latch
1373
+ // with the new latch.
1374
+ updateIncomingBlock (InnerLatch, InnerLatch, OuterLatch);
1375
+ }
1376
+
1333
1377
bool LoopInterchangeTransform::adjustLoopBranches () {
1334
1378
LLVM_DEBUG (dbgs () << " adjustLoopBranches called\n " );
1335
1379
std::vector<DominatorTree::UpdateType> DTUpdates;
@@ -1409,17 +1453,6 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
1409
1453
updateSuccessor (InnerLoopLatchPredecessorBI, InnerLoopLatch,
1410
1454
InnerLoopLatchSuccessor, DTUpdates);
1411
1455
1412
- // Adjust PHI nodes in InnerLoopLatchSuccessor. Update all uses of PHI with
1413
- // the value and remove this PHI node from inner loop.
1414
- SmallVector<PHINode *, 8 > LcssaVec;
1415
- for (PHINode &P : InnerLoopLatchSuccessor->phis ())
1416
- LcssaVec.push_back (&P);
1417
-
1418
- for (PHINode *P : LcssaVec) {
1419
- Value *Incoming = P->getIncomingValueForBlock (InnerLoopLatch);
1420
- P->replaceAllUsesWith (Incoming);
1421
- P->eraseFromParent ();
1422
- }
1423
1456
1424
1457
if (OuterLoopLatchBI->getSuccessor (0 ) == OuterLoopHeader)
1425
1458
OuterLoopLatchSuccessor = OuterLoopLatchBI->getSuccessor (1 );
@@ -1431,12 +1464,15 @@ bool LoopInterchangeTransform::adjustLoopBranches() {
1431
1464
updateSuccessor (OuterLoopLatchBI, OuterLoopLatchSuccessor, InnerLoopLatch,
1432
1465
DTUpdates);
1433
1466
1434
- updateIncomingBlock (OuterLoopLatchSuccessor, OuterLoopLatch, InnerLoopLatch);
1435
-
1436
1467
DT->applyUpdates (DTUpdates);
1437
1468
restructureLoops (OuterLoop, InnerLoop, InnerLoopPreHeader,
1438
1469
OuterLoopPreHeader);
1439
1470
1471
+ moveLCSSAPhis (InnerLoopLatchSuccessor, InnerLoopLatch, OuterLoopLatch);
1472
+ // For PHIs in the exit block of the outer loop, outer's latch has been
1473
+ // replaced by Inners'.
1474
+ updateIncomingBlock (OuterLoopLatchSuccessor, OuterLoopLatch, InnerLoopLatch);
1475
+
1440
1476
// Now update the reduction PHIs in the inner and outer loop headers.
1441
1477
SmallVector<PHINode *, 4 > InnerLoopPHIs, OuterLoopPHIs;
1442
1478
for (PHINode &PHI : drop_begin (InnerLoopHeader->phis (), 1 ))
0 commit comments