Skip to content

Commit 1202d28

Browse files
committed
[SCEV][NFC] Reduce memory footprint & compile time via DFS refactoring
Current implementations of DFS in SCEV check unique-visited of traversed values on pop, and not on push. As result, the same value may be pushed multiple times just to be thrown away when popped. These operations are meaningless and only waste time and increase memory footprint of the worklist. This patch reworks the DFS strategy to check uniqueness before push. Should be NFC. Differential Revision: https://reviews.llvm.org/D111774 Reviewed By: nikic, reames
1 parent 44610c0 commit 1202d28

File tree

1 file changed

+21
-24
lines changed

1 file changed

+21
-24
lines changed

llvm/lib/Analysis/ScalarEvolution.cpp

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4410,24 +4410,24 @@ const SCEV *ScalarEvolution::getPointerBase(const SCEV *V) {
44104410
}
44114411

44124412
/// Push users of the given Instruction onto the given Worklist.
4413-
static void
4414-
PushDefUseChildren(Instruction *I,
4415-
SmallVectorImpl<Instruction *> &Worklist) {
4413+
static void PushDefUseChildren(Instruction *I,
4414+
SmallVectorImpl<Instruction *> &Worklist,
4415+
SmallPtrSetImpl<Instruction *> &Visited) {
44164416
// Push the def-use children onto the Worklist stack.
4417-
for (User *U : I->users())
4418-
Worklist.push_back(cast<Instruction>(U));
4417+
for (User *U : I->users()) {
4418+
auto *UserInsn = cast<Instruction>(U);
4419+
if (Visited.insert(UserInsn).second)
4420+
Worklist.push_back(UserInsn);
4421+
}
44194422
}
44204423

44214424
void ScalarEvolution::forgetSymbolicName(Instruction *PN, const SCEV *SymName) {
44224425
SmallVector<Instruction *, 16> Worklist;
4423-
PushDefUseChildren(PN, Worklist);
4424-
44254426
SmallPtrSet<Instruction *, 8> Visited;
44264427
Visited.insert(PN);
4428+
Worklist.push_back(PN);
44274429
while (!Worklist.empty()) {
44284430
Instruction *I = Worklist.pop_back_val();
4429-
if (!Visited.insert(I).second)
4430-
continue;
44314431

44324432
auto It = ValueExprMap.find_as(static_cast<Value *>(I));
44334433
if (It != ValueExprMap.end()) {
@@ -4453,7 +4453,7 @@ void ScalarEvolution::forgetSymbolicName(Instruction *PN, const SCEV *SymName) {
44534453
}
44544454
}
44554455

4456-
PushDefUseChildren(I, Worklist);
4456+
PushDefUseChildren(I, Worklist, Visited);
44574457
}
44584458
}
44594459

@@ -7370,13 +7370,15 @@ bool ScalarEvolution::isBackedgeTakenCountMaxOrZero(const Loop *L) {
73707370
}
73717371

73727372
/// Push PHI nodes in the header of the given loop onto the given Worklist.
7373-
static void
7374-
PushLoopPHIs(const Loop *L, SmallVectorImpl<Instruction *> &Worklist) {
7373+
static void PushLoopPHIs(const Loop *L,
7374+
SmallVectorImpl<Instruction *> &Worklist,
7375+
SmallPtrSetImpl<Instruction *> &Visited) {
73757376
BasicBlock *Header = L->getHeader();
73767377

73777378
// Push all Loop-header PHIs onto the Worklist stack.
73787379
for (PHINode &PN : Header->phis())
7379-
Worklist.push_back(&PN);
7380+
if (Visited.insert(&PN).second)
7381+
Worklist.push_back(&PN);
73807382
}
73817383

73827384
const ScalarEvolution::BackedgeTakenInfo &
@@ -7437,9 +7439,8 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
74377439
// it handles SCEVUnknown PHI nodes specially.
74387440
if (Result.hasAnyInfo()) {
74397441
SmallVector<Instruction *, 16> Worklist;
7440-
PushLoopPHIs(L, Worklist);
7441-
74427442
SmallPtrSet<Instruction *, 8> Discovered;
7443+
PushLoopPHIs(L, Worklist, Discovered);
74437444
while (!Worklist.empty()) {
74447445
Instruction *I = Worklist.pop_back_val();
74457446

@@ -7551,12 +7552,10 @@ void ScalarEvolution::forgetLoop(const Loop *L) {
75517552
}
75527553

75537554
// Drop information about expressions based on loop-header PHIs.
7554-
PushLoopPHIs(CurrL, Worklist);
7555+
PushLoopPHIs(CurrL, Worklist, Visited);
75557556

75567557
while (!Worklist.empty()) {
75577558
Instruction *I = Worklist.pop_back_val();
7558-
if (!Visited.insert(I).second)
7559-
continue;
75607559

75617560
ValueExprMapType::iterator It =
75627561
ValueExprMap.find_as(static_cast<Value *>(I));
@@ -7567,7 +7566,7 @@ void ScalarEvolution::forgetLoop(const Loop *L) {
75677566
ConstantEvolutionLoopExitValue.erase(PN);
75687567
}
75697568

7570-
PushDefUseChildren(I, Worklist);
7569+
PushDefUseChildren(I, Worklist, Visited);
75717570
}
75727571

75737572
LoopPropertiesCache.erase(CurrL);
@@ -7589,14 +7588,12 @@ void ScalarEvolution::forgetValue(Value *V) {
75897588

75907589
// Drop information about expressions based on loop-header PHIs.
75917590
SmallVector<Instruction *, 16> Worklist;
7591+
SmallPtrSet<Instruction *, 8> Visited;
75927592
Worklist.push_back(I);
7593+
Visited.insert(I);
75937594

7594-
SmallPtrSet<Instruction *, 8> Visited;
75957595
while (!Worklist.empty()) {
75967596
I = Worklist.pop_back_val();
7597-
if (!Visited.insert(I).second)
7598-
continue;
7599-
76007597
ValueExprMapType::iterator It =
76017598
ValueExprMap.find_as(static_cast<Value *>(I));
76027599
if (It != ValueExprMap.end()) {
@@ -7606,7 +7603,7 @@ void ScalarEvolution::forgetValue(Value *V) {
76067603
ConstantEvolutionLoopExitValue.erase(PN);
76077604
}
76087605

7609-
PushDefUseChildren(I, Worklist);
7606+
PushDefUseChildren(I, Worklist, Visited);
76107607
}
76117608
}
76127609

0 commit comments

Comments
 (0)