86 #define DEBUG_TYPE "irce"
100 class InductiveRangeCheck {
102 enum RangeCheckKind :
unsigned {
104 RANGE_CHECK_LOWER = 1,
107 RANGE_CHECK_UPPER = 2,
111 RANGE_CHECK_BOTH = RANGE_CHECK_LOWER | RANGE_CHECK_UPPER,
117 static const char *rangeCheckKindToStr(RangeCheckKind);
125 static RangeCheckKind parseRangeCheckICmp(
Loop *L,
ICmpInst *ICI,
129 static InductiveRangeCheck::RangeCheckKind
133 InductiveRangeCheck() :
134 Offset(
nullptr), Scale(
nullptr), Length(
nullptr),
Branch(
nullptr) { }
138 const SCEV *getScale()
const {
return Scale; }
139 Value *getLength()
const {
return Length; }
142 OS <<
"InductiveRangeCheck:\n";
143 OS <<
" Kind: " << rangeCheckKindToStr(Kind) <<
"\n";
154 getBranch()->print(OS);
158 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
174 Range(
const SCEV *Begin,
const SCEV *End) : Begin(Begin), End(End) {
179 const SCEV *getBegin()
const {
return Begin; }
180 const SCEV *getEnd()
const {
return End; }
187 bool getPassingDirection() {
return true; }
198 static InductiveRangeCheck *create(AllocatorTy &Alloc,
BranchInst *BI,
203 class InductiveRangeCheckElimination :
public LoopPass {
208 InductiveRangeCheckElimination() :
LoopPass(
ID) {
228 "Inductive range check elimination",
false,
false)
230 const char *InductiveRangeCheck::rangeCheckKindToStr(
231 InductiveRangeCheck::RangeCheckKind RCK) {
233 case InductiveRangeCheck::RANGE_CHECK_UNKNOWN:
234 return "RANGE_CHECK_UNKNOWN";
236 case InductiveRangeCheck::RANGE_CHECK_UPPER:
237 return "RANGE_CHECK_UPPER";
239 case InductiveRangeCheck::RANGE_CHECK_LOWER:
240 return "RANGE_CHECK_LOWER";
242 case InductiveRangeCheck::RANGE_CHECK_BOTH:
243 return "RANGE_CHECK_BOTH";
258 InductiveRangeCheck::RangeCheckKind
259 InductiveRangeCheck::parseRangeCheckICmp(
Loop *L,
ICmpInst *ICI,
263 auto IsNonNegativeAndNotLoopVarying = [&SE, L](
Value *V) {
265 if (isa<SCEVCouldNotCompute>(S))
272 using namespace llvm::PatternMatch;
280 return RANGE_CHECK_UNKNOWN;
286 if (
match(RHS, m_ConstantInt<0>())) {
288 return RANGE_CHECK_LOWER;
290 return RANGE_CHECK_UNKNOWN;
296 if (
match(RHS, m_ConstantInt<-1>())) {
298 return RANGE_CHECK_LOWER;
301 if (IsNonNegativeAndNotLoopVarying(LHS)) {
304 return RANGE_CHECK_UPPER;
306 return RANGE_CHECK_UNKNOWN;
312 if (IsNonNegativeAndNotLoopVarying(LHS)) {
315 return RANGE_CHECK_BOTH;
317 return RANGE_CHECK_UNKNOWN;
325 InductiveRangeCheck::RangeCheckKind
329 using namespace llvm::PatternMatch;
335 Value *IndexA =
nullptr, *IndexB =
nullptr;
336 Value *LengthA =
nullptr, *LengthB =
nullptr;
339 if (!ICmpA || !ICmpB)
340 return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
342 auto RCKindA = parseRangeCheckICmp(L, ICmpA, SE, IndexA, LengthA);
343 auto RCKindB = parseRangeCheckICmp(L, ICmpB, SE, IndexB, LengthB);
345 if (RCKindA == InductiveRangeCheck::RANGE_CHECK_UNKNOWN ||
346 RCKindB == InductiveRangeCheck::RANGE_CHECK_UNKNOWN)
347 return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
349 if (IndexA != IndexB)
350 return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
352 if (LengthA !=
nullptr && LengthB !=
nullptr && LengthA != LengthB)
353 return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
356 if (isa<SCEVCouldNotCompute>(Index))
357 return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
359 Length = LengthA ==
nullptr ? LengthB : LengthA;
361 return (InductiveRangeCheck::RangeCheckKind)(RCKindA | RCKindB);
364 if (
ICmpInst *ICI = dyn_cast<ICmpInst>(Condition)) {
365 Value *IndexVal =
nullptr;
367 auto RCKind = parseRangeCheckICmp(L, ICI, SE, IndexVal, Length);
369 if (RCKind == InductiveRangeCheck::RANGE_CHECK_UNKNOWN)
370 return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
373 if (isa<SCEVCouldNotCompute>(Index))
374 return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
379 return InductiveRangeCheck::RANGE_CHECK_UNKNOWN;
383 InductiveRangeCheck *
396 Value *Length =
nullptr;
397 const SCEV *IndexSCEV =
nullptr;
399 auto RCKind = InductiveRangeCheck::parseRangeCheck(L, SE, BI->
getCondition(),
402 if (RCKind == InductiveRangeCheck::RANGE_CHECK_UNKNOWN)
405 assert(IndexSCEV &&
"contract with SplitRangeCheckCondition!");
406 assert((!(RCKind & InductiveRangeCheck::RANGE_CHECK_UPPER) || Length) &&
407 "contract with SplitRangeCheckCondition!");
411 IndexAddRec && (IndexAddRec->
getLoop() == L) && IndexAddRec->
isAffine();
416 InductiveRangeCheck *IRC =
new (A.
Allocate()) InductiveRangeCheck;
417 IRC->Length = Length;
418 IRC->Offset = IndexAddRec->
getStart();
432 struct LoopStructure {
442 unsigned LatchBrExitIdx;
447 bool IndVarIncreasing;
450 :
Tag(
""), Header(nullptr), Latch(nullptr), LatchBr(nullptr),
451 LatchExit(nullptr), LatchBrExitIdx(-1), IndVarNext(nullptr),
452 IndVarStart(nullptr), LoopExitAt(nullptr), IndVarIncreasing(
false) {}
454 template <
typename M> LoopStructure map(M Map)
const {
455 LoopStructure Result;
457 Result.Header = cast<BasicBlock>(Map(Header));
458 Result.Latch = cast<BasicBlock>(Map(Latch));
459 Result.LatchBr = cast<BranchInst>(Map(LatchBr));
460 Result.LatchExit = cast<BasicBlock>(Map(LatchExit));
461 Result.LatchBrExitIdx = LatchBrExitIdx;
462 Result.IndVarNext = Map(IndVarNext);
463 Result.IndVarStart = Map(IndVarStart);
464 Result.LoopExitAt = Map(LoopExitAt);
465 Result.IndVarIncreasing = IndVarIncreasing;
484 class LoopConstrainer {
488 std::vector<BasicBlock *> Blocks;
494 LoopStructure Structure;
499 struct RewrittenRangeInfo {
502 std::vector<PHINode *> PHIValuesAtPseudoExit;
506 : PseudoExit(nullptr), ExitSelector(nullptr), IndVarEnd(nullptr) {}
538 void cloneLoop(ClonedLoop &CLResult,
const char *
Tag)
const;
563 changeIterationSpaceEnd(
const LoopStructure &
LS,
BasicBlock *Preheader,
571 const char *
Tag)
const;
577 void rewriteIncomingValuesForPHIs(
578 LoopStructure &
LS,
BasicBlock *ContinuationBlockAndPreheader,
579 const LoopConstrainer::RewrittenRangeInfo &RRI)
const;
595 const SCEV *LatchTakenCount;
603 InductiveRangeCheck::Range Range;
607 LoopStructure MainLoopStructure;
612 :
F(*L.getHeader()->
getParent()), Ctx(L.getHeader()->getContext()),
613 SE(SE), OriginalLoop(L), OriginalLoopInfo(LI), LatchTakenCount(nullptr),
614 OriginalPreheader(nullptr), MainLoopPreheader(nullptr), Range(R),
615 MainLoopStructure(LS) {}
646 Loop &L,
const char *&FailureReason) {
651 FailureReason =
"no loop latch";
658 FailureReason =
"no preheader";
664 FailureReason =
"latch terminator not conditional branch";
668 unsigned LatchBrExitIdx = LatchBr->
getSuccessor(0) == Header ? 1 : 0;
674 FailureReason =
"short running loop, not profitable";
680 FailureReason =
"latch terminator branch not conditional on integral icmp";
685 if (isa<SCEVCouldNotCompute>(LatchCount)) {
686 FailureReason =
"could not compute latch count";
699 if (!isa<SCEVAddRecExpr>(LeftSCEV)) {
700 if (isa<SCEVAddRecExpr>(RightSCEV)) {
705 FailureReason =
"no add recurrences in the icmp";
714 IntegerType *Ty = cast<IntegerType>(AR->getType());
722 const SCEV *ExtendedStep =
725 bool NoSignedWrap = ExtendAfterOp->getStart() == ExtendedStart &&
726 ExtendAfterOp->getStepRecurrence(SE) == ExtendedStep;
736 auto IsInductionVar = [&](
const SCEVAddRecExpr *AR,
bool &IsIncreasing) {
743 if (!HasNoSignedWrap(AR))
750 IsIncreasing = StepCI->
isOne();
761 const SCEVAddRecExpr *IndVarNext = cast<SCEVAddRecExpr>(LeftSCEV);
762 bool IsIncreasing =
false;
763 if (!IsInductionVar(IndVarNext, IsIncreasing)) {
764 FailureReason =
"LHS in icmp not induction variable";
771 bool FoundExpectedPred =
775 if (!FoundExpectedPred) {
776 FailureReason =
"expected icmp slt semantically, found something else";
780 if (LatchBrExitIdx == 0) {
784 FailureReason =
"limit may overflow when coercing sle to slt";
789 RightValue = B.
CreateAdd(RightValue, One);
793 bool FoundExpectedPred =
797 if (!FoundExpectedPred) {
798 FailureReason =
"expected icmp sgt semantically, found something else";
802 if (LatchBrExitIdx == 0) {
806 FailureReason =
"limit may overflow when coercing sge to sgt";
811 RightValue = B.
CreateSub(RightValue, One);
823 "loop variant exit count doesn't make sense!");
825 assert(!L.
contains(LatchExit) &&
"expected an exit block!");
827 Value *IndVarStartV =
830 IndVarStartV->
setName(
"indvar.start");
832 LoopStructure Result;
835 Result.Header = Header;
836 Result.Latch = Latch;
837 Result.LatchBr = LatchBr;
838 Result.LatchExit = LatchExit;
839 Result.LatchBrExitIdx = LatchBrExitIdx;
840 Result.IndVarStart = IndVarStartV;
841 Result.IndVarNext = LeftValue;
842 Result.IndVarIncreasing = IsIncreasing;
843 Result.LoopExitAt = RightValue;
845 FailureReason =
nullptr;
851 LoopConstrainer::calculateSubRanges()
const {
852 IntegerType *Ty = cast<IntegerType>(LatchTakenCount->getType());
854 if (Range.getType() != Ty)
857 LoopConstrainer::SubRanges Result;
863 const SCEV *Start = SE.
getSCEV(MainLoopStructure.IndVarStart);
864 const SCEV *End = SE.
getSCEV(MainLoopStructure.LoopExitAt);
866 bool Increasing = MainLoopStructure.IndVarIncreasing;
871 const SCEV *Smallest =
nullptr, *Greatest =
nullptr;
897 auto Clamp = [
this, Smallest, Greatest](
const SCEV *S) {
903 bool ProvablyNoPreloop =
905 if (!ProvablyNoPreloop)
906 Result.LowLimit = Clamp(Range.getBegin());
908 bool ProvablyNoPostLoop =
910 if (!ProvablyNoPostLoop)
911 Result.HighLimit = Clamp(Range.getEnd());
916 void LoopConstrainer::cloneLoop(LoopConstrainer::ClonedLoop &Result,
917 const char *
Tag)
const {
918 for (
BasicBlock *BB : OriginalLoop.getBlocks()) {
920 Result.Blocks.push_back(Clone);
921 Result.Map[BB] = Clone;
924 auto GetClonedValue = [&Result](
Value *V) {
925 assert(V &&
"null values not in domain!");
926 auto It = Result.Map.find(V);
927 if (It == Result.Map.end())
929 return static_cast<Value *
>(It->second);
932 Result.Structure = MainLoopStructure.map(GetClonedValue);
933 Result.Structure.Tag =
Tag;
935 for (
unsigned i = 0, e = Result.Blocks.size(); i != e; ++i) {
937 BasicBlock *OriginalBB = OriginalLoop.getBlocks()[i];
939 assert(Result.Map[OriginalBB] == ClonedBB &&
"invariant!");
950 SBBI != SBBE; ++SBBI) {
952 if (OriginalLoop.contains(*SBBI))
956 if (!isa<PHINode>(&
I))
961 PN->
addIncoming(GetClonedValue(OldIncoming), ClonedBB);
967 LoopConstrainer::RewrittenRangeInfo LoopConstrainer::changeIterationSpaceEnd(
1043 RewrittenRangeInfo RRI;
1047 &
F, BBInsertLocation);
1052 bool Increasing = LS.IndVarIncreasing;
1057 Value *EnterLoopCond = Increasing
1058 ? B.CreateICmpSLT(LS.IndVarStart, ExitSubloopAt)
1059 : B.CreateICmpSGT(LS.IndVarStart, ExitSubloopAt);
1061 B.CreateCondBr(EnterLoopCond, LS.Header, RRI.PseudoExit);
1064 LS.LatchBr->setSuccessor(LS.LatchBrExitIdx, RRI.ExitSelector);
1065 B.SetInsertPoint(LS.LatchBr);
1066 Value *TakeBackedgeLoopCond =
1067 Increasing ? B.CreateICmpSLT(LS.IndVarNext, ExitSubloopAt)
1068 : B.CreateICmpSGT(LS.IndVarNext, ExitSubloopAt);
1069 Value *CondForBranch = LS.LatchBrExitIdx == 1
1070 ? TakeBackedgeLoopCond
1071 : B.CreateNot(TakeBackedgeLoopCond);
1073 LS.LatchBr->setCondition(CondForBranch);
1075 B.SetInsertPoint(RRI.ExitSelector);
1080 Value *IterationsLeft = Increasing
1081 ? B.CreateICmpSLT(LS.IndVarNext, LS.LoopExitAt)
1082 : B.CreateICmpSGT(LS.IndVarNext, LS.LoopExitAt);
1083 B.CreateCondBr(IterationsLeft, RRI.PseudoExit, LS.LatchExit);
1092 if (!isa<PHINode>(&I))
1098 BranchToContinuation);
1103 RRI.PHIValuesAtPseudoExit.push_back(NewPHI);
1106 RRI.IndVarEnd =
PHINode::Create(LS.IndVarNext->getType(), 2,
"indvar.end",
1107 BranchToContinuation);
1108 RRI.IndVarEnd->addIncoming(LS.IndVarStart, Preheader);
1109 RRI.IndVarEnd->addIncoming(LS.IndVarNext, RRI.ExitSelector);
1114 if (
PHINode *PN = dyn_cast<PHINode>(&I))
1115 replacePHIBlock(PN, LS.Latch, RRI.ExitSelector);
1123 void LoopConstrainer::rewriteIncomingValuesForPHIs(
1124 LoopStructure &LS,
BasicBlock *ContinuationBlock,
1125 const LoopConstrainer::RewrittenRangeInfo &RRI)
const {
1127 unsigned PHIIndex = 0;
1129 if (!isa<PHINode>(&I))
1139 LS.IndVarStart = RRI.IndVarEnd;
1142 BasicBlock *LoopConstrainer::createPreheader(
const LoopStructure &LS,
1144 const char *Tag)
const {
1150 if (!isa<PHINode>(&I))
1155 replacePHIBlock(PN, OldPreheader, Preheader);
1170 bool LoopConstrainer::run() {
1172 LatchTakenCount = SE.
getExitCount(&OriginalLoop, MainLoopStructure.Latch);
1173 Preheader = OriginalLoop.getLoopPreheader();
1174 assert(!isa<SCEVCouldNotCompute>(LatchTakenCount) && Preheader !=
nullptr &&
1177 OriginalPreheader = Preheader;
1178 MainLoopPreheader = Preheader;
1182 DEBUG(
dbgs() <<
"irce: could not compute subranges\n");
1187 bool Increasing = MainLoopStructure.IndVarIncreasing;
1189 cast<IntegerType>(MainLoopStructure.IndVarNext->getType());
1191 SCEVExpander Expander(SE,
F.getParent()->getDataLayout(),
"irce");
1192 Instruction *InsertPt = OriginalPreheader->getTerminator();
1197 ClonedLoop PreLoop, PostLoop;
1199 Increasing ? SR.LowLimit.hasValue() : SR.HighLimit.hasValue();
1200 bool NeedsPostLoop =
1201 Increasing ? SR.HighLimit.hasValue() : SR.LowLimit.hasValue();
1203 Value *ExitPreLoopAt =
nullptr;
1204 Value *ExitMainLoopAt =
nullptr;
1206 cast<SCEVConstant>(SE.
getConstant(IVTy, -1,
true ));
1209 const SCEV *ExitPreLoopAtSCEV =
nullptr;
1212 ExitPreLoopAtSCEV = *SR.LowLimit;
1215 DEBUG(
dbgs() <<
"irce: could not prove no-overflow when computing "
1216 <<
"preloop exit limit. HighLimit = " << *(*SR.HighLimit)
1220 ExitPreLoopAtSCEV = SE.
getAddExpr(*SR.HighLimit, MinusOneS);
1223 ExitPreLoopAt = Expander.expandCodeFor(ExitPreLoopAtSCEV, IVTy, InsertPt);
1224 ExitPreLoopAt->
setName(
"exit.preloop.at");
1227 if (NeedsPostLoop) {
1228 const SCEV *ExitMainLoopAtSCEV =
nullptr;
1231 ExitMainLoopAtSCEV = *SR.HighLimit;
1234 DEBUG(
dbgs() <<
"irce: could not prove no-overflow when computing "
1235 <<
"mainloop exit limit. LowLimit = " << *(*SR.LowLimit)
1239 ExitMainLoopAtSCEV = SE.
getAddExpr(*SR.LowLimit, MinusOneS);
1242 ExitMainLoopAt = Expander.expandCodeFor(ExitMainLoopAtSCEV, IVTy, InsertPt);
1243 ExitMainLoopAt->
setName(
"exit.mainloop.at");
1249 cloneLoop(PreLoop,
"preloop");
1251 cloneLoop(PostLoop,
"postloop");
1253 RewrittenRangeInfo PreLoopRRI;
1257 PreLoop.Structure.Header);
1260 createPreheader(MainLoopStructure, Preheader,
"mainloop");
1261 PreLoopRRI = changeIterationSpaceEnd(PreLoop.Structure, Preheader,
1262 ExitPreLoopAt, MainLoopPreheader);
1263 rewriteIncomingValuesForPHIs(MainLoopStructure, MainLoopPreheader,
1268 RewrittenRangeInfo PostLoopRRI;
1270 if (NeedsPostLoop) {
1272 createPreheader(PostLoop.Structure, Preheader,
"postloop");
1273 PostLoopRRI = changeIterationSpaceEnd(MainLoopStructure, MainLoopPreheader,
1274 ExitMainLoopAt, PostLoopPreheader);
1275 rewriteIncomingValuesForPHIs(PostLoop.Structure, PostLoopPreheader,
1280 MainLoopPreheader != Preheader ? MainLoopPreheader :
nullptr;
1281 BasicBlock *NewBlocks[] = {PostLoopPreheader, PreLoopRRI.PseudoExit,
1282 PreLoopRRI.ExitSelector, PostLoopRRI.PseudoExit,
1283 PostLoopRRI.ExitSelector, NewMainLoopPreheader};
1291 addToParentLoopIfNeeded(PreLoop.Blocks);
1292 addToParentLoopIfNeeded(PostLoop.Blocks);
1352 const SCEV *UpperLimit =
nullptr;
1356 if (
Value *V = getLength()) {
1359 assert(
Kind == InductiveRangeCheck::RANGE_CHECK_LOWER &&
"invariant!");
1365 return InductiveRangeCheck::Range(Begin, End);
1378 if (R1Value.getType() != R2.getType())
1381 const SCEV *NewBegin = SE.
getSMaxExpr(R1Value.getBegin(), R2.getBegin());
1384 return InductiveRangeCheck::Range(NewBegin, NewEnd);
1389 DEBUG(
dbgs() <<
"irce: giving up constraining loop, too large\n";);
1395 DEBUG(
dbgs() <<
"irce: loop has no preheader, leaving\n");
1406 if (
BranchInst *TBI = dyn_cast<BranchInst>(BBI->getTerminator()))
1407 if (InductiveRangeCheck *IRC =
1408 InductiveRangeCheck::create(IRCAlloc, TBI, L, SE, BPI))
1411 if (RangeChecks.
empty())
1414 auto PrintRecognizedRangeChecks = [&](
raw_ostream &OS) {
1415 OS <<
"irce: looking at loop "; L->
print(OS);
1416 OS <<
"irce: loop has " << RangeChecks.
size()
1417 <<
" inductive range checks: \n";
1418 for (InductiveRangeCheck *IRC : RangeChecks)
1422 DEBUG(PrintRecognizedRangeChecks(
dbgs()));
1425 PrintRecognizedRangeChecks(
errs());
1427 const char *FailureReason =
nullptr;
1429 LoopStructure::parseLoopStructure(SE, BPI, *L, FailureReason);
1430 if (!MaybeLoopStructure.
hasValue()) {
1431 DEBUG(
dbgs() <<
"irce: could not parse loop structure: " << FailureReason
1435 LoopStructure LS = MaybeLoopStructure.
getValue();
1436 bool Increasing = LS.IndVarIncreasing;
1437 const SCEV *MinusOne =
1438 SE.
getConstant(LS.IndVarNext->getType(), Increasing ? -1 : 1,
true);
1448 for (InductiveRangeCheck *IRC : RangeChecks) {
1449 auto Result = IRC->computeSafeIterationSpace(SE, IndVar, B);
1450 if (Result.hasValue()) {
1451 auto MaybeSafeIterRange =
1453 if (MaybeSafeIterRange.hasValue()) {
1455 SafeIterRange = MaybeSafeIterRange.
getValue();
1463 LoopConstrainer LC(*L, getAnalysis<LoopInfoWrapperPass>().getLoopInfo(), LS,
1465 bool Changed = LC.run();
1468 auto PrintConstrainedLoopInfo = [L]() {
1469 dbgs() <<
"irce: in function ";
1471 dbgs() <<
"constrained ";
1475 DEBUG(PrintConstrainedLoopInfo());
1478 PrintConstrainedLoopInfo();
1482 for (InductiveRangeCheck *IRC : RangeChecksToEliminate) {
1483 ConstantInt *FoldedRangeCheck = IRC->getPassingDirection()
1486 IRC->getBranch()->setCondition(FoldedRangeCheck);
1494 return new InductiveRangeCheckElimination;
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type (if unknown returns 0).
Pass interface - Implemented by all 'passes'.
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
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.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const SCEV * getExitCount(Loop *L, BasicBlock *ExitingBlock)
const SCEV * getConstant(ConstantInt *V)
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
ScalarEvolution - This class is the main scalar evolution driver.
bool isKnownNonNegative(const SCEV *S)
isKnownNonNegative - Test if the given expression is known to be non-negative.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
getStepRecurrence - This method constructs and returns the recurrence indicating how much this expres...
bool isLoopExiting(const BlockT *BB) const
isLoopExiting - True if terminator in the block can branch to another block that is outside of the cu...
const_iterator begin(StringRef path)
Get begin iterator over path.
LoopT * getParentLoop() const
reverse_iterator rbegin()
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
static cl::opt< bool > PrintRangeChecks("irce-print-range-checks", cl::Hidden, cl::init(false))
static std::error_code getOffset(const SymbolRef &Sym, SectionRef Sec, uint64_t &Result)
const std::vector< BlockT * > & getBlocks() const
getBlocks - Get a list of the basic blocks which make up this loop.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
BlockT * getHeader() const
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
const SCEV * getStart() const
StringRef getName() const
Return a constant reference to the value's name.
BlockT * getLoopLatch() const
getLoopLatch - If there is a single latch block for this loop, return it.
The SCEV is loop-invariant.
void print(raw_ostream &OS, unsigned Depth=0) const
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
bool isUnconditional() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
const APInt & getValue() const
Return the constant as an APInt value reference.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
static Optional< InductiveRangeCheck::Range > IntersectRange(ScalarEvolution &SE, const Optional< InductiveRangeCheck::Range > &R1, const InductiveRangeCheck::Range &R2, IRBuilder<> &B)
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr it the function does no...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
void print(raw_ostream &O) const
Implement operator<< on Value.
static cl::opt< int > MaxExitProbReciprocal("irce-max-exit-prob-reciprocal", cl::Hidden, cl::init(10))
bool isLoopSimplifyForm() const
isLoopSimplifyForm - Return true if the Loop is in the form that the LoopSimplify form transforms loo...
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS)
isKnownPredicate - Test if the given expression is known to satisfy the condition described by Pred...
ConstantRange getSignedRange(const SCEV *S)
getSignedRange - Determine the signed range for a particular SCEV.
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
addBasicBlockToLoop - This method is used by other analyses to update loop information.
SCEVAddRecExpr - This node represents a polynomial recurrence on the trip count of the specified loop...
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
const T & getValue() const LLVM_LVALUE_FUNCTION
BasicBlock * getSuccessor(unsigned i) const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
RF_NoModuleLevelChanges - If this flag is set, the remapper knows that only local values within a fun...
RF_IgnoreMissingEntries - If this flag is set, the remapper ignores entries that are not in the value...
Interval::succ_iterator succ_end(Interval *I)
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
initializer< Ty > init(const Ty &Val)
bool isAffine() const
isAffine - Return true if this represents an expression A + B*x where A and B are loop invariant valu...
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
BlockT * getLoopPreheader() const
getLoopPreheader - If there is a preheader for this loop, return it.
LLVM Basic Block Representation.
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.
Type * getType() const
getType - Return the LLVM type of this SCEV expression.
LoopDisposition getLoopDisposition(const SCEV *S, const Loop *L)
getLoopDisposition - Return the "disposition" of the given SCEV with respect to the given loop...
BranchInst - Conditional or Unconditional Branch instruction.
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void initializeInductiveRangeCheckEliminationPass(PassRegistry &)
static bool CanBeSMin(ScalarEvolution &SE, const SCEV *S)
const SCEV * getSMaxExpr(const SCEV *LHS, const SCEV *RHS)
Represent the analysis usage information of a pass.
BasicBlock * getIncomingBlock(unsigned i) const
getIncomingBlock - Return incoming basic block number i.
bool contains(const LoopT *L) const
contains - Return true if the specified loop is contained within in this loop.
This instruction compares its operands according to the predicate given to the constructor.
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
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.
Value * getOperand(unsigned i) const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Class to represent integer types.
Predicate getPredicate() const
Return the predicate for this instruction.
T * Allocate(size_t num=1)
Allocate space for an array of objects without constructing them.
INITIALIZE_PASS(InductiveRangeCheckElimination,"irce","Inductive range check elimination", false, false) const char *InductiveRangeCheck
const SCEV * getSMinExpr(const SCEV *LHS, const SCEV *RHS)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is the shared class of boolean and integer constants.
void setIncomingBlock(unsigned i, BasicBlock *BB)
AnalysisUsage & addRequiredID(const void *ID)
static bool CanBeSMax(ScalarEvolution &SE, const SCEV *S)
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.
Type * getType() const
All values are typed, get the type of this value.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
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...
ConstantInt * getValue() const
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
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.
static Constant * getFalse(Type *Ty)
getFalse - For a boolean type, or a vector of boolean type, return false, or a vector with every elem...
const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty)
Value * getIncomingValueForBlock(const BasicBlock *BB) const
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
RemapInstruction - Convert the instruction operands from referencing the current values into those sp...
This class uses information about analyze scalars to rewrite expressions in canonical form...
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
getAddExpr - Get a canonical add expression, or something simpler if possible.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Value * getCondition() const
Analysis pass providing branch probability information.
SCEV - This class represents an analyzed expression in the program.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static cl::opt< unsigned > LoopSizeCutoff("irce-loop-size-cutoff", cl::Hidden, cl::init(64))
const Loop * getLoop() const
ConstantRange getUnsignedRange(const SCEV *S)
getUnsignedRange - Determine the unsigned range for a particular SCEV.
const ARM::ArchExtKind Kind
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))
LLVMContext & getContext() const
Get the context in which this basic block lives.
void print(raw_ostream &OS) const
print - Print out the internal representation of this scalar to the specified stream.
LLVM Value Representation.
const SCEV * getSCEV(Value *V)
getSCEV - Return a SCEV expression for the full generality of the specified expression.
static const Function * getParent(const Value *V)
This class implements an extremely fast bulk output stream that can only output to a stream...
BranchProbability getEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors) const
Get an edge's probability, relative to other out-edges of the Src.
The legacy pass manager's analysis pass to compute loop information.
C - The default llvm calling convention, compatible with C.
const SCEV * getNegativeSCEV(const SCEV *V)
getNegativeSCEV - Return the SCEV object corresponding to -V.
void setIncomingValue(unsigned i, Value *V)
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr)
CloneBasicBlock - Return a copy of the specified basic block, but without embedding the block into a ...
const BasicBlock * getParent() const
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
Pass * createInductiveRangeCheckEliminationPass()
SCEVConstant - This class represents a constant integer value.