summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-02-18 23:26:33 +0000
committerDan Gohman <gohman@apple.com>2010-02-18 23:26:33 +0000
commit60b3326435d8b2980bcefc5d07d1e5f1beafd43a (patch)
tree2d49cff642bc4c3f1551dcb83542da93fdf7693e /llvm/lib/Analysis
parent1e21cc7d197dc287cccdbad8cd7b41f2d2b7654b (diff)
downloadbcm5719-llvm-60b3326435d8b2980bcefc5d07d1e5f1beafd43a.tar.gz
bcm5719-llvm-60b3326435d8b2980bcefc5d07d1e5f1beafd43a.zip
Indvars needs to explicitly notify ScalarEvolution when it is replacing
a loop exit value, so that if a loop gets deleted, ScalarEvolution isn't stick holding on to dangling SCEVAddRecExprs for that loop. This fixes PR6339. llvm-svn: 96626
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 82200cd0281..c2284a8ab9b 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3485,6 +3485,35 @@ void ScalarEvolution::forgetLoop(const Loop *L) {
}
}
+/// forgetValue - This method should be called by the client when it has
+/// changed a value in a way that may effect its value, or which may
+/// disconnect it from a def-use chain linking it to a loop.
+void ScalarEvolution::forgetValue(Value *V) {
+ Instruction *I = dyn_cast<Instruction>(V);
+ if (!I) return;
+
+ // Drop information about expressions based on loop-header PHIs.
+ SmallVector<Instruction *, 16> Worklist;
+ Worklist.push_back(I);
+
+ SmallPtrSet<Instruction *, 8> Visited;
+ while (!Worklist.empty()) {
+ I = Worklist.pop_back_val();
+ if (!Visited.insert(I)) continue;
+
+ std::map<SCEVCallbackVH, const SCEV *>::iterator It =
+ Scalars.find(static_cast<Value *>(I));
+ if (It != Scalars.end()) {
+ ValuesAtScopes.erase(It->second);
+ Scalars.erase(It);
+ if (PHINode *PN = dyn_cast<PHINode>(I))
+ ConstantEvolutionLoopExitValue.erase(PN);
+ }
+
+ PushDefUseChildren(I, Worklist);
+ }
+}
+
/// ComputeBackedgeTakenCount - Compute the number of times the backedge
/// of the specified loop will execute.
ScalarEvolution::BackedgeTakenInfo
OpenPOWER on IntegriCloud