27
27
#include " llvm/IR/BasicBlock.h"
28
28
#include " llvm/IR/CFG.h"
29
29
#include " llvm/IR/DebugInfoMetadata.h"
30
+ #include " llvm/IR/Dominators.h"
30
31
#include " llvm/IR/IRBuilder.h"
31
32
#include " llvm/IR/InstIterator.h"
32
33
#include " llvm/IR/Instructions.h"
@@ -89,6 +90,10 @@ struct BlockInfoType {
89
90
90
91
class AggressiveDeadCodeElimination {
91
92
Function &F;
93
+
94
+ // ADCE does not use DominatorTree per se, but it updates it to preserve the
95
+ // analysis.
96
+ DominatorTree &DT;
92
97
PostDominatorTree &PDT;
93
98
94
99
// / Mapping of blocks to associated information, an element in BlockInfoVec.
@@ -157,9 +162,10 @@ class AggressiveDeadCodeElimination {
157
162
void makeUnconditional (BasicBlock *BB, BasicBlock *Target);
158
163
159
164
public:
160
- AggressiveDeadCodeElimination (Function &F, PostDominatorTree &PDT)
161
- : F(F), PDT(PDT) {}
162
- bool performDeadCodeElimination ();
165
+ AggressiveDeadCodeElimination (Function &F, DominatorTree &DT,
166
+ PostDominatorTree &PDT)
167
+ : F(F), DT(DT), PDT(PDT) {}
168
+ bool performDeadCodeElimination ();
163
169
};
164
170
}
165
171
@@ -557,14 +563,34 @@ void AggressiveDeadCodeElimination::updateDeadRegions() {
557
563
}
558
564
assert ((PreferredSucc && PreferredSucc->PostOrder > 0 ) &&
559
565
" Failed to find safe successor for dead branch" );
566
+
567
+ // Collect removed successors to update the (Post)DominatorTrees.
568
+ SmallPtrSet<BasicBlock *, 4 > RemovedSuccessors;
560
569
bool First = true ;
561
570
for (auto *Succ : successors (BB)) {
562
- if (!First || Succ != PreferredSucc->BB )
571
+ if (!First || Succ != PreferredSucc->BB ) {
563
572
Succ->removePredecessor (BB);
564
- else
573
+ RemovedSuccessors.insert (Succ);
574
+ } else
565
575
First = false ;
566
576
}
567
577
makeUnconditional (BB, PreferredSucc->BB );
578
+
579
+ // Inform the dominators about the deleted CFG edges.
580
+ SmallVector<DominatorTree::UpdateType, 4 > DeletedEdges;
581
+ for (auto *Succ : RemovedSuccessors) {
582
+ // It might have happened that the same successor appeared multiple times
583
+ // and the CFG edge wasn't really removed.
584
+ if (Succ != PreferredSucc->BB ) {
585
+ DEBUG (dbgs () << " ADCE: (Post)DomTree edge enqueued for deletion"
586
+ << BB->getName () << " -> " << Succ->getName () << " \n " );
587
+ DeletedEdges.push_back ({DominatorTree::Delete, BB, Succ});
588
+ }
589
+ }
590
+
591
+ DT.applyUpdates (DeletedEdges);
592
+ PDT.applyUpdates (DeletedEdges);
593
+
568
594
NumBranchesRemoved += 1 ;
569
595
}
570
596
}
@@ -609,6 +635,9 @@ void AggressiveDeadCodeElimination::makeUnconditional(BasicBlock *BB,
609
635
InstInfo[NewTerm].Live = true ;
610
636
if (const DILocation *DL = PredTerm->getDebugLoc ())
611
637
NewTerm->setDebugLoc (DL);
638
+
639
+ InstInfo.erase (PredTerm);
640
+ PredTerm->eraseFromParent ();
612
641
}
613
642
614
643
// ===----------------------------------------------------------------------===//
@@ -617,13 +646,16 @@ void AggressiveDeadCodeElimination::makeUnconditional(BasicBlock *BB,
617
646
//
618
647
// ===----------------------------------------------------------------------===//
619
648
PreservedAnalyses ADCEPass::run (Function &F, FunctionAnalysisManager &FAM) {
649
+ auto &DT = FAM.getResult <DominatorTreeAnalysis>(F);
620
650
auto &PDT = FAM.getResult <PostDominatorTreeAnalysis>(F);
621
- if (!AggressiveDeadCodeElimination (F, PDT).performDeadCodeElimination ())
651
+ if (!AggressiveDeadCodeElimination (F, DT, PDT).performDeadCodeElimination ())
622
652
return PreservedAnalyses::all ();
623
653
624
654
PreservedAnalyses PA;
625
655
PA.preserveSet <CFGAnalyses>();
626
656
PA.preserve <GlobalsAA>();
657
+ PA.preserve <DominatorTreeAnalysis>();
658
+ PA.preserve <PostDominatorTreeAnalysis>();
627
659
return PA;
628
660
}
629
661
@@ -637,14 +669,23 @@ struct ADCELegacyPass : public FunctionPass {
637
669
bool runOnFunction (Function &F) override {
638
670
if (skipFunction (F))
639
671
return false ;
672
+
673
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
640
674
auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree ();
641
- return AggressiveDeadCodeElimination (F, PDT).performDeadCodeElimination ();
675
+ return AggressiveDeadCodeElimination (F, DT, PDT)
676
+ .performDeadCodeElimination ();
642
677
}
643
678
644
679
void getAnalysisUsage (AnalysisUsage &AU) const override {
680
+ // We require DominatorTree here only to update and thus preserve it.
681
+ AU.addRequired <DominatorTreeWrapperPass>();
645
682
AU.addRequired <PostDominatorTreeWrapperPass>();
646
683
if (!RemoveControlFlowFlag)
647
684
AU.setPreservesCFG ();
685
+ else {
686
+ AU.addPreserved <DominatorTreeWrapperPass>();
687
+ AU.addPreserved <PostDominatorTreeWrapperPass>();
688
+ }
648
689
AU.addPreserved <GlobalsAAWrapperPass>();
649
690
}
650
691
};
@@ -653,6 +694,7 @@ struct ADCELegacyPass : public FunctionPass {
653
694
char ADCELegacyPass::ID = 0 ;
654
695
INITIALIZE_PASS_BEGIN (ADCELegacyPass, " adce" ,
655
696
" Aggressive Dead Code Elimination" , false , false )
697
+ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
656
698
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
657
699
INITIALIZE_PASS_END(ADCELegacyPass, " adce" , " Aggressive Dead Code Elimination" ,
658
700
false , false )
0 commit comments