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,31 @@ 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
+ for (auto *Succ : RemovedSuccessors) {
581
+ // It might have happened that the same successor appeared multiple times
582
+ // and the CFG edge wasn't really removed.
583
+ if (Succ != PreferredSucc->BB ) {
584
+ DEBUG (dbgs () << " ADCE: Removing (Post)DomTree edge " << BB->getName ()
585
+ << " -> " << Succ->getName () << " \n " );
586
+ DT.deleteEdge (BB, Succ);
587
+ PDT.deleteEdge (BB, Succ);
588
+ }
589
+ }
590
+
568
591
NumBranchesRemoved += 1 ;
569
592
}
570
593
}
@@ -609,6 +632,9 @@ void AggressiveDeadCodeElimination::makeUnconditional(BasicBlock *BB,
609
632
InstInfo[NewTerm].Live = true ;
610
633
if (const DILocation *DL = PredTerm->getDebugLoc ())
611
634
NewTerm->setDebugLoc (DL);
635
+
636
+ InstInfo.erase (PredTerm);
637
+ PredTerm->eraseFromParent ();
612
638
}
613
639
614
640
// ===----------------------------------------------------------------------===//
@@ -617,13 +643,16 @@ void AggressiveDeadCodeElimination::makeUnconditional(BasicBlock *BB,
617
643
//
618
644
// ===----------------------------------------------------------------------===//
619
645
PreservedAnalyses ADCEPass::run (Function &F, FunctionAnalysisManager &FAM) {
646
+ auto &DT = FAM.getResult <DominatorTreeAnalysis>(F);
620
647
auto &PDT = FAM.getResult <PostDominatorTreeAnalysis>(F);
621
- if (!AggressiveDeadCodeElimination (F, PDT).performDeadCodeElimination ())
648
+ if (!AggressiveDeadCodeElimination (F, DT, PDT).performDeadCodeElimination ())
622
649
return PreservedAnalyses::all ();
623
650
624
651
PreservedAnalyses PA;
625
652
PA.preserveSet <CFGAnalyses>();
626
653
PA.preserve <GlobalsAA>();
654
+ PA.preserve <DominatorTreeAnalysis>();
655
+ PA.preserve <PostDominatorTreeAnalysis>();
627
656
return PA;
628
657
}
629
658
@@ -637,14 +666,23 @@ struct ADCELegacyPass : public FunctionPass {
637
666
bool runOnFunction (Function &F) override {
638
667
if (skipFunction (F))
639
668
return false ;
669
+
670
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree ();
640
671
auto &PDT = getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree ();
641
- return AggressiveDeadCodeElimination (F, PDT).performDeadCodeElimination ();
672
+ return AggressiveDeadCodeElimination (F, DT, PDT)
673
+ .performDeadCodeElimination ();
642
674
}
643
675
644
676
void getAnalysisUsage (AnalysisUsage &AU) const override {
677
+ // We require DominatorTree here only to update and thus preserve it.
678
+ AU.addRequired <DominatorTreeWrapperPass>();
645
679
AU.addRequired <PostDominatorTreeWrapperPass>();
646
680
if (!RemoveControlFlowFlag)
647
681
AU.setPreservesCFG ();
682
+ else {
683
+ AU.addPreserved <DominatorTreeWrapperPass>();
684
+ AU.addPreserved <PostDominatorTreeWrapperPass>();
685
+ }
648
686
AU.addPreserved <GlobalsAAWrapperPass>();
649
687
}
650
688
};
@@ -653,6 +691,7 @@ struct ADCELegacyPass : public FunctionPass {
653
691
char ADCELegacyPass::ID = 0 ;
654
692
INITIALIZE_PASS_BEGIN (ADCELegacyPass, " adce" ,
655
693
" Aggressive Dead Code Elimination" , false , false )
694
+ INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
656
695
INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
657
696
INITIALIZE_PASS_END(ADCELegacyPass, " adce" , " Aggressive Dead Code Elimination" ,
658
697
false , false )
0 commit comments