X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FScalar%2FInductiveRangeCheckElimination.cpp;h=08fdcc38c045d8a48545756efe2f1f0930d82b42;hp=f7095c062697068fa4b420b48aa8812b18795df9;hb=8770f7af5f46c0d34a79cf0beeeef80b1a2ab690;hpb=25e7243edaa7859aae21463bca8ac4d6ed0a9aba diff --git a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp index f7095c06269..08fdcc38c04 100644 --- a/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp +++ b/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp @@ -42,7 +42,6 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/Optional.h" - #include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopInfo.h" @@ -51,27 +50,23 @@ #include "llvm/Analysis/ScalarEvolutionExpander.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/ValueTracking.h" - #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" -#include "llvm/IR/Instructions.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/Module.h" #include "llvm/IR/PatternMatch.h" #include "llvm/IR/ValueHandle.h" #include "llvm/IR/Verifier.h" - +#include "llvm/Pass.h" #include "llvm/Support/Debug.h" - +#include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Transforms/Utils/LoopUtils.h" #include "llvm/Transforms/Utils/SimplifyIndVar.h" #include "llvm/Transforms/Utils/UnrollLoop.h" - -#include "llvm/Pass.h" - #include using namespace llvm; @@ -127,8 +122,9 @@ class InductiveRangeCheck { BranchInst *Branch; RangeCheckKind Kind; - static RangeCheckKind parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE, - Value *&Index, Value *&Length); + static RangeCheckKind parseRangeCheckICmp(Loop *L, ICmpInst *ICI, + ScalarEvolution &SE, Value *&Index, + Value *&Length); static InductiveRangeCheck::RangeCheckKind parseRangeCheck(Loop *L, ScalarEvolution &SE, Value *Condition, @@ -219,7 +215,7 @@ public: AU.addRequiredID(LoopSimplifyID); AU.addRequiredID(LCSSAID); AU.addRequired(); - AU.addRequired(); + AU.addRequired(); } bool runOnLoop(Loop *L, LPPassManager &LPM) override; @@ -260,8 +256,18 @@ const char *InductiveRangeCheck::rangeCheckKindToStr( /// RANGE_CHECK_UPPER. /// InductiveRangeCheck::RangeCheckKind -InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE, - Value *&Index, Value *&Length) { +InductiveRangeCheck::parseRangeCheckICmp(Loop *L, ICmpInst *ICI, + ScalarEvolution &SE, Value *&Index, + Value *&Length) { + + auto IsNonNegativeAndNotLoopVarying = [&SE, L](Value *V) { + const SCEV *S = SE.getSCEV(V); + if (isa(S)) + return false; + + return SE.getLoopDisposition(S, L) == ScalarEvolution::LoopInvariant && + SE.isKnownNonNegative(S); + }; using namespace llvm::PatternMatch; @@ -292,7 +298,7 @@ InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE, return RANGE_CHECK_LOWER; } - if (SE.isKnownNonNegative(SE.getSCEV(LHS))) { + if (IsNonNegativeAndNotLoopVarying(LHS)) { Index = RHS; Length = LHS; return RANGE_CHECK_UPPER; @@ -303,7 +309,7 @@ InductiveRangeCheck::parseRangeCheckICmp(ICmpInst *ICI, ScalarEvolution &SE, std::swap(LHS, RHS); // fallthrough case ICmpInst::ICMP_UGT: - if (SE.isKnownNonNegative(SE.getSCEV(LHS))) { + if (IsNonNegativeAndNotLoopVarying(LHS)) { Index = RHS; Length = LHS; return RANGE_CHECK_BOTH; @@ -333,8 +339,8 @@ InductiveRangeCheck::parseRangeCheck(Loop *L, ScalarEvolution &SE, if (!ICmpA || !ICmpB) return InductiveRangeCheck::RANGE_CHECK_UNKNOWN; - auto RCKindA = parseRangeCheckICmp(ICmpA, SE, IndexA, LengthA); - auto RCKindB = parseRangeCheckICmp(ICmpB, SE, IndexB, LengthB); + auto RCKindA = parseRangeCheckICmp(L, ICmpA, SE, IndexA, LengthA); + auto RCKindB = parseRangeCheckICmp(L, ICmpB, SE, IndexB, LengthB); if (RCKindA == InductiveRangeCheck::RANGE_CHECK_UNKNOWN || RCKindB == InductiveRangeCheck::RANGE_CHECK_UNKNOWN) @@ -358,7 +364,7 @@ InductiveRangeCheck::parseRangeCheck(Loop *L, ScalarEvolution &SE, if (ICmpInst *ICI = dyn_cast(Condition)) { Value *IndexVal = nullptr; - auto RCKind = parseRangeCheckICmp(ICI, SE, IndexVal, Length); + auto RCKind = parseRangeCheckICmp(L, ICI, SE, IndexVal, Length); if (RCKind == InductiveRangeCheck::RANGE_CHECK_UNKNOWN) return InductiveRangeCheck::RANGE_CHECK_UNKNOWN; @@ -701,30 +707,40 @@ LoopStructure::parseLoopStructure(ScalarEvolution &SE, BranchProbabilityInfo &BP } } - auto IsInductionVar = [&SE](const SCEVAddRecExpr *AR, bool &IsIncreasing) { - if (!AR->isAffine()) - return false; + auto HasNoSignedWrap = [&](const SCEVAddRecExpr *AR) { + if (AR->getNoWrapFlags(SCEV::FlagNSW)) + return true; IntegerType *Ty = cast(AR->getType()); IntegerType *WideTy = IntegerType::get(Ty->getContext(), Ty->getBitWidth() * 2); - // Currently we only work with induction variables that have been proved to - // not wrap. This restriction can potentially be lifted in the future. - const SCEVAddRecExpr *ExtendAfterOp = dyn_cast(SE.getSignExtendExpr(AR, WideTy)); - if (!ExtendAfterOp) - return false; + if (ExtendAfterOp) { + const SCEV *ExtendedStart = SE.getSignExtendExpr(AR->getStart(), WideTy); + const SCEV *ExtendedStep = + SE.getSignExtendExpr(AR->getStepRecurrence(SE), WideTy); + + bool NoSignedWrap = ExtendAfterOp->getStart() == ExtendedStart && + ExtendAfterOp->getStepRecurrence(SE) == ExtendedStep; - const SCEV *ExtendedStart = SE.getSignExtendExpr(AR->getStart(), WideTy); - const SCEV *ExtendedStep = - SE.getSignExtendExpr(AR->getStepRecurrence(SE), WideTy); + if (NoSignedWrap) + return true; + } - bool NoSignedWrap = ExtendAfterOp->getStart() == ExtendedStart && - ExtendAfterOp->getStepRecurrence(SE) == ExtendedStep; + // We may have proved this when computing the sign extension above. + return AR->getNoWrapFlags(SCEV::FlagNSW) != SCEV::FlagAnyWrap; + }; + + auto IsInductionVar = [&](const SCEVAddRecExpr *AR, bool &IsIncreasing) { + if (!AR->isAffine()) + return false; + + // Currently we only work with induction variables that have been proved to + // not wrap. This restriction can potentially be lifted in the future. - if (!NoSignedWrap) + if (!HasNoSignedWrap(AR)) return false; if (const SCEVConstant *StepExpr = @@ -1384,7 +1400,8 @@ bool InductiveRangeCheckElimination::runOnLoop(Loop *L, LPPassManager &LPM) { InductiveRangeCheck::AllocatorTy IRCAlloc; SmallVector RangeChecks; ScalarEvolution &SE = getAnalysis(); - BranchProbabilityInfo &BPI = getAnalysis(); + BranchProbabilityInfo &BPI = + getAnalysis().getBPI(); for (auto BBI : L->getBlocks()) if (BranchInst *TBI = dyn_cast(BBI->getTerminator()))