[llvm-commits] CVS: llvm/lib/Analysis/ScalarEvolution.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sat Feb 12 20:37:33 PST 2005
Changes in directory llvm/lib/Analysis:
ScalarEvolution.cpp updated: 1.31 -> 1.32
---
Log message:
Correct the recursive PHI node handling routines in a way that CANNOT induce
infinite loops (using the new replaceSymbolicValuesWithConcrete method).
This patch reverts this patch:
http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20050131/023830.html
... which was an attempted fix for this problem. Unfortunately, that patch
caused test/Regression/Transforms/IndVarsSimplify/exit_value_tests.llx to fail
and slightly castrated the entire analysis. This patch fixes it right.
This patch is dedicated to jeffc, for making me deal with this. :)
---
Diffs of the changes: (+83 -27)
ScalarEvolution.cpp | 110 +++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 83 insertions(+), 27 deletions(-)
Index: llvm/lib/Analysis/ScalarEvolution.cpp
diff -u llvm/lib/Analysis/ScalarEvolution.cpp:1.31 llvm/lib/Analysis/ScalarEvolution.cpp:1.32
--- llvm/lib/Analysis/ScalarEvolution.cpp:1.31 Mon Jan 31 18:18:30 2005
+++ llvm/lib/Analysis/ScalarEvolution.cpp Sat Feb 12 22:37:18 2005
@@ -144,6 +144,12 @@
return false;
}
+SCEVHandle SCEVCouldNotCompute::
+replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ return this;
+}
+
void SCEVCouldNotCompute::print(std::ostream &OS) const {
OS << "***COULDNOTCOMPUTE***";
}
@@ -259,6 +265,33 @@
OS << ")";
}
+SCEVHandle SCEVCommutativeExpr::
+replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ SCEVHandle H = getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H != getOperand(i)) {
+ std::vector<SCEVHandle> NewOps;
+ NewOps.reserve(getNumOperands());
+ for (unsigned j = 0; j != i; ++j)
+ NewOps.push_back(getOperand(j));
+ NewOps.push_back(H);
+ for (++i; i != e; ++i)
+ NewOps.push_back(getOperand(i)->
+ replaceSymbolicValuesWithConcrete(Sym, Conc));
+
+ if (isa<SCEVAddExpr>(this))
+ return SCEVAddExpr::get(NewOps);
+ else if (isa<SCEVMulExpr>(this))
+ return SCEVMulExpr::get(NewOps);
+ else
+ assert(0 && "Unknown commutative expr!");
+ }
+ }
+ return this;
+}
+
+
// SCEVUDivs - Only allow the creation of one SCEVUDivExpr for any particular
// input. Don't use a SCEVHandle here, or else the object will never be
// deleted!
@@ -290,6 +323,28 @@
Operands.end())));
}
+SCEVHandle SCEVAddRecExpr::
+replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ SCEVHandle H = getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H != getOperand(i)) {
+ std::vector<SCEVHandle> NewOps;
+ NewOps.reserve(getNumOperands());
+ for (unsigned j = 0; j != i; ++j)
+ NewOps.push_back(getOperand(j));
+ NewOps.push_back(H);
+ for (++i; i != e; ++i)
+ NewOps.push_back(getOperand(i)->
+ replaceSymbolicValuesWithConcrete(Sym, Conc));
+
+ return get(NewOps, L);
+ }
+ }
+ return this;
+}
+
+
bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const {
// This recurrence is invariant w.r.t to QueryLoop iff QueryLoop doesn't
// contain L.
@@ -1086,8 +1141,14 @@
/// createNodeForPHI - Provide the special handling we need to analyze PHI
/// SCEVs.
SCEVHandle createNodeForPHI(PHINode *PN);
- void UpdatePHIUserScalarEntries(Instruction *I, PHINode *PN,
- std::set<Instruction*> &UpdatedInsts);
+
+ /// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value
+ /// for the specified instruction and replaces any references to the
+ /// symbolic value SymName with the specified value. This is used during
+ /// PHI resolution.
+ void ReplaceSymbolicValueWithConcrete(Instruction *I,
+ const SCEVHandle &SymName,
+ const SCEVHandle &NewVal);
/// ComputeIterationCount - Compute the number of times the specified loop
/// will iterate.
@@ -1153,26 +1214,27 @@
return S;
}
-
-/// UpdatePHIUserScalarEntries - After PHI node analysis, we have a bunch of
-/// entries in the scalar map that refer to the "symbolic" PHI value instead of
-/// the recurrence value. After we resolve the PHI we must loop over all of the
-/// using instructions that have scalar map entries and update them.
-void ScalarEvolutionsImpl::UpdatePHIUserScalarEntries(Instruction *I,
- PHINode *PN,
- std::set<Instruction*> &UpdatedInsts) {
+/// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value for
+/// the specified instruction and replaces any references to the symbolic value
+/// SymName with the specified value. This is used during PHI resolution.
+void ScalarEvolutionsImpl::
+ReplaceSymbolicValueWithConcrete(Instruction *I, const SCEVHandle &SymName,
+ const SCEVHandle &NewVal) {
std::map<Value*, SCEVHandle>::iterator SI = Scalars.find(I);
- if (SI == Scalars.end()) return; // This scalar wasn't previous processed.
- if (UpdatedInsts.insert(I).second && !isa<PHINode>(PN)) {
- Scalars.erase(SI); // Remove the old entry
- getSCEV(I); // Calculate the new entry
-
- for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
- UI != E; ++UI)
- UpdatePHIUserScalarEntries(cast<Instruction>(*UI), PN, UpdatedInsts);
- }
-}
+ if (SI == Scalars.end()) return;
+ SCEVHandle NV =
+ SI->second->replaceSymbolicValuesWithConcrete(SymName, NewVal);
+ if (NV == SI->second) return; // No change.
+
+ SI->second = NV; // Update the scalars map!
+
+ // Any instruction values that use this instruction might also need to be
+ // updated!
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; ++UI)
+ ReplaceSymbolicValueWithConcrete(cast<Instruction>(*UI), SymName, NewVal);
+}
/// createNodeForPHI - PHI nodes have two cases. Either the PHI node exists in
/// a loop header, making it a potential recurrence, or it doesn't.
@@ -1233,13 +1295,7 @@
// entries for the scalars that use the PHI (except for the PHI
// itself) to use the new analyzed value instead of the "symbolic"
// value.
- Scalars.find(PN)->second = PHISCEV; // Update the PHI value
- std::set<Instruction*> UpdatedInsts;
- UpdatedInsts.insert(PN);
- for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end();
- UI != E; ++UI)
- UpdatePHIUserScalarEntries(cast<Instruction>(*UI), PN,
- UpdatedInsts);
+ ReplaceSymbolicValueWithConcrete(PN, SymbolicName, PHISCEV);
return PHISCEV;
}
}
More information about the llvm-commits
mailing list