aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-04-17 18:36:24 +0000
committerChris Lattner <sabre@nondot.org>2004-04-17 18:36:24 +0000
commit7980fb9007b7e13446053daa6a5110aeeb7016dd (patch)
treeba94f169a8246aef1107201216c7e18163fdbdbe /lib
parent4f1134e51ae293536843dcd7fa1147acdc39dec7 (diff)
downloadexternal_llvm-7980fb9007b7e13446053daa6a5110aeeb7016dd.zip
external_llvm-7980fb9007b7e13446053daa6a5110aeeb7016dd.tar.gz
external_llvm-7980fb9007b7e13446053daa6a5110aeeb7016dd.tar.bz2
Add the ability to compute trip counts that are only controlled by constants
even if the loop is using expressions that we can't compute as a closed-form. This allows us to calculate that this function always returns 55: int test() { double X; int Count = 0; for (X = 100; X > 1; X = sqrt(X), ++Count) /*empty*/; return Count; } And allows us to compute trip counts for loops like: int h = 1; do h = 3 * h + 1; while (h <= 256); (which occurs in bzip2), and for this function, which occurs after inlining and other optimizations: int popcount() { int x = 666; int result = 0; while (x != 0) { result = result + (x & 0x1); x = x >> 1; } return result; } We still cannot compute the exit values of result or h in the two loops above, which means we cannot delete the loop, but we are getting closer. Being able to compute a constant trip count for these two loops will allow us to unroll them completely though. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13017 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp179
1 files changed, 174 insertions, 5 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 33a4050..2841200 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -72,9 +72,11 @@
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/InstIterator.h"
+#include "Support/CommandLine.h"
#include "Support/Statistic.h"
#include <cmath>
using namespace llvm;
@@ -92,6 +94,14 @@ namespace {
Statistic<>
NumTripCountsNotComputed("scalar-evolution",
"Number of loops without predictable loop counts");
+ Statistic<>
+ NumBruteForceTripCountsComputed("scalar-evolution",
+ "Number of loops with trip counts computed by force");
+
+ cl::opt<unsigned>
+ MaxBruteForceIterations("scalar-evolution-max-iterations", cl::ReallyHidden,
+ cl::desc("Maximum number of iterations SCEV will symbolically execute a constant derived loop"),
+ cl::init(100));
}
//===----------------------------------------------------------------------===//
@@ -1170,6 +1180,14 @@ namespace {
/// will iterate.
SCEVHandle ComputeIterationCount(const Loop *L);
+ /// ComputeIterationCountExhaustively - If the trip is known to execute a
+ /// constant number of times (the condition evolves only from constants),
+ /// try to evaluate a few iterations of the loop until we get the exit
+ /// condition gets a value of ExitWhen (true or false). If we cannot
+ /// evaluate the trip count of the loop, return UnknownValue.
+ SCEVHandle ComputeIterationCountExhaustively(const Loop *L, Value *Cond,
+ bool ExitWhen);
+
/// HowFarToZero - Return the number of times a backedge comparing the
/// specified value to zero will execute. If not computable, return
/// UnknownValue
@@ -1444,7 +1462,9 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
if (ExitBr == 0) return UnknownValue;
assert(ExitBr->isConditional() && "If unconditional, it can't be in loop!");
SetCondInst *ExitCond = dyn_cast<SetCondInst>(ExitBr->getCondition());
- if (ExitCond == 0) return UnknownValue;
+ if (ExitCond == 0) // Not a setcc
+ return ComputeIterationCountExhaustively(L, ExitBr->getCondition(),
+ ExitBr->getSuccessor(0) == ExitBlock);
SCEVHandle LHS = getSCEV(ExitCond->getOperand(0));
SCEVHandle RHS = getSCEV(ExitCond->getOperand(1));
@@ -1505,13 +1525,17 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
switch (Cond) {
case Instruction::SetNE: // while (X != Y)
// Convert to: while (X-Y != 0)
- if (LHS->getType()->isInteger())
- return HowFarToZero(getMinusSCEV(LHS, RHS), L);
+ if (LHS->getType()->isInteger()) {
+ SCEVHandle TC = HowFarToZero(getMinusSCEV(LHS, RHS), L);
+ if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ }
break;
case Instruction::SetEQ:
// Convert to: while (X-Y == 0) // while (X == Y)
- if (LHS->getType()->isInteger())
- return HowFarToNonZero(getMinusSCEV(LHS, RHS), L);
+ if (LHS->getType()->isInteger()) {
+ SCEVHandle TC = HowFarToNonZero(getMinusSCEV(LHS, RHS), L);
+ if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ }
break;
default:
#if 0
@@ -1523,6 +1547,151 @@ SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
#endif
break;
}
+
+ return ComputeIterationCountExhaustively(L, ExitCond,
+ ExitBr->getSuccessor(0) == ExitBlock);
+}
+
+
+/// getConstantEvolvingPHI - Given an LLVM value and a loop, return a PHI node
+/// in the loop that V is derived from. We allow arbitrary operations along the
+/// way, but the operands of an operation must either be constants or a value
+/// derived from a constant PHI. If this expression does not fit with these
+/// constraints, return null.
+static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) {
+ // If this is not an instruction, or if this is an instruction outside of the
+ // loop, it can't be derived from a loop PHI.
+ Instruction *I = dyn_cast<Instruction>(V);
+ if (I == 0 || !L->contains(I->getParent())) return 0;
+
+ if (PHINode *PN = dyn_cast<PHINode>(I))
+ if (L->getHeader() == I->getParent())
+ return PN;
+ else
+ // We don't currently keep track of the control flow needed to evaluate
+ // PHIs, so we cannot handle PHIs inside of loops.
+ return 0;
+
+ // If this is a call, and we have no hope of constant folding, bail early.
+ if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (!CI->getCalledFunction() ||
+ !canConstantFoldCallTo(CI->getCalledFunction()))
+ return 0;
+ } else if (InvokeInst *II = dyn_cast<InvokeInst>(I))
+ return 0;
+
+ // Otherwise, we can evaluate this instruction if all of its operands but one
+ // are constant, and if the remaining one is derived from a constant evolving
+ // PHI.
+ unsigned Op = 0, e = I->getNumOperands();
+ while (Op != e && (isa<Constant>(I->getOperand(Op)) ||
+ isa<GlobalValue>(I->getOperand(Op))))
+ ++Op; // Skip over all constant operands
+
+ if (Op == e) return 0; // No non-constants? Should be folded!
+
+ // Found the first non-constant operand.
+ unsigned NonConstantOp = Op;
+
+ // Okay, all of the rest must be constants now.
+ for (++Op; Op != e; ++Op)
+ if (!(isa<Constant>(I->getOperand(Op)) ||
+ isa<GlobalValue>(I->getOperand(Op))))
+ return 0; // Too many non-constant operands!
+
+ // This is a expression evolving from a constant PHI if the non-constant
+ // portion is!
+ return getConstantEvolvingPHI(I->getOperand(NonConstantOp), L);
+}
+
+/// EvaluateExpression - Given an expression that passes the
+/// getConstantEvolvingPHI predicate, evaluate its value assuming the PHI node
+/// in the loop has the value PHIVal. If we can't fold this expression for some
+/// reason, return null.
+static Constant *EvaluateExpression(Value *V, Constant *PHIVal) {
+ if (isa<PHINode>(V)) return PHIVal;
+ if (Constant *C = dyn_cast<Constant>(V)) return C;
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(V))
+ return ConstantPointerRef::get(GV);
+ Instruction *I = cast<Instruction>(V);
+
+ std::vector<Constant*> Operands;
+ Operands.resize(I->getNumOperands());
+
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+ Operands[i] = EvaluateExpression(I->getOperand(i), PHIVal);
+ if (Operands[i] == 0) return 0;
+ }
+
+ if (isa<BinaryOperator>(I) || isa<ShiftInst>(I))
+ return ConstantExpr::get(I->getOpcode(), Operands[0], Operands[1]);
+
+ switch (I->getOpcode()) {
+ case Instruction::Cast:
+ return ConstantExpr::getCast(Operands[0], I->getType());
+ case Instruction::Select:
+ return ConstantExpr::getSelect(Operands[0], Operands[1], Operands[2]);
+ case Instruction::Call:
+ if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0])) {
+ Operands.erase(Operands.begin());
+ return ConstantFoldCall(cast<Function>(CPR->getValue()), Operands);
+ }
+
+ return 0;
+ case Instruction::GetElementPtr:
+ Constant *Base = Operands[0];
+ Operands.erase(Operands.begin());
+ return ConstantExpr::getGetElementPtr(Base, Operands);
+ }
+ return 0;
+}
+
+
+/// ComputeIterationCountExhaustively - If the trip is known to execute a
+/// constant number of times (the condition evolves only from constants),
+/// try to evaluate a few iterations of the loop until we get the exit
+/// condition gets a value of ExitWhen (true or false). If we cannot
+/// evaluate the trip count of the loop, return UnknownValue.
+SCEVHandle ScalarEvolutionsImpl::
+ComputeIterationCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen) {
+ PHINode *PN = getConstantEvolvingPHI(Cond, L);
+ if (PN == 0) return UnknownValue;
+
+ // Since the loop is canonicalized, the PHI node must have two entries. One
+ // entry must be a constant (coming in from outside of the loop), and the
+ // second must be derived from the same PHI.
+ bool SecondIsBackedge = L->contains(PN->getIncomingBlock(1));
+ Constant *StartCST =
+ dyn_cast<Constant>(PN->getIncomingValue(!SecondIsBackedge));
+ if (StartCST == 0) return UnknownValue; // Must be a constant.
+
+ Value *BEValue = PN->getIncomingValue(SecondIsBackedge);
+ PHINode *PN2 = getConstantEvolvingPHI(BEValue, L);
+ if (PN2 != PN) return UnknownValue; // Not derived from same PHI.
+
+ // Okay, we find a PHI node that defines the trip count of this loop. Execute
+ // the loop symbolically to determine when the condition gets a value of
+ // "ExitWhen".
+ unsigned IterationNum = 0;
+ unsigned MaxIterations = MaxBruteForceIterations; // Limit analysis.
+ for (Constant *PHIVal = StartCST;
+ IterationNum != MaxIterations; ++IterationNum) {
+ ConstantBool *CondVal =
+ dyn_cast_or_null<ConstantBool>(EvaluateExpression(Cond, PHIVal));
+ if (!CondVal) return UnknownValue; // Couldn't symbolically evaluate.
+ if (CondVal->getValue() == ExitWhen) {
+ ++NumBruteForceTripCountsComputed;
+ return SCEVConstant::get(ConstantUInt::get(Type::UIntTy, IterationNum));
+ }
+
+ // Otherwise, compute the value of the PHI node for the next iteration.
+ Constant *Next = EvaluateExpression(BEValue, PHIVal);
+ if (Next == 0 || Next == PHIVal)
+ return UnknownValue; // Couldn't evaluate or not making progress...
+ PHIVal = Next;
+ }
+
+ // Too many iterations were needed to evaluate.
return UnknownValue;
}