[llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Aug 15 16:34:03 PDT 2005
Changes in directory llvm/lib/Analysis:
ScalarEvolution.cpp updated: 1.40 -> 1.41
---
Log message:
Teach LLVM to know how many times a loop executes when constructed with
a < expression, e.g.: for (i = m; i < n; ++i)
---
Diffs of the changes: (+110 -2)
ScalarEvolution.cpp | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 110 insertions(+), 2 deletions(-)
Index: llvm/lib/Analysis/ScalarEvolution.cpp
diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.40 llvm/lib/Analysis/ScalarEvolution.cpp:1.41
--- llvm/lib/Analysis/ScalarEvolution.cpp:1.40 Tue Aug 9 19:59:40 2005
+++ llvm/lib/Analysis/ScalarEvolution.cpp Mon Aug 15 18:33:51 2005
@@ -1168,14 +1168,19 @@
/// HowFarToZero - Return the number of times a backedge comparing the
/// specified value to zero will execute. If not computable, return
- /// UnknownValue
+ /// UnknownValue.
SCEVHandle HowFarToZero(SCEV *V, const Loop *L);
/// HowFarToNonZero - Return the number of times a backedge checking the
/// specified value for nonzero will execute. If not computable, return
- /// UnknownValue
+ /// UnknownValue.
SCEVHandle HowFarToNonZero(SCEV *V, const Loop *L);
+ /// HowManyLessThans - Return the number of times a backedge containing the
+ /// specified less-than comparison will execute. If not computable, return
+ /// UnknownValue.
+ SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L);
+
/// 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
@@ -1530,6 +1535,20 @@
if (!isa<SCEVCouldNotCompute>(TC)) return TC;
}
break;
+ case Instruction::SetLT:
+ if (LHS->getType()->isInteger() &&
+ ExitCond->getOperand(0)->getType()->isSigned()) {
+ SCEVHandle TC = HowManyLessThans(LHS, RHS, L);
+ if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ }
+ break;
+ case Instruction::SetGT:
+ if (LHS->getType()->isInteger() &&
+ ExitCond->getOperand(0)->getType()->isSigned()) {
+ SCEVHandle TC = HowManyLessThans(RHS, LHS, L);
+ if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ }
+ break;
default:
#if 0
std::cerr << "ComputeIterationCount ";
@@ -2169,6 +2188,95 @@
return UnknownValue;
}
+/// HowManyLessThans - Return the number of times a backedge containing the
+/// specified less-than comparison will execute. If not computable, return
+/// UnknownValue.
+SCEVHandle ScalarEvolutionsImpl::
+HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L) {
+ // Only handle: "ADDREC < LoopInvariant".
+ if (!RHS->isLoopInvariant(L)) return UnknownValue;
+
+ SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(LHS);
+ if (!AddRec || AddRec->getLoop() != L)
+ return UnknownValue;
+
+ if (AddRec->isAffine()) {
+ // FORNOW: We only support unit strides.
+ SCEVHandle One = SCEVUnknown::getIntegerSCEV(1, RHS->getType());
+ if (AddRec->getOperand(1) != One)
+ return UnknownValue;
+
+ // The number of iterations for "[n,+,1] < m", is m-n. However, we don't
+ // know that m is >= n on input to the loop. If it is, the condition return
+ // true zero times. What we really should return, for full generality, is
+ // SMAX(0, m-n). Since we cannot check this, we will instead check for a
+ // canonical loop form: most do-loops will have a check that dominates the
+ // loop, that only enters the loop if [n-1]<m. If we can find this check,
+ // we know that the SMAX will evaluate to m-n, because we know that m >= n.
+
+ // Search for the check.
+ BasicBlock *Preheader = L->getLoopPreheader();
+ BasicBlock *PreheaderDest = L->getHeader();
+ if (Preheader == 0) return UnknownValue;
+
+ BranchInst *LoopEntryPredicate =
+ dyn_cast<BranchInst>(Preheader->getTerminator());
+ if (!LoopEntryPredicate) return UnknownValue;
+
+ // This might be a critical edge broken out. If the loop preheader ends in
+ // an unconditional branch to the loop, check to see if the preheader has a
+ // single predecessor, and if so, look for its terminator.
+ while (LoopEntryPredicate->isUnconditional()) {
+ PreheaderDest = Preheader;
+ Preheader = Preheader->getSinglePredecessor();
+ if (!Preheader) return UnknownValue; // Multiple preds.
+
+ LoopEntryPredicate =
+ dyn_cast<BranchInst>(Preheader->getTerminator());
+ if (!LoopEntryPredicate) return UnknownValue;
+ }
+
+ // Now that we found a conditional branch that dominates the loop, check to
+ // see if it is the comparison we are looking for.
+ SetCondInst *SCI =dyn_cast<SetCondInst>(LoopEntryPredicate->getCondition());
+ if (!SCI) return UnknownValue;
+ Value *PreCondLHS = SCI->getOperand(0);
+ Value *PreCondRHS = SCI->getOperand(1);
+ Instruction::BinaryOps Cond;
+ if (LoopEntryPredicate->getSuccessor(0) == PreheaderDest)
+ Cond = SCI->getOpcode();
+ else
+ Cond = SCI->getInverseCondition();
+
+ switch (Cond) {
+ case Instruction::SetGT:
+ std::swap(PreCondLHS, PreCondRHS);
+ Cond = Instruction::SetLT;
+ // Fall Through.
+ case Instruction::SetLT:
+ if (PreCondLHS->getType()->isInteger() &&
+ PreCondLHS->getType()->isSigned()) {
+ if (RHS != getSCEV(PreCondRHS))
+ return UnknownValue; // Not a comparison against 'm'.
+
+ if (SCEV::getMinusSCEV(AddRec->getOperand(0), One)
+ != getSCEV(PreCondLHS))
+ return UnknownValue; // Not a comparison against 'n-1'.
+ break;
+ } else {
+ return UnknownValue;
+ }
+ default: break;
+ }
+
+ //std::cerr << "Computed Loop Trip Count as: " <<
+ // *SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n";
+ return SCEV::getMinusSCEV(RHS, AddRec->getOperand(0));
+ }
+
+ return UnknownValue;
+}
+
/// getNumIterationsInRange - Return the number of iterations of this loop that
/// produce values in the specified constant range. Another way of looking at
/// this is that it returns the first iteration number where the value is not in
More information about the llvm-commits
mailing list