[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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312920 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Marcello Maggioni 2017-09-11 15:44:20 +00:00
parent 9fb31c8ca3
commit 022ffdf29f

View File

@ -6353,7 +6353,7 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
void ScalarEvolution::forgetLoop(const Loop *L) {
// Drop any stored trip count value.
auto RemoveLoopFromBackedgeMap =
[L](DenseMap<const Loop *, BackedgeTakenInfo> &Map) {
[](DenseMap<const Loop *, BackedgeTakenInfo> &Map, const Loop *L) {
auto BTCPos = Map.find(L);
if (BTCPos != Map.end()) {
BTCPos->second.clear();
@ -6361,53 +6361,58 @@ void ScalarEvolution::forgetLoop(const Loop *L) {
}
};
RemoveLoopFromBackedgeMap(BackedgeTakenCounts);
RemoveLoopFromBackedgeMap(PredicatedBackedgeTakenCounts);
SmallVector<const Loop *, 16> LoopWorklist(1, L);
SmallVector<Instruction *, 32> Worklist;
SmallPtrSet<Instruction *, 16> Visited;
// Drop information about predicated SCEV rewrites for this loop.
for (auto I = PredicatedSCEVRewrites.begin();
I != PredicatedSCEVRewrites.end();) {
std::pair<const SCEV *, const Loop *> 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<Instruction *, 16> Worklist;
PushLoopPHIs(L, Worklist);
RemoveLoopFromBackedgeMap(BackedgeTakenCounts, CurrL);
RemoveLoopFromBackedgeMap(PredicatedBackedgeTakenCounts, CurrL);
SmallPtrSet<Instruction *, 8> Visited;
while (!Worklist.empty()) {
Instruction *I = Worklist.pop_back_val();
if (!Visited.insert(I).second)
continue;
ValueExprMapType::iterator It =
ValueExprMap.find_as(static_cast<Value *>(I));
if (It != ValueExprMap.end()) {
eraseValueFromMap(It->first);
forgetMemoizedResults(It->second);
if (PHINode *PN = dyn_cast<PHINode>(I))
ConstantEvolutionLoopExitValue.erase(PN);
// Drop information about predicated SCEV rewrites for this loop.
for (auto I = PredicatedSCEVRewrites.begin();
I != PredicatedSCEVRewrites.end();) {
std::pair<const SCEV *, const Loop *> 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);
while (!Worklist.empty()) {
Instruction *I = Worklist.pop_back_val();
if (!Visited.insert(I).second)
continue;
ValueExprMapType::iterator It =
ValueExprMap.find_as(static_cast<Value *>(I));
if (It != ValueExprMap.end()) {
eraseValueFromMap(It->first);
forgetMemoizedResults(It->second);
if (PHINode *PN = dyn_cast<PHINode>(I))
ConstantEvolutionLoopExitValue.erase(PN);
}
PushDefUseChildren(I, Worklist);
}
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.
LoopWorklist.append(CurrL->begin(), CurrL->end());
}
for (auto I = ExitLimits.begin(); I != ExitLimits.end(); ++I) {
auto &Query = I->first;
if (Query.L == L)
ExitLimits.erase(I);
}
// Forget all contained loops too, to avoid dangling entries in the
// ValuesAtScopes map.
for (Loop *I : *L)
forgetLoop(I);
LoopPropertiesCache.erase(L);
}
void ScalarEvolution::forgetValue(Value *V) {