summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcello Maggioni <hayarms@gmail.com>2017-09-11 15:44:20 +0000
committerMarcello Maggioni <hayarms@gmail.com>2017-09-11 15:44:20 +0000
commitce90060d1c19ae968706d594dc9054dcabbc495b (patch)
tree38a7296996d73401e913d58725e906a0a7b823c4
parenteb4474cf20f22d23b05ec7d8a048d2d5cda32992 (diff)
downloadbcm5719-llvm-ce90060d1c19ae968706d594dc9054dcabbc495b.tar.gz
bcm5719-llvm-ce90060d1c19ae968706d594dc9054dcabbc495b.zip
[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
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp85
1 files changed, 45 insertions, 40 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 73ce83e9dbc..640d80a176e 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -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);
-
- SmallPtrSet<Instruction *, 8> 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<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);
- 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<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);
+ }
- 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.
+ LoopWorklist.append(CurrL->begin(), CurrL->end());
+ }
}
void ScalarEvolution::forgetValue(Value *V) {
OpenPOWER on IntegriCloud