diff options
author | Dan Gohman <gohman@apple.com> | 2010-04-11 22:16:48 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2010-04-11 22:16:48 +0000 |
commit | 53c66eacc417c0113fba7159487b90005dc8f91e (patch) | |
tree | af9ec08234304171d66ba109eca4df88bb777670 | |
parent | b64cf896f8c6648b2c2bce15107d2892b909f367 (diff) | |
download | external_llvm-53c66eacc417c0113fba7159487b90005dc8f91e.zip external_llvm-53c66eacc417c0113fba7159487b90005dc8f91e.tar.gz external_llvm-53c66eacc417c0113fba7159487b90005dc8f91e.tar.bz2 |
Enhance ScalarEvolution::isKnownPredicate with support for
loop conditions which are invariants.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100995 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/Analysis/ScalarEvolution.h | 7 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolution.cpp | 41 |
2 files changed, 40 insertions, 8 deletions
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h index a486cee..c1f39ad 100644 --- a/include/llvm/Analysis/ScalarEvolution.h +++ b/include/llvm/Analysis/ScalarEvolution.h @@ -380,6 +380,13 @@ namespace llvm { Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs, const Loop *L); + /// isKnownPredicateWithRanges - Test if the given expression is known to + /// satisfy the condition described by Pred and the known constant ranges + /// of LHS and RHS. + /// + bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS); + public: static char ID; // Pass identification, replacement for typeid ScalarEvolution(); diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index f8b2d78..59ac988 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -4651,10 +4651,35 @@ bool ScalarEvolution::isKnownNonZero(const SCEV *S) { bool ScalarEvolution::isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS) { + // If LHS or RHS is an addrec, check to see if the condition is true in + // every iteration of the loop. + if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(LHS)) + if (isLoopEntryGuardedByCond( + AR->getLoop(), Pred, AR->getStart(), RHS) && + isLoopBackedgeGuardedByCond( + AR->getLoop(), Pred, + getAddExpr(AR, AR->getStepRecurrence(*this)), RHS)) + return true; + if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(RHS)) + if (isLoopEntryGuardedByCond( + AR->getLoop(), Pred, LHS, AR->getStart()) && + isLoopBackedgeGuardedByCond( + AR->getLoop(), Pred, + LHS, getAddExpr(AR, AR->getStepRecurrence(*this)))) + return true; + // Otherwise see what can be done with known constant ranges. + return isKnownPredicateWithRanges(Pred, LHS, RHS); +} + +bool +ScalarEvolution::isKnownPredicateWithRanges(ICmpInst::Predicate Pred, + const SCEV *LHS, const SCEV *RHS) { if (HasSameValue(LHS, RHS)) return ICmpInst::isTrueWhenEqual(Pred); + // This code is split out from isKnownPredicate because it is called from + // within isLoopEntryGuardedByCond. switch (Pred) { default: llvm_unreachable("Unexpected ICmpInst::Predicate value!"); @@ -5026,26 +5051,26 @@ ScalarEvolution::isImpliedCondOperandsHelper(ICmpInst::Predicate Pred, break; case ICmpInst::ICMP_SLT: case ICmpInst::ICMP_SLE: - if (isKnownPredicate(ICmpInst::ICMP_SLE, LHS, FoundLHS) && - isKnownPredicate(ICmpInst::ICMP_SGE, RHS, FoundRHS)) + if (isKnownPredicateWithRanges(ICmpInst::ICMP_SLE, LHS, FoundLHS) && + isKnownPredicateWithRanges(ICmpInst::ICMP_SGE, RHS, FoundRHS)) return true; break; case ICmpInst::ICMP_SGT: case ICmpInst::ICMP_SGE: - if (isKnownPredicate(ICmpInst::ICMP_SGE, LHS, FoundLHS) && - isKnownPredicate(ICmpInst::ICMP_SLE, RHS, FoundRHS)) + if (isKnownPredicateWithRanges(ICmpInst::ICMP_SGE, LHS, FoundLHS) && + isKnownPredicateWithRanges(ICmpInst::ICMP_SLE, RHS, FoundRHS)) return true; break; case ICmpInst::ICMP_ULT: case ICmpInst::ICMP_ULE: - if (isKnownPredicate(ICmpInst::ICMP_ULE, LHS, FoundLHS) && - isKnownPredicate(ICmpInst::ICMP_UGE, RHS, FoundRHS)) + if (isKnownPredicateWithRanges(ICmpInst::ICMP_ULE, LHS, FoundLHS) && + isKnownPredicateWithRanges(ICmpInst::ICMP_UGE, RHS, FoundRHS)) return true; break; case ICmpInst::ICMP_UGT: case ICmpInst::ICMP_UGE: - if (isKnownPredicate(ICmpInst::ICMP_UGE, LHS, FoundLHS) && - isKnownPredicate(ICmpInst::ICMP_ULE, RHS, FoundRHS)) + if (isKnownPredicateWithRanges(ICmpInst::ICMP_UGE, LHS, FoundLHS) && + isKnownPredicateWithRanges(ICmpInst::ICMP_ULE, RHS, FoundRHS)) return true; break; } |