summaryrefslogtreecommitdiff
path: root/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp49
1 files changed, 32 insertions, 17 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index ad176098ce..f5804430ee 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -4691,7 +4691,7 @@ static bool canConstantEvolve(Instruction *I, const Loop *L) {
/// recursing through each instruction operand until reaching a loop header phi.
static PHINode *
getConstantEvolvingPHIOperands(Instruction *UseInst, const Loop *L,
- SmallPtrSet<Instruction *, 8> &Visited) {
+ DenseMap<Instruction *, PHINode *> &PHIMap) {
// Otherwise, we can evaluate this instruction if all of its operands are
// constant or derived from a PHI node themselves.
@@ -4705,18 +4705,26 @@ getConstantEvolvingPHIOperands(Instruction *UseInst, const Loop *L,
if (!OpInst || !canConstantEvolve(OpInst, L)) return 0;
PHINode *P = dyn_cast<PHINode>(OpInst);
- if (!P) {
- // If this operand is already visited, ignore it. It's evolving phi has
- // already been shown to be consistent on the first path that reached it.
- if (!Visited.insert(OpInst)) continue;
-
- P = getConstantEvolvingPHIOperands(OpInst, L, Visited);
+ if (P) {
+ if (PHI && PHI != P) return 0; // Evolving from multiple different PHIs.
+ PHI = P;
+ continue;
}
- if (P == 0) return 0; // Not evolving from PHI
- if (PHI == 0)
+
+ // If this operand is already visited, reuse the prior result.
+ P = PHIMap.lookup(OpInst);
+ if (P) {
+ assert(!PHI || P == PHI && "inconsitent data flow");
PHI = P;
- else if (PHI != P)
- return 0; // Evolving from multiple different PHIs.
+ continue;
+ }
+ // Recurse and memoize the results, whether a phi is found or not.
+ // This recursive call invalidates pointers into PHIMap.
+ P = getConstantEvolvingPHIOperands(OpInst, L, PHIMap);
+ PHIMap[OpInst] = P;
+ if (P == 0) return 0; // Not evolving from PHI
+ if (PHI && PHI != P) return 0; // Evolving from multiple different PHIs.
+ PHI = P;
}
// This is a expression evolving from a constant PHI!
return PHI;
@@ -4736,9 +4744,8 @@ static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) {
}
// Record non-constant instructions contained by the loop.
- SmallPtrSet<Instruction *, 8> Visited;
- Visited.insert(I);
- return getConstantEvolvingPHIOperands(I, L, Visited);
+ DenseMap<Instruction *, PHINode *> PHIMap;
+ return getConstantEvolvingPHIOperands(I, L, PHIMap);
}
/// EvaluateExpression - Given an expression that passes the
@@ -4748,6 +4755,7 @@ static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) {
static Constant *EvaluateExpression(Value *V, const Loop *L,
DenseMap<Instruction *, Constant *> &Vals,
const TargetData *TD) {
+ // Convenient constant check, but redundant for recursive calls.
if (Constant *C = dyn_cast<Constant>(V)) return C;
Instruction *I = cast<Instruction>(V);
@@ -4760,8 +4768,15 @@ static Constant *EvaluateExpression(Value *V, const Loop *L,
std::vector<Constant*> Operands(I->getNumOperands());
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
- Operands[i] = EvaluateExpression(I->getOperand(i), L, Vals, TD);
- if (Operands[i] == 0) return 0;
+ Instruction *Operand = dyn_cast<Instruction>(I->getOperand(i));
+ if (!Operand) {
+ Operands[i] = cast<Constant>(I->getOperand(i));
+ continue;
+ }
+ Constant *C = EvaluateExpression(Operand, L, Vals, TD);
+ Vals[Operand] = C;
+ if (!C) return 0;
+ Operands[i] = C;
}
if (const CmpInst *CI = dyn_cast<CmpInst>(I))
@@ -4861,9 +4876,9 @@ const SCEV * ScalarEvolution::ComputeExitCountExhaustively(const Loop *L,
// "ExitWhen".
unsigned IterationNum = 0;
unsigned MaxIterations = MaxBruteForceIterations; // Limit analysis.
- DenseMap<Instruction *, Constant *> PHIValMap;
for (Constant *PHIVal = StartCST;
IterationNum != MaxIterations; ++IterationNum) {
+ DenseMap<Instruction *, Constant *> PHIValMap;
PHIValMap[PN] = PHIVal;
ConstantInt *CondVal =
dyn_cast_or_null<ConstantInt>(EvaluateExpression(Cond, L, PHIValMap, TD));