Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -6353,7 +6353,7 @@ void ScalarEvolution::forgetLoop(const Loop *L) { // Drop any stored trip count value. auto RemoveLoopFromBackedgeMap = - [L](DenseMap &Map) { + [](DenseMap &Map, const Loop *L) { auto BTCPos = Map.find(L); if (BTCPos != Map.end()) { BTCPos->second.clear(); @@ -6361,53 +6361,59 @@ } }; - RemoveLoopFromBackedgeMap(BackedgeTakenCounts); - RemoveLoopFromBackedgeMap(PredicatedBackedgeTakenCounts); + SmallVector LoopWorklist(1, L); + SmallVector Worklist; + SmallPtrSet Visited; - // Drop information about predicated SCEV rewrites for this loop. - for (auto I = PredicatedSCEVRewrites.begin(); - I != PredicatedSCEVRewrites.end();) { - std::pair Entry = I->first; - if (Entry.second == L) - PredicatedSCEVRewrites.erase(I++); - else - ++I; - } + // Iterate over all the loops and sub-loops to drop SCEV information. + while (!LoopWorklist.empty()) { + auto CurrL = LoopWorklist.pop_back_val(); - // Drop information about expressions based on loop-header PHIs. - SmallVector Worklist; - PushLoopPHIs(L, Worklist); - - SmallPtrSet Visited; - while (!Worklist.empty()) { - Instruction *I = Worklist.pop_back_val(); - if (!Visited.insert(I).second) - continue; + RemoveLoopFromBackedgeMap(BackedgeTakenCounts, CurrL); + RemoveLoopFromBackedgeMap(PredicatedBackedgeTakenCounts, CurrL); - ValueExprMapType::iterator It = - ValueExprMap.find_as(static_cast(I)); - if (It != ValueExprMap.end()) { - eraseValueFromMap(It->first); - forgetMemoizedResults(It->second); - if (PHINode *PN = dyn_cast(I)) - ConstantEvolutionLoopExitValue.erase(PN); + // Drop information about predicated SCEV rewrites for this loop. + for (auto I = PredicatedSCEVRewrites.begin(); + I != PredicatedSCEVRewrites.end();) { + std::pair Entry = I->first; + if (Entry.second == CurrL) + PredicatedSCEVRewrites.erase(I++); + else + ++I; } - PushDefUseChildren(I, Worklist); - } + // Drop information about expressions based on loop-header PHIs. + PushLoopPHIs(CurrL, Worklist); - for (auto I = ExitLimits.begin(); I != ExitLimits.end(); ++I) { - auto &Query = I->first; - if (Query.L == L) - ExitLimits.erase(I); - } + while (!Worklist.empty()) { + Instruction *I = Worklist.pop_back_val(); + if (!Visited.insert(I).second) + continue; - // Forget all contained loops too, to avoid dangling entries in the - // ValuesAtScopes map. - for (Loop *I : *L) - forgetLoop(I); + ValueExprMapType::iterator It = + ValueExprMap.find_as(static_cast(I)); + if (It != ValueExprMap.end()) { + eraseValueFromMap(It->first); + forgetMemoizedResults(It->second); + if (PHINode *PN = dyn_cast(I)) + ConstantEvolutionLoopExitValue.erase(PN); + } + + PushDefUseChildren(I, Worklist); + } - LoopPropertiesCache.erase(L); + for (auto I = ExitLimits.begin(); I != ExitLimits.end(); ++I) { + auto &Query = I->first; + if (Query.L == CurrL) + ExitLimits.erase(I); + } + + LoopPropertiesCache.erase(CurrL); + // Forget all contained loops too, to avoid dangling entries in the + // ValuesAtScopes map. + for (auto CL : *CurrL) + LoopWorklist.push_back(CL); + } } void ScalarEvolution::forgetValue(Value *V) {