xref: /llvm-project/llvm/lib/Transforms/Scalar/ADCE.cpp (revision 45e442ebaa1e626174d93380914d9f1133a06d25)
1 //===- ADCE.cpp - Code to perform dead code elimination -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the Aggressive Dead Code Elimination pass.  This pass
11 // optimistically assumes that all instructions are dead until proven otherwise,
12 // allowing it to eliminate dead computations that other DCE passes do not
13 // catch, particularly involving loop computations.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "llvm/Transforms/Scalar/ADCE.h"
18 
19 #include "llvm/ADT/DepthFirstIterator.h"
20 #include "llvm/ADT/SmallPtrSet.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/Analysis/GlobalsModRef.h"
24 #include "llvm/IR/BasicBlock.h"
25 #include "llvm/IR/CFG.h"
26 #include "llvm/IR/DebugInfoMetadata.h"
27 #include "llvm/IR/InstIterator.h"
28 #include "llvm/IR/Instructions.h"
29 #include "llvm/IR/IntrinsicInst.h"
30 #include "llvm/Pass.h"
31 #include "llvm/ProfileData/InstrProf.h"
32 #include "llvm/Transforms/Scalar.h"
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "adce"
36 
37 STATISTIC(NumRemoved, "Number of instructions removed");
38 
39 namespace {
40 class AggressiveDeadCodeElimination {
41   Function &F;
42   /// Instructions known to be live.
43   SmallPtrSet<Instruction *, 32> Alive;
44   /// Instructions known to be live where we need to mark
45   /// reaching definitions as live.
46   SmallVector<Instruction *, 128> Worklist;
47   /// Debug info scopes around a live instruction.
48   SmallPtrSet<const Metadata *, 32> AliveScopes;
49 
50   void initialize();
51   /// True for operations which are always treated as live.
52   bool isAlwaysLive(Instruction &I);
53   /// True for instrumentation instructions for value profiling.
54   bool isInstrumentsConstant(Instruction &I);
55 
56 
57   /// Propagate liveness to reaching definitions.
58   void markLiveInstructions();
59   /// Mark an instruction as live.
60   void markLive(Instruction &I);
61 
62   void collectLiveScopes(const DILocalScope &LS);
63   void collectLiveScopes(const DILocation &DL);
64 
65 
66   /// Remove instructions not marked live, return if any any instruction
67   /// was removed.
68   bool removeDeadInstructions();
69 
70 public:
71   AggressiveDeadCodeElimination(Function &F) : F(F) {}
72   bool performDeadCodeElimination();
73 };
74 }
75 
76 bool AggressiveDeadCodeElimination::performDeadCodeElimination() {
77   initialize();
78   markLiveInstructions();
79   return removeDeadInstructions();
80 }
81 
82 void AggressiveDeadCodeElimination::initialize() {
83   // Collect the set of "root" instructions that are known live.
84   for (Instruction &I : instructions(F))
85     if (isAlwaysLive(I))
86       markLive(I);
87 }
88 
89 bool AggressiveDeadCodeElimination::isAlwaysLive(Instruction &I) {
90 
91   // TODO -- use llvm::isInstructionTriviallyDead
92   if (isa<TerminatorInst>(I) || I.isEHPad() || I.mayHaveSideEffects()) {
93     // Skip any value profile instrumentation calls if they are
94     // instrumenting constants.
95     if (!isInstrumentsConstant(I))
96       return true;
97   }
98   return false;
99 }
100 
101 // Check if this instruction is a runtime call for value profiling and
102 // if it's instrumenting a constant.
103 bool AggressiveDeadCodeElimination::isInstrumentsConstant(Instruction &I) {
104   // TODO -- move this test into llvm::isInstructionTriviallyDead
105   if (CallInst *CI = dyn_cast<CallInst>(&I))
106     if (Function *Callee = CI->getCalledFunction())
107       if (Callee->getName().equals(getInstrProfValueProfFuncName()))
108         if (isa<Constant>(CI->getArgOperand(0)))
109           return true;
110   return false;
111 }
112 
113 void AggressiveDeadCodeElimination::markLiveInstructions() {
114 
115   // Propagate liveness backwards to operands.  Keep track of live debug info
116   // scopes.
117   while (!Worklist.empty()) {
118     Instruction *Curr = Worklist.pop_back_val();
119 
120     // Collect the live debug info scopes attached to this instruction.
121     if (const DILocation *DL = Curr->getDebugLoc())
122       collectLiveScopes(*DL);
123 
124     for (Use &OI : Curr->operands()) {
125       if (Instruction *Inst = dyn_cast<Instruction>(OI))
126         markLive(*Inst);
127     }
128   }
129 }
130 
131 void AggressiveDeadCodeElimination::collectLiveScopes(const DILocalScope &LS) {
132   if (!AliveScopes.insert(&LS).second)
133     return;
134 
135   if (isa<DISubprogram>(LS))
136     return;
137 
138   // Tail-recurse through the scope chain.
139   collectLiveScopes(cast<DILocalScope>(*LS.getScope()));
140 }
141 
142 void AggressiveDeadCodeElimination::collectLiveScopes(const DILocation &DL) {
143   // Even though DILocations are not scopes, shove them into AliveScopes so we
144   // don't revisit them.
145   if (!AliveScopes.insert(&DL).second)
146     return;
147 
148   // Collect live scopes from the scope chain.
149   collectLiveScopes(*DL.getScope());
150 
151   // Tail-recurse through the inlined-at chain.
152   if (const DILocation *IA = DL.getInlinedAt())
153     collectLiveScopes(*IA);
154 }
155 
156 void AggressiveDeadCodeElimination::markLive(Instruction &I) {
157   if (!Alive.insert(&I).second)
158     return;
159   Worklist.push_back(&I);
160 }
161 
162 bool AggressiveDeadCodeElimination::removeDeadInstructions() {
163 
164   // The inverse of the live set is the dead set.  These are those instructions
165   // which have no side effects and do not influence the control flow or return
166   // value of the function, and may therefore be deleted safely.
167   // NOTE: We reuse the Worklist vector here for memory efficiency.
168   for (Instruction &I : instructions(F)) {
169     // Check if the instruction is alive.
170     if (Alive.count(&I))
171       continue;
172 
173     if (auto *DII = dyn_cast<DbgInfoIntrinsic>(&I)) {
174       // Check if the scope of this variable location is alive.
175       if (AliveScopes.count(DII->getDebugLoc()->getScope()))
176         continue;
177 
178       // Fallthrough and drop the intrinsic.
179       DEBUG({
180         // If intrinsic is pointing at a live SSA value, there may be an
181         // earlier optimization bug: if we know the location of the variable,
182         // why isn't the scope of the location alive?
183         if (Value *V = DII->getVariableLocation())
184           if (Instruction *II = dyn_cast<Instruction>(V))
185             if (Alive.count(II))
186               dbgs() << "Dropping debug info for " << *DII << "\n";
187       });
188     }
189 
190     // Prepare to delete.
191     Worklist.push_back(&I);
192     I.dropAllReferences();
193   }
194 
195   for (Instruction *&I : Worklist) {
196     ++NumRemoved;
197     I->eraseFromParent();
198   }
199 
200   return !Worklist.empty();
201 }
202 
203 PreservedAnalyses ADCEPass::run(Function &F, FunctionAnalysisManager &) {
204   if (!AggressiveDeadCodeElimination(F).performDeadCodeElimination())
205     return PreservedAnalyses::all();
206 
207   // FIXME: This should also 'preserve the CFG'.
208   auto PA = PreservedAnalyses();
209   PA.preserve<GlobalsAA>();
210   return PA;
211 }
212 
213 namespace {
214 struct ADCELegacyPass : public FunctionPass {
215   static char ID; // Pass identification, replacement for typeid
216   ADCELegacyPass() : FunctionPass(ID) {
217     initializeADCELegacyPassPass(*PassRegistry::getPassRegistry());
218   }
219 
220   bool runOnFunction(Function &F) override {
221     if (skipFunction(F))
222       return false;
223     return AggressiveDeadCodeElimination(F).performDeadCodeElimination();
224   }
225 
226   void getAnalysisUsage(AnalysisUsage &AU) const override {
227     AU.setPreservesCFG();
228     AU.addPreserved<GlobalsAAWrapperPass>();
229   }
230 };
231 }
232 
233 char ADCELegacyPass::ID = 0;
234 INITIALIZE_PASS(ADCELegacyPass, "adce", "Aggressive Dead Code Elimination",
235                 false, false)
236 
237 FunctionPass *llvm::createAggressiveDCEPass() { return new ADCELegacyPass(); }
238