aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-02-12 22:19:27 +0000
committerDan Gohman <gohman@apple.com>2009-02-12 22:19:27 +0000
commitc2390b14c91764cba6e4394d05e58e387a7dfb19 (patch)
tree50928112e772fb856a2eada26c52ca9010bd2b53 /lib/Analysis/ScalarEvolution.cpp
parent0f123cf732ad249117b7471e37bf819633b76a6e (diff)
downloadexternal_llvm-c2390b14c91764cba6e4394d05e58e387a7dfb19.zip
external_llvm-c2390b14c91764cba6e4394d05e58e387a7dfb19.tar.gz
external_llvm-c2390b14c91764cba6e4394d05e58e387a7dfb19.tar.bz2
Teach IndVarSimplify to optimize code using the C "int" type for
loop induction on LP64 targets. When the induction variable is used in addressing, IndVars now is usually able to inserst a 64-bit induction variable and eliminates the sign-extending cast. This is also useful for code using C "short" types for induction variables on targets with 32-bit addressing. Inserting a wider induction variable is easy; the tricky part is determining when trunc(sext(i)) expressions are no-ops. This requires range analysis of the loop trip count. A common case is when the original loop iteration starts at 0 and exits when the induction variable is signed-less-than a fixed value; this case is now handled. This replaces IndVarSimplify's OptimizeCanonicalIVType. It was doing the same optimization, but it was limited to loops with constant trip counts, because it was running after the loop rewrite, and the information about the original induction variable is lost by that point. Rename ScalarEvolution's executesAtLeastOnce to isLoopGuardedByCond, generalize it to be able to test for ICMP_NE conditions, and move it to be a public function so that IndVars can use it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@64407 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp100
1 files changed, 73 insertions, 27 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index c05ba8d..59e76c0 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -1404,6 +1404,11 @@ namespace {
SCEVHandle getSCEVAtScope(SCEV *V, const Loop *L);
+ /// isLoopGuardedByCond - Test whether entry to the loop is protected by
+ /// a conditional between LHS and RHS.
+ bool isLoopGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
+ SCEV *LHS, SCEV *RHS);
+
/// hasLoopInvariantIterationCount - Return true if the specified loop has
/// an analyzable loop-invariant iteration count.
bool hasLoopInvariantIterationCount(const Loop *L);
@@ -1476,10 +1481,6 @@ namespace {
/// found.
BasicBlock* getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
- /// executesAtLeastOnce - Test whether entry to the loop is protected by
- /// a conditional between LHS and RHS.
- bool executesAtLeastOnce(const Loop *L, bool isSigned, SCEV *LHS, SCEV *RHS);
-
/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
/// in the header of its containing loop, we know the loop executes a
/// constant number of times, and the PHI node is just a recurrence
@@ -2726,9 +2727,10 @@ ScalarEvolutionsImpl::getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB) {
return 0;
}
-/// executesAtLeastOnce - Test whether entry to the loop is protected by
+/// isLoopGuardedByCond - Test whether entry to the loop is protected by
/// a conditional between LHS and RHS.
-bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool isSigned,
+bool ScalarEvolutionsImpl::isLoopGuardedByCond(const Loop *L,
+ ICmpInst::Predicate Pred,
SCEV *LHS, SCEV *RHS) {
BasicBlock *Preheader = L->getLoopPreheader();
BasicBlock *PreheaderDest = L->getHeader();
@@ -2759,26 +2761,62 @@ bool ScalarEvolutionsImpl::executesAtLeastOnce(const Loop *L, bool isSigned,
else
Cond = ICI->getInversePredicate();
- switch (Cond) {
- case ICmpInst::ICMP_UGT:
- if (isSigned) continue;
- std::swap(PreCondLHS, PreCondRHS);
- Cond = ICmpInst::ICMP_ULT;
- break;
- case ICmpInst::ICMP_SGT:
- if (!isSigned) continue;
- std::swap(PreCondLHS, PreCondRHS);
- Cond = ICmpInst::ICMP_SLT;
- break;
- case ICmpInst::ICMP_ULT:
- if (isSigned) continue;
- break;
- case ICmpInst::ICMP_SLT:
- if (!isSigned) continue;
- break;
- default:
- continue;
- }
+ if (Cond == Pred)
+ ; // An exact match.
+ else if (!ICmpInst::isTrueWhenEqual(Cond) && Pred == ICmpInst::ICMP_NE)
+ ; // The actual condition is beyond sufficient.
+ else
+ // Check a few special cases.
+ switch (Cond) {
+ case ICmpInst::ICMP_UGT:
+ if (Pred == ICmpInst::ICMP_ULT) {
+ std::swap(PreCondLHS, PreCondRHS);
+ Cond = ICmpInst::ICMP_ULT;
+ break;
+ }
+ continue;
+ case ICmpInst::ICMP_SGT:
+ if (Pred == ICmpInst::ICMP_SLT) {
+ std::swap(PreCondLHS, PreCondRHS);
+ Cond = ICmpInst::ICMP_SLT;
+ break;
+ }
+ continue;
+ case ICmpInst::ICMP_NE:
+ // Expressions like (x >u 0) are often canonicalized to (x != 0),
+ // so check for this case by checking if the NE is comparing against
+ // a minimum or maximum constant.
+ if (!ICmpInst::isTrueWhenEqual(Pred))
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(PreCondRHS)) {
+ const APInt &A = CI->getValue();
+ switch (Pred) {
+ case ICmpInst::ICMP_SLT:
+ if (A.isMaxSignedValue()) break;
+ continue;
+ case ICmpInst::ICMP_SGT:
+ if (A.isMinSignedValue()) break;
+ continue;
+ case ICmpInst::ICMP_ULT:
+ if (A.isMaxValue()) break;
+ continue;
+ case ICmpInst::ICMP_UGT:
+ if (A.isMinValue()) break;
+ continue;
+ default:
+ continue;
+ }
+ Cond = ICmpInst::ICMP_NE;
+ // NE is symmetric but the original comparison may not be. Swap
+ // the operands if necessary so that they match below.
+ if (isa<SCEVConstant>(LHS))
+ std::swap(PreCondLHS, PreCondRHS);
+ break;
+ }
+ continue;
+ default:
+ // We weren't able to reconcile the condition.
+ continue;
+ }
if (!PreCondLHS->getType()->isInteger()) continue;
@@ -2819,7 +2857,8 @@ HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L, bool isSigned) {
// First, we get the value of the LHS in the first iteration: n
SCEVHandle Start = AddRec->getOperand(0);
- if (executesAtLeastOnce(L, isSigned,
+ if (isLoopGuardedByCond(L,
+ isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT,
SE.getMinusSCEV(AddRec->getOperand(0), One), RHS)) {
// Since we know that the condition is true in order to enter the loop,
// we know that it will run exactly m-n times.
@@ -2997,6 +3036,13 @@ void ScalarEvolution::setSCEV(Value *V, const SCEVHandle &H) {
}
+bool ScalarEvolution::isLoopGuardedByCond(const Loop *L,
+ ICmpInst::Predicate Pred,
+ SCEV *LHS, SCEV *RHS) {
+ return ((ScalarEvolutionsImpl*)Impl)->isLoopGuardedByCond(L, Pred,
+ LHS, RHS);
+}
+
SCEVHandle ScalarEvolution::getIterationCount(const Loop *L) const {
return ((ScalarEvolutionsImpl*)Impl)->getIterationCount(L);
}