diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -2039,6 +2039,12 @@ /// Helper for forgetMemoizedResults. void forgetMemoizedResultsImpl(const SCEV *S); + /// Iterate over instructions in \p Worlist 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 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -8435,6 +8435,25 @@ 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); @@ -8468,21 +8487,7 @@ // 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 @@ -8506,20 +8511,8 @@ 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); }