Skip to content

Commit ce90060

Browse files
committed
[ScalarEvolution] Refactor forgetLoop() to improve performance
forgetLoop() has pretty bad performance because it goes over the same instructions over and over again in particular when nested loop are involved. The refactoring changes the function to a not-recursive function and reusing the allocation for data-structures and the Visited set. NFCI Differential Revision: https://reviews.llvm.org/D37659 llvm-svn: 312920
1 parent eb4474c commit ce90060

File tree

1 file changed

+45
-40
lines changed

1 file changed

+45
-40
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6353,61 +6353,66 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
63536353
void ScalarEvolution::forgetLoop(const Loop *L) {
63546354
// Drop any stored trip count value.
63556355
auto RemoveLoopFromBackedgeMap =
6356-
[L](DenseMap<const Loop *, BackedgeTakenInfo> &Map) {
6356+
[](DenseMap<const Loop *, BackedgeTakenInfo> &Map, const Loop *L) {
63576357
auto BTCPos = Map.find(L);
63586358
if (BTCPos != Map.end()) {
63596359
BTCPos->second.clear();
63606360
Map.erase(BTCPos);
63616361
}
63626362
};
63636363

6364-
RemoveLoopFromBackedgeMap(BackedgeTakenCounts);
6365-
RemoveLoopFromBackedgeMap(PredicatedBackedgeTakenCounts);
6364+
SmallVector<const Loop *, 16> LoopWorklist(1, L);
6365+
SmallVector<Instruction *, 32> Worklist;
6366+
SmallPtrSet<Instruction *, 16> Visited;
63666367

6367-
// Drop information about predicated SCEV rewrites for this loop.
6368-
for (auto I = PredicatedSCEVRewrites.begin();
6369-
I != PredicatedSCEVRewrites.end();) {
6370-
std::pair<const SCEV *, const Loop *> Entry = I->first;
6371-
if (Entry.second == L)
6372-
PredicatedSCEVRewrites.erase(I++);
6373-
else
6374-
++I;
6375-
}
6368+
// Iterate over all the loops and sub-loops to drop SCEV information.
6369+
while (!LoopWorklist.empty()) {
6370+
auto *CurrL = LoopWorklist.pop_back_val();
63766371

6377-
// Drop information about expressions based on loop-header PHIs.
6378-
SmallVector<Instruction *, 16> Worklist;
6379-
PushLoopPHIs(L, Worklist);
6380-
6381-
SmallPtrSet<Instruction *, 8> Visited;
6382-
while (!Worklist.empty()) {
6383-
Instruction *I = Worklist.pop_back_val();
6384-
if (!Visited.insert(I).second)
6385-
continue;
6372+
RemoveLoopFromBackedgeMap(BackedgeTakenCounts, CurrL);
6373+
RemoveLoopFromBackedgeMap(PredicatedBackedgeTakenCounts, CurrL);
63866374

6387-
ValueExprMapType::iterator It =
6388-
ValueExprMap.find_as(static_cast<Value *>(I));
6389-
if (It != ValueExprMap.end()) {
6390-
eraseValueFromMap(It->first);
6391-
forgetMemoizedResults(It->second);
6392-
if (PHINode *PN = dyn_cast<PHINode>(I))
6393-
ConstantEvolutionLoopExitValue.erase(PN);
6375+
// Drop information about predicated SCEV rewrites for this loop.
6376+
for (auto I = PredicatedSCEVRewrites.begin();
6377+
I != PredicatedSCEVRewrites.end();) {
6378+
std::pair<const SCEV *, const Loop *> Entry = I->first;
6379+
if (Entry.second == CurrL)
6380+
PredicatedSCEVRewrites.erase(I++);
6381+
else
6382+
++I;
63946383
}
63956384

6396-
PushDefUseChildren(I, Worklist);
6397-
}
6385+
// Drop information about expressions based on loop-header PHIs.
6386+
PushLoopPHIs(CurrL, Worklist);
63986387

6399-
for (auto I = ExitLimits.begin(); I != ExitLimits.end(); ++I) {
6400-
auto &Query = I->first;
6401-
if (Query.L == L)
6402-
ExitLimits.erase(I);
6403-
}
6388+
while (!Worklist.empty()) {
6389+
Instruction *I = Worklist.pop_back_val();
6390+
if (!Visited.insert(I).second)
6391+
continue;
64046392

6405-
// Forget all contained loops too, to avoid dangling entries in the
6406-
// ValuesAtScopes map.
6407-
for (Loop *I : *L)
6408-
forgetLoop(I);
6393+
ValueExprMapType::iterator It =
6394+
ValueExprMap.find_as(static_cast<Value *>(I));
6395+
if (It != ValueExprMap.end()) {
6396+
eraseValueFromMap(It->first);
6397+
forgetMemoizedResults(It->second);
6398+
if (PHINode *PN = dyn_cast<PHINode>(I))
6399+
ConstantEvolutionLoopExitValue.erase(PN);
6400+
}
6401+
6402+
PushDefUseChildren(I, Worklist);
6403+
}
64096404

6410-
LoopPropertiesCache.erase(L);
6405+
for (auto I = ExitLimits.begin(); I != ExitLimits.end(); ++I) {
6406+
auto &Query = I->first;
6407+
if (Query.L == CurrL)
6408+
ExitLimits.erase(I);
6409+
}
6410+
6411+
LoopPropertiesCache.erase(CurrL);
6412+
// Forget all contained loops too, to avoid dangling entries in the
6413+
// ValuesAtScopes map.
6414+
LoopWorklist.append(CurrL->begin(), CurrL->end());
6415+
}
64116416
}
64126417

64136418
void ScalarEvolution::forgetValue(Value *V) {

0 commit comments

Comments
 (0)