1 //===- DCE.cpp - Code to perform dead code elimination --------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements dead inst elimination and dead code elimination.
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.
16 //===----------------------------------------------------------------------===//
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/Transforms/Utils/Local.h"
23 #include "llvm/IR/InstIterator.h"
24 #include "llvm/IR/Instruction.h"
25 #include "llvm/Pass.h"
26 #include "llvm/Support/DebugCounter.h"
27 #include "llvm/Transforms/Scalar.h"
30 #define DEBUG_TYPE "dce"
32 STATISTIC(DIEEliminated
, "Number of insts removed by DIE pass");
33 STATISTIC(DCEEliminated
, "Number of insts removed");
34 DEBUG_COUNTER(DCECounter
, "dce-transform",
35 "Controls which instructions are eliminated");
38 //===--------------------------------------------------------------------===//
39 // DeadInstElimination pass implementation
41 struct DeadInstElimination
: public BasicBlockPass
{
42 static char ID
; // Pass identification, replacement for typeid
43 DeadInstElimination() : BasicBlockPass(ID
) {
44 initializeDeadInstEliminationPass(*PassRegistry::getPassRegistry());
46 bool runOnBasicBlock(BasicBlock
&BB
) override
{
47 if (skipBasicBlock(BB
))
49 auto *TLIP
= getAnalysisIfAvailable
<TargetLibraryInfoWrapperPass
>();
50 TargetLibraryInfo
*TLI
= TLIP
? &TLIP
->getTLI() : nullptr;
52 for (BasicBlock::iterator DI
= BB
.begin(); DI
!= BB
.end(); ) {
53 Instruction
*Inst
= &*DI
++;
54 if (isInstructionTriviallyDead(Inst
, TLI
)) {
55 if (!DebugCounter::shouldExecute(DCECounter
))
57 salvageDebugInfo(*Inst
);
58 Inst
->eraseFromParent();
66 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
72 char DeadInstElimination::ID
= 0;
73 INITIALIZE_PASS(DeadInstElimination
, "die",
74 "Dead Instruction Elimination", false, false)
76 Pass
*llvm::createDeadInstEliminationPass() {
77 return new DeadInstElimination();
80 static bool DCEInstruction(Instruction
*I
,
81 SmallSetVector
<Instruction
*, 16> &WorkList
,
82 const TargetLibraryInfo
*TLI
) {
83 if (isInstructionTriviallyDead(I
, TLI
)) {
84 if (!DebugCounter::shouldExecute(DCECounter
))
89 // Null out all of the instruction's operands to see if any operand becomes
91 for (unsigned i
= 0, e
= I
->getNumOperands(); i
!= e
; ++i
) {
92 Value
*OpV
= I
->getOperand(i
);
93 I
->setOperand(i
, nullptr);
95 if (!OpV
->use_empty() || I
== OpV
)
98 // If the operand is an instruction that became dead as we nulled out the
99 // operand, and if it is 'trivially' dead, delete it in a future loop
101 if (Instruction
*OpI
= dyn_cast
<Instruction
>(OpV
))
102 if (isInstructionTriviallyDead(OpI
, TLI
))
103 WorkList
.insert(OpI
);
106 I
->eraseFromParent();
113 static bool eliminateDeadCode(Function
&F
, TargetLibraryInfo
*TLI
) {
114 bool MadeChange
= false;
115 SmallSetVector
<Instruction
*, 16> WorkList
;
116 // Iterate over the original function, only adding insts to the worklist
117 // if they actually need to be revisited. This avoids having to pre-init
118 // the worklist with the entire function's worth of instructions.
119 for (inst_iterator FI
= inst_begin(F
), FE
= inst_end(F
); FI
!= FE
;) {
120 Instruction
*I
= &*FI
;
123 // We're visiting this instruction now, so make sure it's not in the
124 // worklist from an earlier visit.
125 if (!WorkList
.count(I
))
126 MadeChange
|= DCEInstruction(I
, WorkList
, TLI
);
129 while (!WorkList
.empty()) {
130 Instruction
*I
= WorkList
.pop_back_val();
131 MadeChange
|= DCEInstruction(I
, WorkList
, TLI
);
136 PreservedAnalyses
DCEPass::run(Function
&F
, FunctionAnalysisManager
&AM
) {
137 if (!eliminateDeadCode(F
, AM
.getCachedResult
<TargetLibraryAnalysis
>(F
)))
138 return PreservedAnalyses::all();
140 PreservedAnalyses PA
;
141 PA
.preserveSet
<CFGAnalyses
>();
146 struct DCELegacyPass
: public FunctionPass
{
147 static char ID
; // Pass identification, replacement for typeid
148 DCELegacyPass() : FunctionPass(ID
) {
149 initializeDCELegacyPassPass(*PassRegistry::getPassRegistry());
152 bool runOnFunction(Function
&F
) override
{
156 auto *TLIP
= getAnalysisIfAvailable
<TargetLibraryInfoWrapperPass
>();
157 TargetLibraryInfo
*TLI
= TLIP
? &TLIP
->getTLI() : nullptr;
159 return eliminateDeadCode(F
, TLI
);
162 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
163 AU
.setPreservesCFG();
168 char DCELegacyPass::ID
= 0;
169 INITIALIZE_PASS(DCELegacyPass
, "dce", "Dead Code Elimination", false, false)
171 FunctionPass
*llvm::createDeadCodeEliminationPass() {
172 return new DCELegacyPass();