diff options
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 38 |
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) { |