diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h index 548c6c503dc26..2d2ef0c9c4a27 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -2037,6 +2037,12 @@ class ScalarEvolution { /// Helper for forgetMemoizedResults. void forgetMemoizedResultsImpl(const SCEV *S); + /// Iterate over instructions in \p Worklist and their users. Erase entries + /// from ValueExprMap and collect SCEV expressions in \p ToForget + void visitAndClearUsers(SmallVectorImpl &Worklist, + SmallPtrSetImpl &Visited, + SmallVectorImpl &ToForget); + /// Return an existing SCEV for V if there is one, otherwise return nullptr. const SCEV *getExistingSCEV(Value *V); diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index a820879b22082..f997b1950a4d4 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -8415,6 +8415,25 @@ void ScalarEvolution::forgetAllLoops() { FoldCache.clear(); FoldCacheUser.clear(); } +void ScalarEvolution::visitAndClearUsers( + SmallVectorImpl &Worklist, + SmallPtrSetImpl &Visited, + SmallVectorImpl &ToForget) { + while (!Worklist.empty()) { + Instruction *I = Worklist.pop_back_val(); + + ValueExprMapType::iterator It = + ValueExprMap.find_as(static_cast(I)); + if (It != ValueExprMap.end()) { + eraseValueFromMap(It->first); + ToForget.push_back(It->second); + if (PHINode *PN = dyn_cast(I)) + ConstantEvolutionLoopExitValue.erase(PN); + } + + PushDefUseChildren(I, Worklist, Visited); + } +} void ScalarEvolution::forgetLoop(const Loop *L) { SmallVector LoopWorklist(1, L); @@ -8448,21 +8467,7 @@ void ScalarEvolution::forgetLoop(const Loop *L) { // Drop information about expressions based on loop-header PHIs. PushLoopPHIs(CurrL, Worklist, Visited); - - while (!Worklist.empty()) { - Instruction *I = Worklist.pop_back_val(); - - ValueExprMapType::iterator It = - ValueExprMap.find_as(static_cast(I)); - if (It != ValueExprMap.end()) { - eraseValueFromMap(It->first); - ToForget.push_back(It->second); - if (PHINode *PN = dyn_cast(I)) - ConstantEvolutionLoopExitValue.erase(PN); - } - - PushDefUseChildren(I, Worklist, Visited); - } + visitAndClearUsers(Worklist, Visited, ToForget); LoopPropertiesCache.erase(CurrL); // Forget all contained loops too, to avoid dangling entries in the @@ -8486,20 +8491,8 @@ void ScalarEvolution::forgetValue(Value *V) { SmallVector ToForget; Worklist.push_back(I); Visited.insert(I); + visitAndClearUsers(Worklist, Visited, ToForget); - while (!Worklist.empty()) { - I = Worklist.pop_back_val(); - ValueExprMapType::iterator It = - ValueExprMap.find_as(static_cast(I)); - if (It != ValueExprMap.end()) { - eraseValueFromMap(It->first); - ToForget.push_back(It->second); - if (PHINode *PN = dyn_cast(I)) - ConstantEvolutionLoopExitValue.erase(PN); - } - - PushDefUseChildren(I, Worklist, Visited); - } forgetMemoizedResults(ToForget); }