aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp38
1 files changed, 38 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 8b3fc8d..9670e53 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8410,6 +8410,44 @@ void ScalarEvolution::forgetValue(Value *V) {
forgetMemoizedResults(ToForget);
}
+void ScalarEvolution::forgetLcssaPhiWithNewPredecessor(Loop *L, PHINode *V) {
+ if (!isSCEVable(V->getType()))
+ return;
+
+ // If SCEV looked through a trivial LCSSA phi node, we might have SCEV's
+ // directly using a SCEVUnknown/SCEVAddRec defined in the loop. After an
+ // extra predecessor is added, this is no longer valid. Find all Unknowns and
+ // AddRecs defined in the loop and invalidate any SCEV's making use of them.
+ if (const SCEV *S = getExistingSCEV(V)) {
+ struct InvalidationRootCollector {
+ Loop *L;
+ SmallVector<const SCEV *, 8> Roots;
+
+ InvalidationRootCollector(Loop *L) : L(L) {}
+
+ bool follow(const SCEV *S) {
+ if (auto *SU = dyn_cast<SCEVUnknown>(S)) {
+ if (auto *I = dyn_cast<Instruction>(SU->getValue()))
+ if (L->contains(I))
+ Roots.push_back(S);
+ } else if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
+ if (L->contains(AddRec->getLoop()))
+ Roots.push_back(S);
+ }
+ return true;
+ }
+ bool isDone() const { return false; }
+ };
+
+ InvalidationRootCollector C(L);
+ visitAll(S, C);
+ forgetMemoizedResults(C.Roots);
+ }
+
+ // Also perform the normal invalidation.
+ forgetValue(V);
+}
+
void ScalarEvolution::forgetLoopDispositions() { LoopDispositions.clear(); }
void ScalarEvolution::forgetBlockAndLoopDispositions(Value *V) {