121 #define DEBUG_TYPE "irce" 135 class InductiveRangeCheck {
137 const SCEV *Begin =
nullptr;
138 const SCEV *Step =
nullptr;
139 const SCEV *End =
nullptr;
140 Use *CheckUse =
nullptr;
141 bool IsSigned =
true;
153 const SCEV *getBegin()
const {
return Begin; }
154 const SCEV *getStep()
const {
return Step; }
155 const SCEV *getEnd()
const {
return End; }
156 bool isSigned()
const {
return IsSigned; }
159 OS <<
"InductiveRangeCheck:\n";
166 OS <<
"\n CheckUse: ";
167 getCheckUse()->getUser()->print(OS);
168 OS <<
" Operand: " << getCheckUse()->getOperandNo() <<
"\n";
176 Use *getCheckUse()
const {
return CheckUse; }
186 Range(
const SCEV *Begin,
const SCEV *End) : Begin(Begin), End(End) {
191 const SCEV *getBegin()
const {
return Begin; }
192 const SCEV *getEnd()
const {
return End; }
205 bool getPassingDirection() {
return true; }
212 bool IsLatchSigned)
const;
225 class InductiveRangeCheckElimination {
235 : SE(SE), BPI(BPI), DT(DT), LI(LI) {}
240 class IRCELegacyPass :
public LoopPass {
261 "Inductive range check elimination",
false,
false)
272 InductiveRangeCheck::parseRangeCheckICmp(
Loop *L,
ICmpInst *ICI,
274 Value *&Length,
bool &IsSigned) {
275 auto IsLoopInvariant = [&SE, L](
Value *V) {
276 return SE.isLoopInvariant(SE.getSCEV(V), L);
280 Value *LHS = ICI->getOperand(0);
281 Value *RHS = ICI->getOperand(1);
292 if (
match(RHS, m_ConstantInt<0>())) {
303 if (
match(RHS, m_ConstantInt<-1>())) {
308 if (IsLoopInvariant(LHS)) {
320 if (IsLoopInvariant(LHS)) {
331 void InductiveRangeCheck::extractRangeChecksFromCond(
335 Value *Condition = ConditionUse.
get();
336 if (!Visited.
insert(Condition).second)
341 extractRangeChecksFromCond(L, SE, cast<User>(Condition)->getOperandUse(0),
343 extractRangeChecksFromCond(L, SE, cast<User>(Condition)->getOperandUse(1),
354 if (!parseRangeCheckICmp(L, ICI, SE,
Index, Length, IsSigned))
359 IndexAddRec && (IndexAddRec->getLoop() == L) && IndexAddRec->
isAffine();
364 const SCEV *End =
nullptr;
373 unsigned BitWidth = cast<IntegerType>(IndexAddRec->getType())->
getBitWidth();
378 InductiveRangeCheck IRC;
380 IRC.Begin = IndexAddRec->getStart();
381 IRC.Step = IndexAddRec->getStepRecurrence(SE);
382 IRC.CheckUse = &ConditionUse;
383 IRC.IsSigned = IsSigned;
387 void InductiveRangeCheck::extractRangeChecksFromBranch(
400 InductiveRangeCheck::extractRangeChecksFromCond(L, SE, BI->
getOperandUse(0),
413 Context, {
MDString::get(Context,
"llvm.loop.unroll.disable")});
418 {
MDString::get(Context,
"llvm.loop.vectorize.enable"), FalseVal});
420 Context, {
MDString::get(Context,
"llvm.loop.licm_versioning.disable")});
423 {
MDString::get(Context,
"llvm.loop.distribute.enable"), FalseVal});
426 DisableLICMVersioning, DisableDistribution});
439 struct LoopStructure {
440 const char *Tag =
"";
460 Value *IndVarBase =
nullptr;
461 Value *IndVarStart =
nullptr;
462 Value *IndVarStep =
nullptr;
463 Value *LoopExitAt =
nullptr;
464 bool IndVarIncreasing =
false;
465 bool IsSignedPredicate =
true;
467 LoopStructure() =
default;
469 template <
typename M> LoopStructure map(M Map)
const {
470 LoopStructure Result;
472 Result.Header = cast<BasicBlock>(Map(Header));
473 Result.Latch = cast<BasicBlock>(Map(Latch));
474 Result.LatchBr = cast<BranchInst>(Map(LatchBr));
475 Result.LatchExit = cast<BasicBlock>(Map(LatchExit));
476 Result.LatchBrExitIdx = LatchBrExitIdx;
477 Result.IndVarBase = Map(IndVarBase);
478 Result.IndVarStart = Map(IndVarStart);
479 Result.IndVarStep = Map(IndVarStep);
480 Result.LoopExitAt = Map(LoopExitAt);
481 Result.IndVarIncreasing = IndVarIncreasing;
482 Result.IsSignedPredicate = IsSignedPredicate;
488 Loop &,
const char *&);
499 class LoopConstrainer {
503 std::vector<BasicBlock *> Blocks;
509 LoopStructure Structure;
514 struct RewrittenRangeInfo {
517 std::vector<PHINode *> PHIValuesAtPseudoExit;
520 RewrittenRangeInfo() =
default;
550 void cloneLoop(ClonedLoop &CLResult,
const char *Tag)
const;
554 Loop *createClonedLoopStructure(
Loop *Original,
Loop *Parent,
579 changeIterationSpaceEnd(
const LoopStructure &
LS,
BasicBlock *Preheader,
586 const char *Tag)
const;
592 void rewriteIncomingValuesForPHIs(
593 LoopStructure &LS,
BasicBlock *ContinuationBlockAndPreheader,
594 const LoopConstrainer::RewrittenRangeInfo &RRI)
const;
613 const SCEV *LatchTakenCount =
nullptr;
621 InductiveRangeCheck::Range Range;
625 LoopStructure MainLoopStructure;
633 SE(SE), DT(DT), LI(LI), LPMAddNewLoop(LPMAddNewLoop), OriginalLoop(L),
634 Range(R), MainLoopStructure(LS) {}
652 const SCEV *BoundSCEV,
const SCEV *Step,
654 unsigned LatchBrExitIdx,
671 LLVM_DEBUG(
dbgs() <<
"irce: LatchExitBrIdx: " << LatchBrExitIdx <<
"\n");
679 if (LatchBrExitIdx == 1)
682 assert(LatchBrExitIdx == 0 &&
683 "LatchBrExitIdx should be either 0 or 1");
691 const SCEV *MinusOne =
702 const SCEV *BoundSCEV,
const SCEV *Step,
704 unsigned LatchBrExitIdx,
719 LLVM_DEBUG(
dbgs() <<
"irce: LatchExitBrIdx: " << LatchBrExitIdx <<
"\n");
727 if (LatchBrExitIdx == 1)
730 assert(LatchBrExitIdx == 0 &&
"LatchBrExitIdx should be 0 or 1");
732 const SCEV *StepMinusOne =
747 const char *&FailureReason) {
749 FailureReason =
"loop not in LoopSimplify form";
754 assert(Latch &&
"Simplified loops only have one latch!");
757 FailureReason =
"loop has already been cloned";
762 FailureReason =
"no loop latch";
769 FailureReason =
"no preheader";
775 FailureReason =
"latch terminator not conditional branch";
779 unsigned LatchBrExitIdx = LatchBr->
getSuccessor(0) == Header ? 1 : 0;
787 FailureReason =
"short running loop, not profitable";
793 FailureReason =
"latch terminator branch not conditional on integral icmp";
798 if (isa<SCEVCouldNotCompute>(LatchCount)) {
799 FailureReason =
"could not compute latch count";
812 if (!isa<SCEVAddRecExpr>(LeftSCEV)) {
813 if (isa<SCEVAddRecExpr>(RightSCEV)) {
818 FailureReason =
"no add recurrences in the icmp";
827 IntegerType *Ty = cast<IntegerType>(AR->getType());
835 const SCEV *ExtendedStep =
838 bool NoSignedWrap = ExtendAfterOp->getStart() == ExtendedStart &&
839 ExtendAfterOp->getStepRecurrence(SE) == ExtendedStep;
852 const SCEVAddRecExpr *IndVarBase = cast<SCEVAddRecExpr>(LeftSCEV);
854 FailureReason =
"LHS in icmp not induction variable";
858 if (!isa<SCEVConstant>(StepRec)) {
859 FailureReason =
"LHS in icmp not induction variable";
862 ConstantInt *StepCI = cast<SCEVConstant>(StepRec)->getValue();
864 if (ICI->
isEquality() && !HasNoSignedWrap(IndVarBase)) {
865 FailureReason =
"LHS in icmp needs nsw for equality predicates";
879 bool DecreasedRightValueByOne =
false;
880 if (StepCI->
isOne()) {
905 DecreasedRightValueByOne =
true;
910 DecreasedRightValueByOne =
true;
917 bool FoundExpectedPred =
918 (LTPred && LatchBrExitIdx == 1) || (GTPred && LatchBrExitIdx == 0);
920 if (!FoundExpectedPred) {
921 FailureReason =
"expected icmp slt semantically, found something else";
927 FailureReason =
"unsigned latch conditions are explicitly prohibited";
932 LatchBrExitIdx, &L, SE)) {
933 FailureReason =
"Unsafe loop bounds";
936 if (LatchBrExitIdx == 0) {
939 if (!DecreasedRightValueByOne) {
941 RightValue =
B.CreateAdd(RightValue, One);
944 assert(!DecreasedRightValueByOne &&
945 "Right value can be decreased only for LatchBrExitIdx == 0!");
948 bool IncreasedRightValueByOne =
false;
969 IncreasedRightValueByOne =
true;
973 IncreasedRightValueByOne =
true;
981 bool FoundExpectedPred =
982 (GTPred && LatchBrExitIdx == 1) || (LTPred && LatchBrExitIdx == 0);
984 if (!FoundExpectedPred) {
985 FailureReason =
"expected icmp sgt semantically, found something else";
993 FailureReason =
"unsigned latch conditions are explicitly prohibited";
998 LatchBrExitIdx, &L, SE)) {
999 FailureReason =
"Unsafe bounds";
1003 if (LatchBrExitIdx == 0) {
1006 if (!IncreasedRightValueByOne) {
1008 RightValue =
B.CreateSub(RightValue, One);
1011 assert(!IncreasedRightValueByOne &&
1012 "Right value can be increased only for LatchBrExitIdx == 0!");
1019 "loop variant exit count doesn't make sense!");
1023 Value *IndVarStartV =
1026 IndVarStartV->
setName(
"indvar.start");
1028 LoopStructure Result;
1030 Result.Tag =
"main";
1031 Result.Header = Header;
1032 Result.Latch = Latch;
1033 Result.LatchBr = LatchBr;
1034 Result.LatchExit = LatchExit;
1035 Result.LatchBrExitIdx = LatchBrExitIdx;
1036 Result.IndVarStart = IndVarStartV;
1037 Result.IndVarStep = StepCI;
1038 Result.IndVarBase = LeftValue;
1039 Result.IndVarIncreasing = IsIncreasing;
1040 Result.LoopExitAt = RightValue;
1041 Result.IsSignedPredicate = IsSignedPredicate;
1043 FailureReason =
nullptr;
1049 LoopConstrainer::calculateSubRanges(
bool IsSignedPredicate)
const {
1050 IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType());
1052 if (Range.getType() != Ty)
1055 LoopConstrainer::SubRanges Result;
1060 const SCEV *Start = SE.
getSCEV(MainLoopStructure.IndVarStart);
1061 const SCEV *End = SE.
getSCEV(MainLoopStructure.LoopExitAt);
1063 bool Increasing = MainLoopStructure.IndVarIncreasing;
1069 const SCEV *Smallest =
nullptr, *Greatest =
nullptr, *GreatestSeen =
nullptr;
1095 GreatestSeen = Start;
1098 auto Clamp = [
this, Smallest, Greatest, IsSignedPredicate](
const SCEV *S) {
1099 return IsSignedPredicate
1110 bool ProvablyNoPreloop =
1112 if (!ProvablyNoPreloop)
1113 Result.LowLimit = Clamp(Range.getBegin());
1115 bool ProvablyNoPostLoop =
1117 if (!ProvablyNoPostLoop)
1118 Result.HighLimit = Clamp(Range.getEnd());
1123 void LoopConstrainer::cloneLoop(LoopConstrainer::ClonedLoop &Result,
1124 const char *Tag)
const {
1125 for (
BasicBlock *BB : OriginalLoop.getBlocks()) {
1127 Result.Blocks.push_back(Clone);
1128 Result.Map[BB] = Clone;
1131 auto GetClonedValue = [&Result](
Value *V) {
1132 assert(V &&
"null values not in domain!");
1133 auto It = Result.Map.find(V);
1134 if (It == Result.Map.end())
1136 return static_cast<Value *
>(It->second);
1140 cast<BasicBlock>(GetClonedValue(OriginalLoop.getLoopLatch()));
1144 Result.Structure = MainLoopStructure.map(GetClonedValue);
1145 Result.Structure.Tag = Tag;
1147 for (
unsigned i = 0, e = Result.Blocks.size(); i != e; ++i) {
1149 BasicBlock *OriginalBB = OriginalLoop.getBlocks()[i];
1151 assert(Result.Map[OriginalBB] == ClonedBB &&
"invariant!");
1162 if (OriginalLoop.contains(
SBB))
1167 PN.
addIncoming(GetClonedValue(OldIncoming), ClonedBB);
1173 LoopConstrainer::RewrittenRangeInfo LoopConstrainer::changeIterationSpaceEnd(
1247 RewrittenRangeInfo RRI;
1249 BasicBlock *BBInsertLocation = LS.Latch->getNextNode();
1251 &
F, BBInsertLocation);
1256 bool Increasing = LS.IndVarIncreasing;
1257 bool IsSignedPredicate = LS.IsSignedPredicate;
1262 Value *EnterLoopCond =
nullptr;
1267 EnterLoopCond = B.
CreateICmp(Pred, LS.IndVarStart, ExitSubloopAt);
1269 B.
CreateCondBr(EnterLoopCond, LS.Header, RRI.PseudoExit);
1272 LS.LatchBr->setSuccessor(LS.LatchBrExitIdx, RRI.ExitSelector);
1277 Value *CondForBranch = LS.LatchBrExitIdx == 1
1278 ? TakeBackedgeLoopCond
1281 LS.LatchBr->setCondition(CondForBranch);
1288 Value *IterationsLeft = B.
CreateICmp(Pred, LS.IndVarBase, LS.LoopExitAt);
1289 B.
CreateCondBr(IterationsLeft, RRI.PseudoExit, LS.LatchExit);
1297 for (
PHINode &PN : LS.Header->phis()) {
1299 BranchToContinuation);
1304 RRI.PHIValuesAtPseudoExit.push_back(NewPHI);
1307 RRI.IndVarEnd =
PHINode::Create(LS.IndVarBase->getType(), 2,
"indvar.end",
1308 BranchToContinuation);
1309 RRI.IndVarEnd->addIncoming(LS.IndVarStart, Preheader);
1310 RRI.IndVarEnd->addIncoming(LS.IndVarBase, RRI.ExitSelector);
1314 for (
PHINode &PN : LS.LatchExit->phis())
1315 replacePHIBlock(&PN, LS.Latch, RRI.ExitSelector);
1320 void LoopConstrainer::rewriteIncomingValuesForPHIs(
1321 LoopStructure &LS,
BasicBlock *ContinuationBlock,
1322 const LoopConstrainer::RewrittenRangeInfo &RRI)
const {
1323 unsigned PHIIndex = 0;
1324 for (
PHINode &PN : LS.Header->phis())
1329 LS.IndVarStart = RRI.IndVarEnd;
1332 BasicBlock *LoopConstrainer::createPreheader(
const LoopStructure &LS,
1334 const char *Tag)
const {
1338 for (
PHINode &PN : LS.Header->phis())
1340 replacePHIBlock(&PN, OldPreheader, Preheader);
1354 Loop *LoopConstrainer::createClonedLoopStructure(
Loop *Original,
Loop *Parent,
1357 Loop &New = *LI.AllocateLoop();
1361 LI.addTopLevelLoop(&New);
1362 LPMAddNewLoop(&New, IsSubloop);
1365 for (
auto *BB : Original->
blocks())
1366 if (LI.getLoopFor(BB) == Original)
1370 for (
Loop *SubLoop : *Original)
1371 createClonedLoopStructure(SubLoop, &New, VM,
true);
1376 bool LoopConstrainer::run() {
1378 LatchTakenCount = SE.
getExitCount(&OriginalLoop, MainLoopStructure.Latch);
1379 Preheader = OriginalLoop.getLoopPreheader();
1380 assert(!isa<SCEVCouldNotCompute>(LatchTakenCount) && Preheader !=
nullptr &&
1383 OriginalPreheader = Preheader;
1384 MainLoopPreheader = Preheader;
1386 bool IsSignedPredicate = MainLoopStructure.IsSignedPredicate;
1394 bool Increasing = MainLoopStructure.IndVarIncreasing;
1396 cast<IntegerType>(MainLoopStructure.IndVarBase->getType());
1398 SCEVExpander Expander(SE,
F.getParent()->getDataLayout(),
"irce");
1399 Instruction *InsertPt = OriginalPreheader->getTerminator();
1404 ClonedLoop PreLoop, PostLoop;
1406 Increasing ? SR.LowLimit.hasValue() : SR.HighLimit.hasValue();
1407 bool NeedsPostLoop =
1408 Increasing ? SR.HighLimit.hasValue() : SR.LowLimit.hasValue();
1410 Value *ExitPreLoopAt =
nullptr;
1411 Value *ExitMainLoopAt =
nullptr;
1413 cast<SCEVConstant>(SE.
getConstant(IVTy, -1,
true ));
1416 const SCEV *ExitPreLoopAtSCEV =
nullptr;
1419 ExitPreLoopAtSCEV = *SR.LowLimit;
1422 ExitPreLoopAtSCEV = SE.
getAddExpr(*SR.HighLimit, MinusOneS);
1424 LLVM_DEBUG(
dbgs() <<
"irce: could not prove no-overflow when computing " 1425 <<
"preloop exit limit. HighLimit = " 1426 << *(*SR.HighLimit) <<
"\n");
1431 LLVM_DEBUG(
dbgs() <<
"irce: could not prove that it is safe to expand the" 1432 <<
" preloop exit limit " << *ExitPreLoopAtSCEV
1433 <<
" at block " << InsertPt->getParent()->getName()
1438 ExitPreLoopAt = Expander.expandCodeFor(ExitPreLoopAtSCEV, IVTy, InsertPt);
1439 ExitPreLoopAt->
setName(
"exit.preloop.at");
1442 if (NeedsPostLoop) {
1443 const SCEV *ExitMainLoopAtSCEV =
nullptr;
1446 ExitMainLoopAtSCEV = *SR.HighLimit;
1449 ExitMainLoopAtSCEV = SE.
getAddExpr(*SR.LowLimit, MinusOneS);
1451 LLVM_DEBUG(
dbgs() <<
"irce: could not prove no-overflow when computing " 1452 <<
"mainloop exit limit. LowLimit = " 1453 << *(*SR.LowLimit) <<
"\n");
1458 LLVM_DEBUG(
dbgs() <<
"irce: could not prove that it is safe to expand the" 1459 <<
" main loop exit limit " << *ExitMainLoopAtSCEV
1460 <<
" at block " << InsertPt->getParent()->getName()
1465 ExitMainLoopAt = Expander.expandCodeFor(ExitMainLoopAtSCEV, IVTy, InsertPt);
1466 ExitMainLoopAt->
setName(
"exit.mainloop.at");
1472 cloneLoop(PreLoop,
"preloop");
1474 cloneLoop(PostLoop,
"postloop");
1476 RewrittenRangeInfo PreLoopRRI;
1480 PreLoop.Structure.Header);
1483 createPreheader(MainLoopStructure, Preheader,
"mainloop");
1484 PreLoopRRI = changeIterationSpaceEnd(PreLoop.Structure, Preheader,
1485 ExitPreLoopAt, MainLoopPreheader);
1486 rewriteIncomingValuesForPHIs(MainLoopStructure, MainLoopPreheader,
1491 RewrittenRangeInfo PostLoopRRI;
1493 if (NeedsPostLoop) {
1495 createPreheader(PostLoop.Structure, Preheader,
"postloop");
1496 PostLoopRRI = changeIterationSpaceEnd(MainLoopStructure, MainLoopPreheader,
1497 ExitMainLoopAt, PostLoopPreheader);
1498 rewriteIncomingValuesForPHIs(PostLoop.Structure, PostLoopPreheader,
1503 MainLoopPreheader != Preheader ? MainLoopPreheader :
nullptr;
1504 BasicBlock *NewBlocks[] = {PostLoopPreheader, PreLoopRRI.PseudoExit,
1505 PreLoopRRI.ExitSelector, PostLoopRRI.PseudoExit,
1506 PostLoopRRI.ExitSelector, NewMainLoopPreheader};
1521 Loop *PreL =
nullptr, *PostL =
nullptr;
1522 if (!PreLoop.Blocks.empty()) {
1523 PreL = createClonedLoopStructure(&OriginalLoop,
1524 OriginalLoop.getParentLoop(), PreLoop.Map,
1528 if (!PostLoop.Blocks.empty()) {
1530 createClonedLoopStructure(&OriginalLoop, OriginalLoop.getParentLoop(),
1531 PostLoop.Map,
false);
1535 auto CanonicalizeLoop = [&] (
Loop *L,
bool IsOriginalLoop) {
1540 if (!IsOriginalLoop)
1544 CanonicalizeLoop(PreL,
false);
1546 CanonicalizeLoop(PostL,
false);
1547 CanonicalizeLoop(&OriginalLoop,
true);
1556 InductiveRangeCheck::computeSafeIterationSpace(
1558 bool IsLatchSigned)
const {
1588 const SCEV *
C = getBegin();
1609 auto ClampedSubtract = [&](
const SCEV *
X,
const SCEV *
Y) {
1614 if (IsLatchSigned) {
1645 auto SCEVCheckNonNegative = [&](
const SCEV *
X) {
1666 const SCEV *REnd = getEnd();
1667 const SCEV *EndIsNonNegative = SCEVCheckNonNegative(REnd);
1669 const SCEV *Begin = SE.
getMulExpr(ClampedSubtract(Zero, M), EndIsNonNegative);
1670 const SCEV *End = SE.
getMulExpr(ClampedSubtract(REnd, M), EndIsNonNegative);
1671 return InductiveRangeCheck::Range(Begin, End);
1677 const InductiveRangeCheck::Range &
R2) {
1678 if (R2.isEmpty(SE,
true))
1685 assert(!R1Value.isEmpty(SE,
true) &&
1686 "We should never have empty R1!");
1690 if (R1Value.getType() != R2.getType())
1693 const SCEV *NewBegin = SE.
getSMaxExpr(R1Value.getBegin(), R2.getBegin());
1697 auto Ret = InductiveRangeCheck::Range(NewBegin, NewEnd);
1698 if (
Ret.isEmpty(SE,
true))
1706 const InductiveRangeCheck::Range &
R2) {
1707 if (R2.isEmpty(SE,
false))
1714 assert(!R1Value.isEmpty(SE,
false) &&
1715 "We should never have empty R1!");
1719 if (R1Value.getType() != R2.getType())
1722 const SCEV *NewBegin = SE.
getUMaxExpr(R1Value.getBegin(), R2.getBegin());
1726 auto Ret = InductiveRangeCheck::Range(NewBegin, NewEnd);
1727 if (
Ret.isEmpty(SE,
false))
1739 InductiveRangeCheckElimination IRCE(AR.
SE, BPI, AR.
DT, AR.
LI);
1740 auto LPMAddNewLoop = [&U](
Loop *NL,
bool IsSubloop) {
1744 bool Changed = IRCE.run(&L, LPMAddNewLoop);
1755 ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
1757 getAnalysis<BranchProbabilityInfoWrapperPass>().getBPI();
1758 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1759 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1760 InductiveRangeCheckElimination IRCE(SE, &BPI, DT, LI);
1761 auto LPMAddNewLoop = [&LPM](
Loop *NL,
bool ) {
1764 return IRCE.run(L, LPMAddNewLoop);
1767 bool InductiveRangeCheckElimination::run(
1770 LLVM_DEBUG(
dbgs() <<
"irce: giving up constraining loop, too large\n");
1784 if (
BranchInst *TBI = dyn_cast<BranchInst>(BBI->getTerminator()))
1785 InductiveRangeCheck::extractRangeChecksFromBranch(TBI, L, SE, BPI,
1788 if (RangeChecks.
empty())
1791 auto PrintRecognizedRangeChecks = [&](
raw_ostream &OS) {
1792 OS <<
"irce: looking at loop "; L->
print(OS);
1793 OS <<
"irce: loop has " << RangeChecks.
size()
1794 <<
" inductive range checks: \n";
1795 for (InductiveRangeCheck &IRC : RangeChecks)
1802 PrintRecognizedRangeChecks(
errs());
1804 const char *FailureReason =
nullptr;
1806 LoopStructure::parseLoopStructure(SE, BPI, *L, FailureReason);
1807 if (!MaybeLoopStructure.
hasValue()) {
1809 << FailureReason <<
"\n";);
1812 LoopStructure LS = MaybeLoopStructure.
getValue();
1824 auto IntersectRange =
1828 for (InductiveRangeCheck &IRC : RangeChecks) {
1829 auto Result = IRC.computeSafeIterationSpace(SE, IndVar,
1830 LS.IsSignedPredicate);
1831 if (Result.hasValue()) {
1832 auto MaybeSafeIterRange =
1833 IntersectRange(SE, SafeIterRange, Result.
getValue());
1834 if (MaybeSafeIterRange.hasValue()) {
1836 !MaybeSafeIterRange.getValue().isEmpty(SE, LS.IsSignedPredicate) &&
1837 "We should never return empty ranges!");
1839 SafeIterRange = MaybeSafeIterRange.
getValue();
1847 LoopConstrainer LC(*L, LI, LPMAddNewLoop, LS, SE, DT,
1849 bool Changed = LC.run();
1852 auto PrintConstrainedLoopInfo = [L]() {
1853 dbgs() <<
"irce: in function ";
1855 dbgs() <<
"constrained ";
1862 PrintConstrainedLoopInfo();
1866 for (InductiveRangeCheck &IRC : RangeChecksToEliminate) {
1867 ConstantInt *FoldedRangeCheck = IRC.getPassingDirection()
1870 IRC.getCheckUse()->set(FoldedRangeCheck);
1878 return new IRCELegacyPass();
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
Pass interface - Implemented by all 'passes'.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A parsed version of the target data layout string in and methods for querying it. ...
const_iterator end(StringRef path)
Get end iterator over path.
static ConstantInt * getFalse(LLVMContext &Context)
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
static IntegerType * getInt1Ty(LLVMContext &C)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
const SCEV * getConstant(ConstantInt *V)
This class represents lattice values for constants.
bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint, ScalarEvolution &SE)
Return true if the given expression is safe to expand in the sense that all materialized values are d...
void replaceOperandWith(unsigned I, Metadata *New)
Replace a specific operand.
static MDString * get(LLVMContext &Context, StringRef Str)
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
void push_back(const T &Elt)
bool cannotBeMinInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE, bool Signed)
Returns true if S is defined and never is equal to signed/unsigned min.
The main scalar evolution driver.
bool isZero() const
Return true if the expression is a constant zero.
bool isKnownNonNegativeInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE)
Returns true if we can prove that S is defined and always non-negative in loop L. ...
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
static cl::opt< bool > AllowUnsignedLatchCondition("irce-allow-unsigned-latch", cl::Hidden, cl::init(true))
static Optional< InductiveRangeCheck::Range > IntersectSignedRange(ScalarEvolution &SE, const Optional< InductiveRangeCheck::Range > &R1, const InductiveRangeCheck::Range &R2)
bool isAvailableAtLoopEntry(const SCEV *S, const Loop *L)
Determine if the SCEV can be evaluated at loop's entry.
An efficient, type-erasing, non-owning reference to a callable.
const Use & getOperandUse(unsigned i) const
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
BasicBlock * getSuccessor(unsigned i) const
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
Value * getCondition() const
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
This defines the Use class.
static cl::opt< bool > PrintRangeChecks("irce-print-range-checks", cl::Hidden, cl::init(false))
LLVMContext & getContext() const
Get the context in which this basic block lives.
bool isKnownNegativeInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE)
Returns true if we can prove that S is defined and always negative in loop L.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
void print(raw_ostream &OS, unsigned Depth=0, bool Verbose=false) const
Print loop with all the BBs inside it.
Value * CreateNot(Value *V, const Twine &Name="")
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
The SCEV is loop-invariant.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
#define INITIALIZE_PASS_DEPENDENCY(depName)
const Loop * getLoop() const
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, bool PreserveLCSSA)
Simplify each loop in a loop nest recursively.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
INITIALIZE_PASS_BEGIN(IRCELegacyPass, "irce", "Inductive range check elimination", false, false) INITIALIZE_PASS_END(IRCELegacyPass
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void setName(const Twine &Name)
Change the name of the value.
static cl::opt< int > MaxExitProbReciprocal("irce-max-exit-prob-reciprocal", cl::Hidden, cl::init(10))
This file implements a class to represent arbitrary precision integral constant values and operations...
BlockT * getHeader() const
Analysis pass which computes BranchProbabilityInfo.
ConstantInt * getValue() const
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS...
static void DisableAllLoopOptsOnLoop(Loop &L)
Type * getType() const
All values are typed, get the type of this value.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
This node represents a polynomial recurrence on the trip count of the specified loop.
static const char * ClonedLoopTag
void setLoopID(MDNode *LoopID) const
Set the llvm.loop loop id metadata for this loop.
const T & getValue() const LLVM_LVALUE_FUNCTION
Inductive range check elimination
This header provides classes for managing per-loop analyses.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Legacy analysis pass which computes BranchProbabilityInfo.
Value * getOperand(unsigned i) const
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS)
Test whether entry to the loop is protected by a conditional between LHS and RHS. ...
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
initializer< Ty > init(const Ty &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM Basic Block Representation.
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop...
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L)
Return the "disposition" of the given SCEV with respect to the given loop.
Conditional or Unconditional Branch instruction.
static StringRef getPredicateName(Predicate P)
Value * getIncomingValueForBlock(const BasicBlock *BB) const
This file contains the declarations for the subclasses of Constant, which represent the different fla...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
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.
const SCEV * getSMaxExpr(const SCEV *LHS, const SCEV *RHS)
Represent the analysis usage information of a pass.
This instruction compares its operands according to the predicate given to the constructor.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Value * expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I)
Insert code to directly compute the specified SCEV expression into the program.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
const SCEV * getStart() const
Class to represent integer types.
bool isKnownNegative(const SCEV *S)
Test if the given expression is known to be negative.
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
void addSiblingLoops(ArrayRef< Loop *> NewSibLoops)
Loop passes should use this method to indicate they have added new sibling loops to the current loop...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static wasm::ValType getType(const TargetRegisterClass *RC)
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.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
static bool isSafeIncreasingBound(const SCEV *Start, const SCEV *BoundSCEV, const SCEV *Step, ICmpInst::Predicate Pred, unsigned LatchBrExitIdx, Loop *L, ScalarEvolution &SE)
Given a loop with an increasing induction variable, is it possible to safely calculate the bounds of ...
const SCEV * getSMinExpr(const SCEV *LHS, const SCEV *RHS)
void print(raw_ostream &OS) const
Print out the internal representation of this scalar to the specified stream.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
static cl::opt< bool > SkipProfitabilityChecks("irce-skip-profitability-checks", cl::Hidden, cl::init(false))
This is the shared class of boolean and integer constants.
Type * getType() const
Return the LLVM type of this SCEV expression.
void setIncomingBlock(unsigned i, BasicBlock *BB)
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
static APInt getMinValue(unsigned numBits)
Gets minimum unsigned value of APInt for a specific bit width.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
const SCEV * getUMaxExpr(const SCEV *LHS, const SCEV *RHS)
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static ConstantInt * getTrue(LLVMContext &Context)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Class for arbitrary precision integers.
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, DebugInfoFinder *DIFinder=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM...
This class uses information about analyze scalars to rewrite expressions in canonical form...
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
If this flag is set, the remapper ignores missing function-local entries (Argument, Instruction, BasicBlock) that are not in the value map.
LoopT * getParentLoop() const
Predicate getPredicate() const
Return the predicate for this instruction.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
bool isLoopSimplifyForm() const
Return true if the Loop is in the form that the LoopSimplify form transforms loops to...
Analysis providing branch probability information.
This class represents an analyzed expression in the program.
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
LLVM_NODISCARD bool empty() const
unsigned greater or equal
Represents a single loop in the control flow graph.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
StringRef getName() const
Return a constant reference to the value's name.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
const Function * getParent() const
Return the enclosing method, or null if none.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
void getLoopAnalysisUsage(AnalysisUsage &AU)
Helper to consistently add the set of standard passes to a loop pass's AnalysisUsage.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static cl::opt< unsigned > LoopSizeCutoff("irce-loop-size-cutoff", cl::Hidden, cl::init(64))
bool isUnconditional() const
static bool isSafeDecreasingBound(const SCEV *Start, const SCEV *BoundSCEV, const SCEV *Step, ICmpInst::Predicate Pred, unsigned LatchBrExitIdx, Loop *L, ScalarEvolution &SE)
Given a loop with an deccreasing induction variable, is it possible to safely calculate the bounds of...
void initializeIRCELegacyPassPass(PassRegistry &)
static Optional< InductiveRangeCheck::Range > IntersectUnsignedRange(ScalarEvolution &SE, const Optional< InductiveRangeCheck::Range > &R1, const InductiveRangeCheck::Range &R2)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
static cl::opt< bool > PrintChangedLoops("irce-print-changed-loops", cl::Hidden, cl::init(false))
const SCEV * getUMinExpr(const SCEV *LHS, const SCEV *RHS)
const SCEV * getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Return the SCEV object corresponding to -V.
LLVM Value Representation.
const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
succ_range successors(Instruction *I)
This class implements an extremely fast bulk output stream that can only output to a stream...
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
A container for analyses that lazily runs them and caches their results.
const SCEV * getExitCount(const Loop *L, BasicBlock *ExitingBlock)
Get the expression for the number of loop iterations for which this loop is guaranteed not to exit vi...
static BranchProbability getZero()
bool cannotBeMaxInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE, bool Signed)
Returns true if S is defined and never is equal to signed/unsigned max.
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
void setIncomingValue(unsigned i, Value *V)
iterator_range< block_iterator > blocks() const
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask=NoWrapMask) const
Pass * createInductiveRangeCheckEliminationPass()
const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
const BasicBlock * getParent() const
This class represents a constant integer value.