Skip to content

Commit 015093d

Browse files
authored
[GVN] Improve processBlock for instruction erasure (#131753)
This patch deletes the instructions immediately in core GVN processing by using the appropriate iterators. Thus, it avoids collecting the instructions in a vector and then doing the erasure.
1 parent d66dbd6 commit 015093d

File tree

2 files changed

+19
-53
lines changed
  • llvm
    • include/llvm/Transforms/Scalar
    • lib/Transforms/Scalar

2 files changed

+19
-53
lines changed

llvm/include/llvm/Transforms/Scalar/GVN.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,7 @@ class GVNPass : public PassInfoMixin<GVNPass> {
137137

138138
/// This removes the specified instruction from
139139
/// our various maps and marks it for deletion.
140-
void markInstructionForDeletion(Instruction *I) {
141-
VN.erase(I);
142-
InstrsToErase.push_back(I);
143-
}
140+
void salvageAndRemoveInstruction(Instruction *I);
144141

145142
DominatorTree &getDominatorTree() const { return *DT; }
146143
AAResults *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
@@ -306,7 +303,6 @@ class GVNPass : public PassInfoMixin<GVNPass> {
306303
// propagate to any successors. Entries added mid-block are applied
307304
// to the remaining instructions in the block.
308305
SmallMapVector<Value *, Value *, 4> ReplaceOperandsWithMap;
309-
SmallVector<Instruction *, 8> InstrsToErase;
310306

311307
// Map the block to reversed postorder traversal number. It is used to
312308
// find back edge easily.

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,12 @@ void GVNPass::printPipeline(
876876
OS << '>';
877877
}
878878

879+
void GVNPass::salvageAndRemoveInstruction(Instruction *I) {
880+
salvageKnowledge(I, AC);
881+
salvageDebugInfo(*I);
882+
removeInstruction(I);
883+
}
884+
879885
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
880886
LLVM_DUMP_METHOD void GVNPass::dump(DenseMap<uint32_t, Value *> &Map) const {
881887
errs() << "{\n";
@@ -1555,7 +1561,6 @@ void GVNPass::eliminatePartiallyRedundantLoad(
15551561
replaceValuesPerBlockEntry(ValuesPerBlock, OldLoad, NewLoad);
15561562
if (uint32_t ValNo = VN.lookup(OldLoad, false))
15571563
LeaderTable.erase(ValNo, OldLoad, OldLoad->getParent());
1558-
VN.erase(OldLoad);
15591564
removeInstruction(OldLoad);
15601565
}
15611566
}
@@ -1572,11 +1577,11 @@ void GVNPass::eliminatePartiallyRedundantLoad(
15721577
I->setDebugLoc(Load->getDebugLoc());
15731578
if (V->getType()->isPtrOrPtrVectorTy())
15741579
MD->invalidateCachedPointerInfo(V);
1575-
markInstructionForDeletion(Load);
15761580
ORE->emit([&]() {
15771581
return OptimizationRemark(DEBUG_TYPE, "LoadPRE", Load)
15781582
<< "load eliminated by PRE";
15791583
});
1584+
salvageAndRemoveInstruction(Load);
15801585
}
15811586

15821587
bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
@@ -1795,7 +1800,7 @@ bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
17951800
// Erase instructions generated by the failed PHI translation before
17961801
// trying to number them. PHI translation might insert instructions
17971802
// in basic blocks other than the current one, and we delete them
1798-
// directly, as markInstructionForDeletion only allows removing from the
1803+
// directly, as salvageAndRemoveInstruction only allows removing from the
17991804
// current basic block.
18001805
NewInsts.pop_back_val()->eraseFromParent();
18011806
}
@@ -1994,9 +1999,9 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) {
19941999
I->setDebugLoc(Load->getDebugLoc());
19952000
if (V->getType()->isPtrOrPtrVectorTy())
19962001
MD->invalidateCachedPointerInfo(V);
1997-
markInstructionForDeletion(Load);
19982002
++NumGVNLoad;
19992003
reportLoadElim(Load, V, ORE);
2004+
salvageAndRemoveInstruction(Load);
20002005
return true;
20012006
}
20022007

@@ -2064,7 +2069,7 @@ bool GVNPass::processAssumeIntrinsic(AssumeInst *IntrinsicI) {
20642069
}
20652070
}
20662071
if (isAssumeWithEmptyBundle(*IntrinsicI)) {
2067-
markInstructionForDeletion(IntrinsicI);
2072+
salvageAndRemoveInstruction(IntrinsicI);
20682073
return true;
20692074
}
20702075
return false;
@@ -2175,7 +2180,7 @@ bool GVNPass::processLoad(LoadInst *L) {
21752180
return false;
21762181

21772182
if (L->use_empty()) {
2178-
markInstructionForDeletion(L);
2183+
salvageAndRemoveInstruction(L);
21792184
return true;
21802185
}
21812186

@@ -2205,11 +2210,11 @@ bool GVNPass::processLoad(LoadInst *L) {
22052210
// MaterializeAdjustedValue is responsible for combining metadata.
22062211
ICF->removeUsersOf(L);
22072212
L->replaceAllUsesWith(AvailableValue);
2208-
markInstructionForDeletion(L);
22092213
if (MSSAU)
22102214
MSSAU->removeMemoryAccess(L);
22112215
++NumGVNLoad;
22122216
reportLoadElim(L, AvailableValue, ORE);
2217+
salvageAndRemoveInstruction(L);
22132218
// Tell MDA to reexamine the reused pointer since we might have more
22142219
// information after forwarding it.
22152220
if (MD && AvailableValue->getType()->isPtrOrPtrVectorTy())
@@ -2601,7 +2606,7 @@ bool GVNPass::processInstruction(Instruction *I) {
26012606
Changed = true;
26022607
}
26032608
if (isInstructionTriviallyDead(I, TLI)) {
2604-
markInstructionForDeletion(I);
2609+
salvageAndRemoveInstruction(I);
26052610
Changed = true;
26062611
}
26072612
if (Changed) {
@@ -2718,7 +2723,7 @@ bool GVNPass::processInstruction(Instruction *I) {
27182723
patchAndReplaceAllUsesWith(I, Repl);
27192724
if (MD && Repl->getType()->isPtrOrPtrVectorTy())
27202725
MD->invalidateCachedPointerInfo(Repl);
2721-
markInstructionForDeletion(I);
2726+
salvageAndRemoveInstruction(I);
27222727
return true;
27232728
}
27242729

@@ -2794,10 +2799,6 @@ bool GVNPass::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
27942799
}
27952800

27962801
bool GVNPass::processBlock(BasicBlock *BB) {
2797-
// FIXME: Kill off InstrsToErase by doing erasing eagerly in a helper function
2798-
// (and incrementing BI before processing an instruction).
2799-
assert(InstrsToErase.empty() &&
2800-
"We expect InstrsToErase to be empty across iterations");
28012802
if (DeadBlocks.count(BB))
28022803
return false;
28032804

@@ -2812,44 +2813,13 @@ bool GVNPass::processBlock(BasicBlock *BB) {
28122813
SmallPtrSet<PHINode *, 8> PHINodesToRemove;
28132814
ChangedFunction |= EliminateDuplicatePHINodes(BB, PHINodesToRemove);
28142815
for (PHINode *PN : PHINodesToRemove) {
2815-
VN.erase(PN);
28162816
removeInstruction(PN);
28172817
}
2818-
2819-
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
2820-
BI != BE;) {
2818+
for (Instruction &Inst : make_early_inc_range(*BB)) {
28212819
if (!ReplaceOperandsWithMap.empty())
2822-
ChangedFunction |= replaceOperandsForInBlockEquality(&*BI);
2823-
ChangedFunction |= processInstruction(&*BI);
2824-
2825-
if (InstrsToErase.empty()) {
2826-
++BI;
2827-
continue;
2828-
}
2829-
2830-
// If we need some instructions deleted, do it now.
2831-
NumGVNInstr += InstrsToErase.size();
2832-
2833-
// Avoid iterator invalidation.
2834-
bool AtStart = BI == BB->begin();
2835-
if (!AtStart)
2836-
--BI;
2837-
2838-
for (auto *I : InstrsToErase) {
2839-
assert(I->getParent() == BB && "Removing instruction from wrong block?");
2840-
LLVM_DEBUG(dbgs() << "GVN removed: " << *I << '\n');
2841-
salvageKnowledge(I, AC);
2842-
salvageDebugInfo(*I);
2843-
removeInstruction(I);
2844-
}
2845-
InstrsToErase.clear();
2846-
2847-
if (AtStart)
2848-
BI = BB->begin();
2849-
else
2850-
++BI;
2820+
ChangedFunction |= replaceOperandsForInBlockEquality(&Inst);
2821+
ChangedFunction |= processInstruction(&Inst);
28512822
}
2852-
28532823
return ChangedFunction;
28542824
}
28552825

@@ -3055,7 +3025,6 @@ bool GVNPass::performScalarPRE(Instruction *CurInst) {
30553025
CurInst->replaceAllUsesWith(Phi);
30563026
if (MD && Phi->getType()->isPtrOrPtrVectorTy())
30573027
MD->invalidateCachedPointerInfo(Phi);
3058-
VN.erase(CurInst);
30593028
LeaderTable.erase(ValNo, CurInst, CurrentBlock);
30603029

30613030
LLVM_DEBUG(dbgs() << "GVN PRE removed: " << *CurInst << '\n');
@@ -3155,6 +3124,7 @@ void GVNPass::cleanupGlobalSets() {
31553124
}
31563125

31573126
void GVNPass::removeInstruction(Instruction *I) {
3127+
VN.erase(I);
31583128
if (MD) MD->removeInstruction(I);
31593129
if (MSSAU)
31603130
MSSAU->removeMemoryAccess(I);

0 commit comments

Comments
 (0)