@@ -163,6 +163,9 @@ namespace {
163
163
164
164
// Map between induction variable and its increment
165
165
DenseMap<Instruction *, int64_t > IVToIncMap;
166
+ // For loop with multiple induction variable, remember the one used only to
167
+ // control the loop.
168
+ Instruction *LoopControlIV;
166
169
167
170
// A chain of isomorphic instructions, identified by a single-use PHI
168
171
// representing a reduction. Only the last value may be used outside the
@@ -350,9 +353,11 @@ namespace {
350
353
ScalarEvolution *SE, AliasAnalysis *AA,
351
354
TargetLibraryInfo *TLI, DominatorTree *DT, LoopInfo *LI,
352
355
bool PreserveLCSSA,
353
- DenseMap<Instruction *, int64_t > &IncrMap)
356
+ DenseMap<Instruction *, int64_t > &IncrMap,
357
+ Instruction *LoopCtrlIV)
354
358
: Parent(Parent), L(L), SE(SE), AA(AA), TLI(TLI), DT(DT), LI(LI),
355
- PreserveLCSSA (PreserveLCSSA), IV(IV), IVToIncMap(IncrMap) {}
359
+ PreserveLCSSA (PreserveLCSSA), IV(IV), IVToIncMap(IncrMap),
360
+ LoopControlIV(LoopCtrlIV) {}
356
361
357
362
// / Stage 1: Find all the DAG roots for the induction variable.
358
363
bool findRoots ();
@@ -391,6 +396,7 @@ namespace {
391
396
UsesTy::iterator Start,
392
397
UsesTy::iterator End);
393
398
void replaceIV (Instruction *Inst, Instruction *IV, const SCEV *IterCount);
399
+ void updateNonLoopCtrlIncr ();
394
400
395
401
LoopReroll *Parent;
396
402
@@ -421,8 +427,18 @@ namespace {
421
427
UsesTy Uses;
422
428
// Map between induction variable and its increment
423
429
DenseMap<Instruction *, int64_t > &IVToIncMap;
430
+ Instruction *LoopControlIV;
424
431
};
425
432
433
+ // Check if it is a compare-like instruction whose user is a branch
434
+ bool isCompareUsedByBranch (Instruction *I) {
435
+ auto *TI = I->getParent ()->getTerminator ();
436
+ if (!isa<BranchInst>(TI) || !isa<CmpInst>(I))
437
+ return false ;
438
+ return I->hasOneUse () && TI->getOperand (0 ) == I;
439
+ };
440
+
441
+ bool isLoopControlIV (Loop *L, Instruction *IV);
426
442
void collectPossibleIVs (Loop *L, SmallInstructionVector &PossibleIVs);
427
443
void collectPossibleReductions (Loop *L,
428
444
ReductionTracker &Reductions);
@@ -494,6 +510,60 @@ static const SCEVConstant *getIncrmentFactorSCEV(ScalarEvolution *SE,
494
510
return CIncSCEV;
495
511
}
496
512
513
+ // Check if an IV is only used to control the loop. There are two cases:
514
+ // 1. It only has one use which is loop increment, and the increment is only
515
+ // used by comparison and the PHI, and the comparison is only used by branch.
516
+ // 2. It is used by loop increment and the comparison, the loop increment is
517
+ // only used by the PHI, and the comparison is used only by the branch.
518
+ bool LoopReroll::isLoopControlIV (Loop *L, Instruction *IV) {
519
+
520
+ unsigned IVUses = IV->getNumUses ();
521
+ if (IVUses != 2 && IVUses != 1 )
522
+ return false ;
523
+
524
+ for (auto *User : IV->users ()) {
525
+ int32_t IncOrCmpUses = User->getNumUses ();
526
+ bool IsCompInst = isCompareUsedByBranch (cast<Instruction>(User));
527
+
528
+ // User can only have one or two uses.
529
+ if (IncOrCmpUses != 2 && IncOrCmpUses != 1 )
530
+ return false ;
531
+
532
+ // Case 1
533
+ if (IVUses == 1 ) {
534
+ // The only user must be the loop increment.
535
+ // The loop increment must have two uses.
536
+ if (IsCompInst || IncOrCmpUses != 2 )
537
+ return false ;
538
+ }
539
+
540
+ // Case 2
541
+ if (IVUses == 2 && IncOrCmpUses != 1 )
542
+ return false ;
543
+
544
+ // The users of the IV must be a binary operation or a comparison
545
+ if (auto *BO = dyn_cast<BinaryOperator>(User)) {
546
+ if (BO->getOpcode () == Instruction::Add) {
547
+ // Loop Increment
548
+ // User of Loop Increment should be either PHI or CMP
549
+ for (auto *UU : User->users ()) {
550
+ if (PHINode *PN = dyn_cast<PHINode>(UU)) {
551
+ if (PN != IV)
552
+ return false ;
553
+ }
554
+ // Must be a CMP
555
+ else if (!isCompareUsedByBranch (dyn_cast<Instruction>(UU)))
556
+ return false ;
557
+ }
558
+ } else
559
+ return false ;
560
+ // Compare : can only have one use, and must be branch
561
+ } else if (!IsCompInst)
562
+ return false ;
563
+ }
564
+ return true ;
565
+ }
566
+
497
567
// Collect the list of loop induction variables with respect to which it might
498
568
// be possible to reroll the loop.
499
569
void LoopReroll::collectPossibleIVs (Loop *L,
@@ -525,7 +595,14 @@ void LoopReroll::collectPossibleIVs(Loop *L,
525
595
IVToIncMap[&*I] = IncSCEV->getValue ()->getSExtValue ();
526
596
DEBUG (dbgs () << " LRR: Possible IV: " << *I << " = " << *PHISCEV
527
597
<< " \n " );
528
- PossibleIVs.push_back (&*I);
598
+
599
+ if (isLoopControlIV (L, &*I)) {
600
+ assert (!LoopControlIV && " Found two loop control only IV" );
601
+ LoopControlIV = &(*I);
602
+ DEBUG (dbgs () << " LRR: Possible loop control only IV: " << *I << " = "
603
+ << *PHISCEV << " \n " );
604
+ } else
605
+ PossibleIVs.push_back (&*I);
529
606
}
530
607
}
531
608
}
@@ -1072,6 +1149,28 @@ bool LoopReroll::DAGRootTracker::validate(ReductionTracker &Reductions) {
1072
1149
Uses[I].set (IL_All);
1073
1150
}
1074
1151
1152
+ // Make sure we mark loop-control-only PHIs as used in all iterations. See
1153
+ // comment above LoopReroll::isLoopControlIV for more information.
1154
+ BasicBlock *Header = L->getHeader ();
1155
+ if (LoopControlIV && LoopControlIV != IV) {
1156
+ for (auto *U : LoopControlIV->users ()) {
1157
+ Instruction *IVUser = dyn_cast<Instruction>(U);
1158
+ // IVUser could be loop increment or compare
1159
+ Uses[IVUser].set (IL_All);
1160
+ for (auto *UU : IVUser->users ()) {
1161
+ Instruction *UUser = dyn_cast<Instruction>(UU);
1162
+ // UUser could be compare, PHI or branch
1163
+ Uses[UUser].set (IL_All);
1164
+ // Is UUser a compare instruction?
1165
+ if (UU->hasOneUse ()) {
1166
+ Instruction *BI = dyn_cast<BranchInst>(*UUser->user_begin ());
1167
+ if (BI == cast<BranchInst>(Header->getTerminator ()))
1168
+ Uses[BI].set (IL_All);
1169
+ }
1170
+ }
1171
+ }
1172
+ }
1173
+
1075
1174
// Make sure all instructions in the loop are in one and only one
1076
1175
// set.
1077
1176
for (auto &KV : Uses) {
@@ -1314,25 +1413,65 @@ void LoopReroll::DAGRootTracker::replace(const SCEV *IterCount) {
1314
1413
++J;
1315
1414
}
1316
1415
1317
- // We need to create a new induction variable for each different BaseInst.
1318
- for (auto &DRS : RootSets)
1319
- // Insert the new induction variable.
1320
- replaceIV (DRS.BaseInst , IV, IterCount);
1416
+ bool HasTwoIVs = LoopControlIV && LoopControlIV != IV;
1417
+
1418
+ if (HasTwoIVs) {
1419
+ updateNonLoopCtrlIncr ();
1420
+ replaceIV (LoopControlIV, LoopControlIV, IterCount);
1421
+ } else
1422
+ // We need to create a new induction variable for each different BaseInst.
1423
+ for (auto &DRS : RootSets)
1424
+ // Insert the new induction variable.
1425
+ replaceIV (DRS.BaseInst , IV, IterCount);
1321
1426
1322
1427
SimplifyInstructionsInBlock (Header, TLI);
1323
1428
DeleteDeadPHIs (Header, TLI);
1324
1429
}
1325
1430
1431
+ // For non-loop-control IVs, we only need to update the last increment
1432
+ // with right amount, then we are done.
1433
+ void LoopReroll::DAGRootTracker::updateNonLoopCtrlIncr () {
1434
+ const SCEV *NewInc = nullptr ;
1435
+ for (auto *LoopInc : LoopIncs) {
1436
+ GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LoopInc);
1437
+ const SCEVConstant *COp = nullptr ;
1438
+ if (GEP && LoopInc->getOperand (0 )->getType ()->isPointerTy ()) {
1439
+ COp = dyn_cast<SCEVConstant>(SE->getSCEV (LoopInc->getOperand (1 )));
1440
+ } else {
1441
+ COp = dyn_cast<SCEVConstant>(SE->getSCEV (LoopInc->getOperand (0 )));
1442
+ if (!COp)
1443
+ COp = dyn_cast<SCEVConstant>(SE->getSCEV (LoopInc->getOperand (1 )));
1444
+ }
1445
+
1446
+ assert (COp && " Didn't find constant operand of LoopInc!\n " );
1447
+
1448
+ const APInt &AInt = COp->getValue ()->getValue ();
1449
+ const SCEV *ScaleSCEV = SE->getConstant (COp->getType (), Scale);
1450
+ if (AInt.isNegative ()) {
1451
+ NewInc = SE->getNegativeSCEV (COp);
1452
+ NewInc = SE->getUDivExpr (NewInc, ScaleSCEV);
1453
+ NewInc = SE->getNegativeSCEV (NewInc);
1454
+ } else
1455
+ NewInc = SE->getUDivExpr (COp, ScaleSCEV);
1456
+
1457
+ LoopInc->setOperand (1 , dyn_cast<SCEVConstant>(NewInc)->getValue ());
1458
+ }
1459
+ }
1460
+
1326
1461
void LoopReroll::DAGRootTracker::replaceIV (Instruction *Inst,
1327
1462
Instruction *InstIV,
1328
1463
const SCEV *IterCount) {
1329
1464
BasicBlock *Header = L->getHeader ();
1330
1465
int64_t Inc = IVToIncMap[InstIV];
1331
- bool Negative = Inc < 0 ;
1466
+ bool NeedNewIV = InstIV == LoopControlIV;
1467
+ bool Negative = !NeedNewIV && Inc < 0 ;
1332
1468
1333
1469
const SCEVAddRecExpr *RealIVSCEV = cast<SCEVAddRecExpr>(SE->getSCEV (Inst));
1334
1470
const SCEV *Start = RealIVSCEV->getStart ();
1335
1471
1472
+ if (NeedNewIV)
1473
+ Start = SE->getConstant (Start->getType (), 0 );
1474
+
1336
1475
const SCEV *SizeOfExpr = nullptr ;
1337
1476
const SCEV *IncrExpr =
1338
1477
SE->getConstant (RealIVSCEV->getType (), Negative ? -1 : 1 );
@@ -1360,6 +1499,12 @@ void LoopReroll::DAGRootTracker::replaceIV(Instruction *Inst,
1360
1499
if (Uses[BI].find_first () == IL_All) {
1361
1500
const SCEV *ICSCEV = RealIVSCEV->evaluateAtIteration (IterCount, *SE);
1362
1501
1502
+ if (NeedNewIV)
1503
+ ICSCEV = SE->getMulExpr (IterCount,
1504
+ SE->getConstant (IterCount->getType (), Scale));
1505
+ else
1506
+ ICSCEV = RealIVSCEV->evaluateAtIteration (IterCount, *SE);
1507
+
1363
1508
// Iteration count SCEV minus or plus 1
1364
1509
const SCEV *MinusPlus1SCEV =
1365
1510
SE->getConstant (ICSCEV->getType (), Negative ? -1 : 1 );
@@ -1514,7 +1659,7 @@ bool LoopReroll::reroll(Instruction *IV, Loop *L, BasicBlock *Header,
1514
1659
const SCEV *IterCount,
1515
1660
ReductionTracker &Reductions) {
1516
1661
DAGRootTracker DAGRoots (this , L, IV, SE, AA, TLI, DT, LI, PreserveLCSSA,
1517
- IVToIncMap);
1662
+ IVToIncMap, LoopControlIV );
1518
1663
1519
1664
if (!DAGRoots.findRoots ())
1520
1665
return false ;
@@ -1566,6 +1711,7 @@ bool LoopReroll::runOnLoop(Loop *L, LPPassManager &LPM) {
1566
1711
// reroll (there may be several possible options).
1567
1712
SmallInstructionVector PossibleIVs;
1568
1713
IVToIncMap.clear ();
1714
+ LoopControlIV = nullptr ;
1569
1715
collectPossibleIVs (L, PossibleIVs);
1570
1716
1571
1717
if (PossibleIVs.empty ()) {
0 commit comments