1 //===- DCE.cpp - Code to perform dead code elimination --------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements dead inst elimination and dead code elimination. 10 // 11 // Dead Inst Elimination performs a single pass over the function removing 12 // instructions that are obviously dead. Dead Code Elimination is similar, but 13 // it rechecks instructions that were used by removed instructions to see if 14 // they are newly dead. 15 // 16 //===----------------------------------------------------------------------===// 17 18 #include "llvm/Transforms/Scalar/DCE.h" 19 #include "llvm/ADT/SetVector.h" 20 #include "llvm/ADT/Statistic.h" 21 #include "llvm/Analysis/TargetLibraryInfo.h" 22 #include "llvm/IR/InstIterator.h" 23 #include "llvm/IR/Instruction.h" 24 #include "llvm/InitializePasses.h" 25 #include "llvm/Pass.h" 26 #include "llvm/Support/DebugCounter.h" 27 #include "llvm/Transforms/Scalar.h" 28 #include "llvm/Transforms/Utils/Local.h" 29 using namespace llvm; 30 31 #define DEBUG_TYPE "dce" 32 33 STATISTIC(DIEEliminated, "Number of insts removed by DIE pass"); 34 STATISTIC(DCEEliminated, "Number of insts removed"); 35 DEBUG_COUNTER(DCECounter, "dce-transform", 36 "Controls which instructions are eliminated"); 37 38 namespace { 39 //===--------------------------------------------------------------------===// 40 // DeadInstElimination pass implementation 41 // 42 struct DeadInstElimination : public FunctionPass { 43 static char ID; // Pass identification, replacement for typeid 44 DeadInstElimination() : FunctionPass(ID) { 45 initializeDeadInstEliminationPass(*PassRegistry::getPassRegistry()); 46 } 47 bool runOnFunction(Function &F) override { 48 if (skipFunction(F)) 49 return false; 50 auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>(); 51 TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI(F) : nullptr; 52 53 bool Changed = false; 54 for (auto &BB : F) { 55 for (BasicBlock::iterator DI = BB.begin(); DI != BB.end(); ) { 56 Instruction *Inst = &*DI++; 57 if (isInstructionTriviallyDead(Inst, TLI)) { 58 if (!DebugCounter::shouldExecute(DCECounter)) 59 continue; 60 salvageDebugInfo(*Inst); 61 Inst->eraseFromParent(); 62 Changed = true; 63 ++DIEEliminated; 64 } 65 } 66 } 67 return Changed; 68 } 69 70 void getAnalysisUsage(AnalysisUsage &AU) const override { 71 AU.setPreservesCFG(); 72 } 73 }; 74 } 75 76 char DeadInstElimination::ID = 0; 77 INITIALIZE_PASS(DeadInstElimination, "die", 78 "Dead Instruction Elimination", false, false) 79 80 Pass *llvm::createDeadInstEliminationPass() { 81 return new DeadInstElimination(); 82 } 83 84 static bool DCEInstruction(Instruction *I, 85 SmallSetVector<Instruction *, 16> &WorkList, 86 const TargetLibraryInfo *TLI) { 87 if (isInstructionTriviallyDead(I, TLI)) { 88 if (!DebugCounter::shouldExecute(DCECounter)) 89 return false; 90 91 salvageDebugInfo(*I); 92 93 // Null out all of the instruction's operands to see if any operand becomes 94 // dead as we go. 95 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { 96 Value *OpV = I->getOperand(i); 97 I->setOperand(i, nullptr); 98 99 if (!OpV->use_empty() || I == OpV) 100 continue; 101 102 // If the operand is an instruction that became dead as we nulled out the 103 // operand, and if it is 'trivially' dead, delete it in a future loop 104 // iteration. 105 if (Instruction *OpI = dyn_cast<Instruction>(OpV)) 106 if (isInstructionTriviallyDead(OpI, TLI)) 107 WorkList.insert(OpI); 108 } 109 110 I->eraseFromParent(); 111 ++DCEEliminated; 112 return true; 113 } 114 return false; 115 } 116 117 static bool eliminateDeadCode(Function &F, TargetLibraryInfo *TLI) { 118 bool MadeChange = false; 119 SmallSetVector<Instruction *, 16> WorkList; 120 // Iterate over the original function, only adding insts to the worklist 121 // if they actually need to be revisited. This avoids having to pre-init 122 // the worklist with the entire function's worth of instructions. 123 for (inst_iterator FI = inst_begin(F), FE = inst_end(F); FI != FE;) { 124 Instruction *I = &*FI; 125 ++FI; 126 127 // We're visiting this instruction now, so make sure it's not in the 128 // worklist from an earlier visit. 129 if (!WorkList.count(I)) 130 MadeChange |= DCEInstruction(I, WorkList, TLI); 131 } 132 133 while (!WorkList.empty()) { 134 Instruction *I = WorkList.pop_back_val(); 135 MadeChange |= DCEInstruction(I, WorkList, TLI); 136 } 137 return MadeChange; 138 } 139 140 PreservedAnalyses DCEPass::run(Function &F, FunctionAnalysisManager &AM) { 141 if (!eliminateDeadCode(F, AM.getCachedResult<TargetLibraryAnalysis>(F))) 142 return PreservedAnalyses::all(); 143 144 PreservedAnalyses PA; 145 PA.preserveSet<CFGAnalyses>(); 146 return PA; 147 } 148 149 namespace { 150 struct DCELegacyPass : public FunctionPass { 151 static char ID; // Pass identification, replacement for typeid 152 DCELegacyPass() : FunctionPass(ID) { 153 initializeDCELegacyPassPass(*PassRegistry::getPassRegistry()); 154 } 155 156 bool runOnFunction(Function &F) override { 157 if (skipFunction(F)) 158 return false; 159 160 auto *TLIP = getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>(); 161 TargetLibraryInfo *TLI = TLIP ? &TLIP->getTLI(F) : nullptr; 162 163 return eliminateDeadCode(F, TLI); 164 } 165 166 void getAnalysisUsage(AnalysisUsage &AU) const override { 167 AU.setPreservesCFG(); 168 } 169 }; 170 } 171 172 char DCELegacyPass::ID = 0; 173 INITIALIZE_PASS(DCELegacyPass, "dce", "Dead Code Elimination", false, false) 174 175 FunctionPass *llvm::createDeadCodeEliminationPass() { 176 return new DCELegacyPass(); 177 } 178