64#define DEBUG_TYPE "loop-reroll"
66STATISTIC(NumRerolledLoops,
"Number of rerolled loops");
71 cl::desc(
"The maximum number of failures to tolerate"
72 " during fuzzy matching. (default: 400)"));
151 enum IterationLimits {
153 IL_MaxRerollIterations = 32,
164 : AA(AA), LI(LI), SE(SE), TLI(TLI), DT(DT),
165 PreserveLCSSA(PreserveLCSSA) {}
166 bool runOnLoop(
Loop *L);
185 TinyInstructionVector LoopControlIVs;
190 struct SimpleLoopReduction {
192 assert(isa<PHINode>(
P) &&
"First reduction instruction must be a PHI");
201 assert(Valid &&
"Using invalid reduction");
206 assert(Valid &&
"Using invalid reduction");
211 assert(Valid &&
"Using invalid reduction");
218 size_t size()
const {
219 assert(Valid &&
"Using invalid reduction");
227 assert(Valid &&
"Using invalid reduction");
232 assert(Valid &&
"Using invalid reduction");
248 struct ReductionTracker {
252 void addSLR(SimpleLoopReduction &SLR) { PossibleReds.
push_back(SLR); }
262 void restrictToScale(
uint64_t Scale,
263 SmallInstructionSet &PossibleRedSet,
264 SmallInstructionSet &PossibleRedPHISet,
265 SmallInstructionSet &PossibleRedLastSet) {
266 PossibleRedIdx.clear();
267 PossibleRedIter.clear();
270 for (
unsigned i = 0, e = PossibleReds.size(); i != e; ++i)
271 if (PossibleReds[i].
size() % Scale == 0) {
272 PossibleRedLastSet.insert(PossibleReds[i].getReducedValue());
273 PossibleRedPHISet.insert(PossibleReds[i].getPHI());
275 PossibleRedSet.insert(PossibleReds[i].getPHI());
276 PossibleRedIdx[PossibleReds[i].getPHI()] = i;
278 PossibleRedSet.insert(J);
279 PossibleRedIdx[J] = i;
290 if (J1I != PossibleRedIdx.end()) {
292 if (J2I != PossibleRedIdx.end() && J1I->second == J2I->second)
303 if (PossibleRedIdx.count(J1)) {
304 assert(PossibleRedIdx.count(J2) &&
305 "Recording reduction vs. non-reduction instruction?");
307 PossibleRedIter[J1] = 0;
308 PossibleRedIter[J2] = i;
310 int Idx = PossibleRedIdx[J1];
312 "Recording pair from different reductions?");
320 bool validateSelected();
321 void replaceSelected();
325 SmallReductionVector PossibleReds;
360 SmallInstructionVector Roots;
363 SmallInstructionSet SubsumedInsts;
368 struct DAGRootTracker {
374 TinyInstructionVector LoopCtrlIVs)
375 : Parent(Parent),
L(
L), SE(SE), AA(AA), TLI(TLI), DT(DT), LI(LI),
376 PreserveLCSSA(PreserveLCSSA), IV(IV), IVToIncMap(IncrMap),
377 LoopControlIVs(LoopCtrlIVs) {}
383 bool validate(ReductionTracker &Reductions);
394 SmallInstructionSet SubsumedInsts);
395 bool findRootsBase(
Instruction *IVU, SmallInstructionSet SubsumedInsts);
397 std::map<int64_t,Instruction*> &Roots);
398 bool validateRootSet(DAGRootSet &DRS);
400 bool collectUsedInstructions(SmallInstructionSet &PossibleRedSet);
401 void collectInLoopUserSet(
const SmallInstructionVector &Roots,
402 const SmallInstructionSet &Exclude,
403 const SmallInstructionSet &Final,
406 const SmallInstructionSet &Exclude,
407 const SmallInstructionSet &Final,
411 const SmallInstructionSet &Exclude,
418 void replaceIV(DAGRootSet &DRS,
const SCEV *Start,
const SCEV *IncrExpr);
446 SmallInstructionVector LoopIncs;
456 TinyInstructionVector LoopControlIVs;
461 auto *TI =
I->getParent()->getTerminator();
462 if (!isa<BranchInst>(TI) || !isa<CmpInst>(
I))
464 return I->hasOneUse() && TI->getOperand(0) ==
I;
468 void collectPossibleIVs(
Loop *L, SmallInstructionVector &PossibleIVs);
469 void collectPossibleReductions(
Loop *L,
470 ReductionTracker &Reductions);
472 const SCEV *BackedgeTakenCount, ReductionTracker &Reductions);
481 for (
User *U :
I->users()) {
482 if (!L->contains(cast<Instruction>(U)))
495 unsigned IVUses =
IV->getNumUses();
496 if (IVUses != 2 && IVUses != 1)
499 for (
auto *
User :
IV->users()) {
501 bool IsCompInst = isCompareUsedByBranch(cast<Instruction>(
User));
504 if (IncOrCmpUses != 2 && IncOrCmpUses != 1)
511 if (IsCompInst || IncOrCmpUses != 2)
516 if (IVUses == 2 && IncOrCmpUses != 1)
520 if (
auto *BO = dyn_cast<BinaryOperator>(
User)) {
521 if (BO->getOpcode() == Instruction::Add) {
525 if (
PHINode *PN = dyn_cast<PHINode>(UU)) {
531 auto *UUser = cast<Instruction>(UU);
534 if (BO->hasNoSignedWrap() && UUser->hasOneUse() &&
535 isa<SExtInst>(UUser))
536 UUser = cast<Instruction>(*(UUser->user_begin()));
537 if (!isCompareUsedByBranch(UUser))
544 }
else if (!IsCompInst)
552void LoopReroll::collectPossibleIVs(
Loop *L,
553 SmallInstructionVector &PossibleIVs) {
555 if (!
IV.getType()->isIntegerTy() && !
IV.getType()->isPointerTy())
559 dyn_cast<SCEVAddRecExpr>(SE->
getSCEV(&
IV))) {
560 if (PHISCEV->getLoop() != L)
562 if (!PHISCEV->isAffine())
564 const auto *IncSCEV = dyn_cast<SCEVConstant>(PHISCEV->getStepRecurrence(*SE));
566 IVToIncMap[&
IV] = IncSCEV->getValue()->getSExtValue();
570 if (isLoopControlIV(L, &
IV)) {
571 LoopControlIVs.push_back(&
IV);
573 <<
" = " << *PHISCEV <<
"\n");
575 PossibleIVs.push_back(&
IV);
584void LoopReroll::SimpleLoopReduction::add(
Loop *L) {
585 assert(!Valid &&
"Cannot add to an already-valid chain");
595 C = cast<Instruction>(*
C->user_begin());
596 if (
C->hasOneUse()) {
597 if (!
C->isBinaryOp())
606 }
while (
C->hasOneUse());
614 for (
User *U :
C->users()) {
616 if (
L->contains(cast<Instruction>(U)))
626void LoopReroll::collectPossibleReductions(
Loop *L,
627 ReductionTracker &Reductions) {
630 IE = Header->getFirstInsertionPt();
I != IE; ++
I) {
631 if (!isa<PHINode>(
I))
633 if (!
I->getType()->isSingleValueType())
636 SimpleLoopReduction SLR(&*
I, L);
641 << SLR.size() <<
" chained instructions)\n");
642 Reductions.addSLR(SLR);
658void LoopReroll::DAGRootTracker::collectInLoopUserSet(
659 Instruction *Root,
const SmallInstructionSet &Exclude,
660 const SmallInstructionSet &Final,
662 SmallInstructionVector
Queue(1, Root);
663 while (!
Queue.empty()) {
665 if (!
Users.insert(
I).second)
669 for (
Use &U :
I->uses()) {
673 if (PN->getIncomingBlock(U) ==
L->getHeader())
677 if (
L->contains(
User) && !Exclude.count(
User)) {
683 for (
Use &U :
I->operands()) {
685 if (
Op->hasOneUse() &&
L->contains(Op) && !Exclude.count(Op) &&
694void LoopReroll::DAGRootTracker::collectInLoopUserSet(
695 const SmallInstructionVector &Roots,
696 const SmallInstructionSet &Exclude,
697 const SmallInstructionSet &Final,
700 collectInLoopUserSet(Root, Exclude, Final,
Users);
704 if (
LoadInst *LI = dyn_cast<LoadInst>(
I))
705 return LI->isUnordered();
707 return SI->isUnordered();
709 return !
MI->isVolatile();
718 switch (
I->getOpcode()) {
719 default:
return false;
720 case Instruction::Add:
721 case Instruction::Sub:
722 case Instruction::Mul:
723 case Instruction::Shl:
724 case Instruction::AShr:
725 case Instruction::LShr:
726 case Instruction::GetElementPtr:
727 case Instruction::Trunc:
728 case Instruction::ZExt:
729 case Instruction::SExt:
739 if ((BO && BO->
getOpcode() != Instruction::Add) ||
740 (!BO && !isa<GetElementPtrInst>(U)))
743 for (
auto *UU : U->users()) {
744 PHINode *PN = dyn_cast<PHINode>(UU);
751bool LoopReroll::DAGRootTracker::
752collectPossibleRoots(
Instruction *
Base, std::map<int64_t,Instruction*> &Roots) {
753 SmallInstructionVector BaseUsers;
755 for (
auto *
I :
Base->users()) {
759 LoopIncs.push_back(cast<Instruction>(
I));
764 if (
auto *BO = dyn_cast<BinaryOperator>(
I)) {
765 if (BO->getOpcode() == Instruction::Add ||
766 BO->getOpcode() == Instruction::Or)
767 CI = dyn_cast<ConstantInt>(BO->getOperand(1));
768 }
else if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I)) {
769 Value *LastOperand =
GEP->getOperand(
GEP->getNumOperands()-1);
770 CI = dyn_cast<ConstantInt>(LastOperand);
775 BaseUsers.push_back(II);
785 if (Roots.find(V) != Roots.end())
789 Roots[
V] = cast<Instruction>(
I);
793 if (Roots.empty() || (Roots.size() == 1 && BaseUsers.empty()))
799 if (BaseUsers.size()) {
800 if (Roots.find(0) != Roots.end()) {
801 LLVM_DEBUG(
dbgs() <<
"LRR: Multiple roots found for base - aborting!\n");
808 unsigned NumBaseUses = BaseUsers.size();
809 if (NumBaseUses == 0)
810 NumBaseUses = Roots.begin()->second->getNumUses();
813 for (
auto &KV : Roots) {
816 if (!KV.second->hasNUses(NumBaseUses)) {
817 LLVM_DEBUG(
dbgs() <<
"LRR: Aborting - Root and Base #users not the same: "
818 <<
"#Base=" << NumBaseUses
819 <<
", #Root=" << KV.second->getNumUses() <<
"\n");
827void LoopReroll::DAGRootTracker::
828findRootsRecursive(
Instruction *
I, SmallInstructionSet SubsumedInsts) {
831 if (
I->hasNUsesOrMore(IL_MaxRerollIterations + 1))
834 if (
I !=
IV && findRootsBase(
I, SubsumedInsts))
837 SubsumedInsts.insert(
I);
839 for (
User *V :
I->users()) {
848 findRootsRecursive(
I, SubsumedInsts);
852bool LoopReroll::DAGRootTracker::validateRootSet(DAGRootSet &DRS) {
853 if (DRS.Roots.empty())
871 const auto *
ADR = dyn_cast<SCEVAddRecExpr>(SE->
getSCEV(DRS.BaseInst));
876 unsigned N = DRS.Roots.size() + 1;
881 if (
ADR->getStepRecurrence(*SE) != SE->
getMulExpr(StepSCEV, ScaleSCEV))
885 for (
unsigned i = 1; i <
N - 1; ++i) {
888 if (NewStepSCEV != StepSCEV)
895bool LoopReroll::DAGRootTracker::
896findRootsBase(
Instruction *IVU, SmallInstructionSet SubsumedInsts) {
898 const auto *IVU_ADR = dyn_cast<SCEVAddRecExpr>(SE->
getSCEV(IVU));
899 if (!IVU_ADR || IVU_ADR->getLoop() != L)
902 std::map<int64_t, Instruction*>
V;
903 if (!collectPossibleRoots(IVU, V))
908 if (
V.find(0) ==
V.end())
909 SubsumedInsts.insert(IVU);
913 DRS.BaseInst =
nullptr;
919 DRS.BaseInst = KV.second;
920 DRS.SubsumedInsts = SubsumedInsts;
921 }
else if (DRS.Roots.empty()) {
923 }
else if (
V.find(KV.first - 1) !=
V.end()) {
924 DRS.Roots.push_back(KV.second);
927 if (!validateRootSet(DRS))
932 DRS.BaseInst = KV.second;
937 if (!validateRootSet(DRS))
942 RootSets.append(PotentialRootSets.
begin(), PotentialRootSets.
end());
947bool LoopReroll::DAGRootTracker::findRoots() {
948 Inc = IVToIncMap[
IV];
950 assert(RootSets.empty() &&
"Unclean state!");
951 if (std::abs(Inc) == 1) {
952 for (
auto *IVU :
IV->users()) {
954 LoopIncs.push_back(cast<Instruction>(IVU));
956 findRootsRecursive(
IV, SmallInstructionSet());
957 LoopIncs.push_back(
IV);
959 if (!findRootsBase(
IV, SmallInstructionSet()))
964 if (RootSets.empty()) {
965 LLVM_DEBUG(
dbgs() <<
"LRR: Aborting because no root sets found!\n");
968 for (
auto &V : RootSets) {
969 if (
V.Roots.empty() ||
V.Roots.size() != RootSets[0].Roots.size()) {
972 <<
"LRR: Aborting because not all root sets have the same size\n");
977 Scale = RootSets[0].Roots.size() + 1;
979 if (Scale > IL_MaxRerollIterations) {
980 LLVM_DEBUG(
dbgs() <<
"LRR: Aborting - too many iterations found. "
981 <<
"#Found=" << Scale
982 <<
", #Max=" << IL_MaxRerollIterations <<
"\n");
986 LLVM_DEBUG(
dbgs() <<
"LRR: Successfully found roots: Scale=" << Scale
992bool LoopReroll::DAGRootTracker::collectUsedInstructions(SmallInstructionSet &PossibleRedSet) {
995 for (
auto &
I : *
L->getHeader()) {
996 Uses[&
I].resize(IL_End);
999 SmallInstructionSet Exclude;
1000 for (
auto &DRS : RootSets) {
1001 Exclude.insert(DRS.Roots.begin(), DRS.Roots.end());
1002 Exclude.insert(DRS.SubsumedInsts.begin(), DRS.SubsumedInsts.end());
1003 Exclude.insert(DRS.BaseInst);
1005 Exclude.insert(LoopIncs.begin(), LoopIncs.end());
1007 for (
auto &DRS : RootSets) {
1009 collectInLoopUserSet(DRS.BaseInst, Exclude, PossibleRedSet, VBase);
1010 for (
auto *
I : VBase) {
1015 for (
auto *Root : DRS.Roots) {
1017 collectInLoopUserSet(Root, Exclude, PossibleRedSet, V);
1020 if (
V.size() != VBase.size()) {
1021 LLVM_DEBUG(
dbgs() <<
"LRR: Aborting - use sets are different sizes\n");
1032 for (
auto *
I : DRS.SubsumedInsts) {
1033 Uses[
I].set(IL_All);
1040 for (
auto &DRS : RootSets) {
1041 Exclude.insert(DRS.Roots.begin(), DRS.Roots.end());
1042 Exclude.insert(DRS.SubsumedInsts.begin(), DRS.SubsumedInsts.end());
1043 Exclude.insert(DRS.BaseInst);
1047 collectInLoopUserSet(LoopIncs, Exclude, PossibleRedSet, V);
1049 if (
I->mayHaveSideEffects()) {
1051 <<
"An instruction which does not belong to any root "
1052 <<
"sets must not have side effects: " << *
I);
1055 Uses[
I].set(IL_All);
1065LoopReroll::DAGRootTracker::nextInstr(
int Val, UsesTy &In,
1066 const SmallInstructionSet &Exclude,
1067 UsesTy::iterator *StartI) {
1068 UsesTy::iterator
I = StartI ? *StartI :
In.begin();
1069 while (
I !=
In.end() && (
I->second.test(Val) == 0 ||
1070 Exclude.contains(
I->first)))
1075bool LoopReroll::DAGRootTracker::isBaseInst(
Instruction *
I) {
1076 for (
auto &DRS : RootSets) {
1077 if (DRS.BaseInst ==
I)
1083bool LoopReroll::DAGRootTracker::isRootInst(
Instruction *
I) {
1084 for (
auto &DRS : RootSets) {
1093bool LoopReroll::DAGRootTracker::instrDependsOn(
Instruction *
I,
1094 UsesTy::iterator Start,
1095 UsesTy::iterator End) {
1096 for (
auto *U :
I->users()) {
1097 for (
auto It = Start; It != End; ++It)
1105 if (isa<DbgInfoIntrinsic>(
I))
1113 case Intrinsic::annotation:
1114 case Intrinsic::ptr_annotation:
1115 case Intrinsic::var_annotation:
1123bool LoopReroll::DAGRootTracker::validate(ReductionTracker &Reductions) {
1138 SmallInstructionSet PossibleRedSet;
1139 SmallInstructionSet PossibleRedLastSet;
1140 SmallInstructionSet PossibleRedPHISet;
1141 Reductions.restrictToScale(Scale, PossibleRedSet,
1142 PossibleRedPHISet, PossibleRedLastSet);
1145 if (!collectUsedInstructions(PossibleRedSet))
1149 for (
auto *
I : PossibleRedPHISet) {
1150 Uses[
I].set(IL_All);
1156 for (
Instruction *LoopControlIV : LoopControlIVs) {
1157 for (
auto *U : LoopControlIV->users()) {
1160 Uses[IVUser].set(IL_All);
1161 for (
auto *UU : IVUser->
users()) {
1164 Uses[UUser].set(IL_All);
1166 if (isa<SExtInst>(UUser)) {
1167 UUser = dyn_cast<Instruction>(*(UUser->
user_begin()));
1168 Uses[UUser].set(IL_All);
1171 if (UU->hasOneUse()) {
1173 if (BI == cast<BranchInst>(Header->getTerminator()))
1174 Uses[BI].set(IL_All);
1182 for (
auto &KV :
Uses) {
1185 dbgs() <<
"LRR: Aborting - instruction is not used in 1 iteration: "
1186 << *KV.first <<
" (#uses=" << KV.second.count() <<
")\n");
1193 dbgs() <<
"LRR: " << KV.second.find_first() <<
"\t" << *KV.first <<
"\n";
1197 for (
unsigned Iter = 1; Iter < Scale; ++Iter) {
1202 bool FutureSideEffects =
false;
1208 SmallInstructionSet Visited;
1209 auto BaseIt = nextInstr(0,
Uses, Visited);
1210 auto RootIt = nextInstr(Iter,
Uses, Visited);
1211 auto LastRootIt =
Uses.begin();
1213 while (BaseIt !=
Uses.end() && RootIt !=
Uses.end()) {
1218 bool Continue =
false;
1219 if (isBaseInst(BaseInst)) {
1220 Visited.insert(BaseInst);
1221 BaseIt = nextInstr(0,
Uses, Visited);
1224 if (isRootInst(RootInst)) {
1225 LastRootIt = RootIt;
1226 Visited.insert(RootInst);
1227 RootIt = nextInstr(Iter,
Uses, Visited);
1230 if (Continue)
continue;
1243 auto TryIt = RootIt;
1245 while (TryIt !=
Uses.end() &&
1249 TryIt = nextInstr(Iter,
Uses, Visited, &TryIt);
1252 if (TryIt ==
Uses.end() || TryIt == RootIt ||
1253 instrDependsOn(TryIt->first, RootIt, TryIt)) {
1255 << *BaseInst <<
" vs. " << *RootInst <<
"\n");
1260 RootInst = TryIt->first;
1271 for (; LastRootIt < RootIt; ++LastRootIt) {
1273 if (LastRootIt->second.find_first() < (
int)Iter)
1275 if (
I->mayWriteToMemory())
1284 FutureSideEffects =
true;
1290 if (RootIt->second.count() > 1) {
1291 LLVM_DEBUG(
dbgs() <<
"LRR: iteration root match failed at " << *BaseInst
1292 <<
" vs. " << *RootInst <<
" (prev. case overlap)\n");
1300 for (
auto &K : AST) {
1303 << *BaseInst <<
" vs. " << *RootInst
1304 <<
" (depends on future store)\n");
1318 LLVM_DEBUG(
dbgs() <<
"LRR: iteration root match failed at " << *BaseInst
1319 <<
" vs. " << *RootInst
1320 <<
" (side effects prevent reordering)\n");
1334 bool InReduction = Reductions.isPairInSame(BaseInst, RootInst);
1337 bool Swapped =
false, SomeOpMatched =
false;
1345 if (
Instruction *Op2I = dyn_cast<Instruction>(Op2))
1346 if (Reductions.isPairInSame(RootInst, Op2I))
1350 if (BMI != BaseMap.
end()) {
1353 for (
auto &DRS : RootSets) {
1361 if (BaseInst->
getOperand(Swapped ?
unsigned(!j) : j) != Op2) {
1367 if (!Swapped && BaseInst->
isCommutative() && !SomeOpMatched &&
1372 <<
"LRR: iteration root match failed at " << *BaseInst
1373 <<
" vs. " << *RootInst <<
" (operand " << j <<
")\n");
1378 SomeOpMatched =
true;
1382 if ((!PossibleRedLastSet.count(BaseInst) &&
1384 (!PossibleRedLastSet.count(RootInst) &&
1386 LLVM_DEBUG(
dbgs() <<
"LRR: iteration root match failed at " << *BaseInst
1387 <<
" vs. " << *RootInst <<
" (uses outside loop)\n");
1391 Reductions.recordPair(BaseInst, RootInst, Iter);
1392 BaseMap.
insert(std::make_pair(RootInst, BaseInst));
1394 LastRootIt = RootIt;
1395 Visited.insert(BaseInst);
1396 Visited.insert(RootInst);
1397 BaseIt = nextInstr(0,
Uses, Visited);
1398 RootIt = nextInstr(Iter,
Uses, Visited);
1401 "Mismatched set sizes!");
1410void LoopReroll::DAGRootTracker::replace(
const SCEV *BackedgeTakenCount) {
1417 for (
auto &DRS : RootSets) {
1419 cast<SCEVAddRecExpr>(SE->
getSCEV(DRS.BaseInst));
1426 unsigned I =
Uses[&Inst].find_first();
1427 if (
I > 0 &&
I < IL_All) {
1429 Inst.eraseFromParent();
1434 for (
size_t i = 0, e = RootSets.size(); i != e; ++i)
1436 replaceIV(RootSets[i], StartExprs[i], IncrExprs[i]);
1439 BranchInst *BI = cast<BranchInst>(Header->getTerminator());
1440 const DataLayout &
DL = Header->getModule()->getDataLayout();
1446 Expander.expandCodeFor(NewIVSCEV, BackedgeTakenCount->
getType(),
1447 Header->getFirstNonPHIOrDbg());
1449 auto TripCount = SE->
getAddExpr(BackedgeTakenCount, One);
1452 auto ScaledBECount = SE->
getMinusSCEV(ScaledTripCount, One);
1454 Expander.expandCodeFor(ScaledBECount, BackedgeTakenCount->
getType(),
1455 Header->getFirstNonPHIOrDbg());
1468void LoopReroll::DAGRootTracker::replaceIV(DAGRootSet &DRS,
1470 const SCEV *IncrExpr) {
1474 const SCEV *NewIVSCEV =
1478 const DataLayout &
DL = Header->getModule()->getDataLayout();
1480 Value *NewIV = Expander.expandCodeFor(NewIVSCEV, Inst->
getType(),
1481 Header->getFirstNonPHIOrDbg());
1483 for (
auto &KV :
Uses)
1484 if (KV.second.find_first() == 0)
1485 KV.first->replaceUsesOfWith(Inst, NewIV);
1492bool LoopReroll::ReductionTracker::validateSelected() {
1494 for (
int i : Reds) {
1495 int PrevIter = 0, BaseCount = 0, Count = 0;
1500 int Iter = PossibleRedIter[J];
1501 if (Iter != PrevIter && Iter != PrevIter + 1 &&
1503 LLVM_DEBUG(
dbgs() <<
"LRR: Out-of-order non-associative reduction: "
1508 if (Iter != PrevIter) {
1509 if (Count != BaseCount) {
1511 <<
"LRR: Iteration " << PrevIter <<
" reduction use count "
1512 << Count <<
" is not equal to the base use count "
1513 << BaseCount <<
"\n");
1535void LoopReroll::ReductionTracker::replaceSelected() {
1538 for (
int i : Reds) {
1540 for (
int e = PossibleReds[i].
size();
j !=
e; ++
j)
1541 if (PossibleRedIter[PossibleReds[i][j]] != 0) {
1547 SmallInstructionVector
Users;
1548 for (
User *U : PossibleReds[i].getReducedValue()->
users()) {
1549 Users.push_back(cast<Instruction>(U));
1554 PossibleReds[i][j]);
1602 const SCEV *BackedgeTakenCount,
1603 ReductionTracker &Reductions) {
1604 DAGRootTracker DAGRoots(
this, L,
IV, SE, AA, TLI, DT, LI, PreserveLCSSA,
1605 IVToIncMap, LoopControlIVs);
1607 if (!DAGRoots.findRoots())
1609 LLVM_DEBUG(
dbgs() <<
"LRR: Found all root induction increments for: " << *
IV
1612 if (!DAGRoots.validate(Reductions))
1614 if (!Reductions.validateSelected())
1619 Reductions.replaceSelected();
1620 DAGRoots.replace(BackedgeTakenCount);
1626bool LoopReroll::runOnLoop(
Loop *L) {
1628 LLVM_DEBUG(
dbgs() <<
"LRR: F[" << Header->getParent()->getName() <<
"] Loop %"
1629 << Header->getName() <<
" (" <<
L->getNumBlocks()
1633 if (
L->getNumBlocks() > 1)
1640 LLVM_DEBUG(
dbgs() <<
"\n Before Reroll:\n" << *(
L->getHeader()) <<
"\n");
1641 LLVM_DEBUG(
dbgs() <<
"LRR: backedge-taken count = " << *BackedgeTakenCount
1646 SmallInstructionVector PossibleIVs;
1648 LoopControlIVs.clear();
1649 collectPossibleIVs(L, PossibleIVs);
1651 if (PossibleIVs.empty()) {
1656 ReductionTracker Reductions;
1657 collectPossibleReductions(L, Reductions);
1658 bool Changed =
false;
1663 if (reroll(PossibleIV, L, Header, BackedgeTakenCount, Reductions)) {
1667 LLVM_DEBUG(
dbgs() <<
"\n After Reroll:\n" << *(
L->getHeader()) <<
"\n");
1679 return LoopReroll(&AR.
AA, &AR.
LI, &AR.
SE, &AR.
TLI, &AR.
DT,
true).runOnLoop(&L)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements a class to represent arbitrary precision integral constant values and operations...
SmallPtrSet< MachineInstr *, 2 > Uses
SmallVector< MachineOperand, 4 > Cond
This file implements the BitVector class.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
iv Induction Variable Users
static bool isIgnorableInst(const Instruction *I)
static cl::opt< unsigned > NumToleratedFailedMatches("reroll-num-tolerated-failed-matches", cl::init(400), cl::Hidden, cl::desc("The maximum number of failures to tolerate" " during fuzzy matching. (default: 400)"))
static bool isLoopIncrement(User *U, Instruction *IV)
static bool isSimpleArithmeticOp(User *IVU)
Return true if IVU is a "simple" arithmetic operation.
static bool isUnorderedLoadStore(Instruction *I)
static bool hasUsesOutsideLoop(Instruction *I, Loop *L)
This file implements a map that provides insertion order iteration.
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This defines the Use class.
static bool isAssociative(const COFFSection &Section)
static const uint32_t IV[8]
int64_t getSExtValue() const
Get sign extended value.
A container for analyses that lazily runs them and caches their results.
LLVM Basic Block Representation.
InstListType::iterator iterator
Instruction iterators...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
BinaryOps getOpcode() const
Conditional or Unconditional Branch instruction.
void setCondition(Value *V)
void swapSuccessors()
Swap the successors of this branch instruction.
BasicBlock * getSuccessor(unsigned i) const
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
This instruction compares its operands according to the predicate given to the constructor.
bool isSameOperationAs(const Instruction *I, unsigned flags=0) const LLVM_READONLY
This function determines if the specified instruction executes the same operation as the current one.
bool isAssociative() const LLVM_READONLY
Return true if the instruction is associative:
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
An instruction for reading from memory.
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Represents a single loop in the control flow graph.
This class implements a map that also provides access to all stored values in a deterministic order.
typename VectorType::iterator iterator
This is the common base class for memset/memcpy/memmove.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This node represents a polynomial recurrence on the trip count of the specified loop.
const SCEV * getStart() const
This class uses information about analyze scalars to rewrite expressions in canonical form.
This class represents an analyzed expression in the program.
Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
const SCEV * getConstant(ConstantInt *V)
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
void forgetLoop(const Loop *L)
This method should be called by the client when it has changed a loop in a way that may effect Scalar...
const SCEV * getAddRecExpr(const SCEV *Start, const SCEV *Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
bool hasLoopInvariantBackedgeTakenCount(const Loop *L)
Return true if the specified loop has an analyzable loop-invariant backedge-taken count.
const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Provides information about what library functions are available for the current target.
bool isPointerTy() const
True if this is an instance of PointerType.
A Use represents the edge between a Value definition and its users.
bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
iterator_range< user_iterator > users()
unsigned getNumUses() const
This method computes the number of uses of this Value.
@ C
The default llvm calling convention, compatible with C.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
initializer< Ty > init(const Ty &Val)
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
const_iterator end(StringRef path)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
Scan the specified basic block and try to simplify any instructions in it and recursively delete dead...
bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Examine each PHI in the given block and delete it if it is dead.
auto reverse(ContainerTy &&C)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isModOrRefSet(const ModRefInfo MRI)
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr)
Return true if the instruction does not have any effects besides calculating the result and does not ...
PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
void replace(Container &Cont, typename Container::iterator ContIt, typename Container::iterator ContEnd, RandomAccessIterator ValIt, RandomAccessIterator ValEnd)
Given a sequence container Cont, replace the range [ContIt, ContEnd) with the range [ValIt,...
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...