LLVM 17.0.0git
DCE.cpp
Go to the documentation of this file.
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
19#include "llvm/ADT/SetVector.h"
20#include "llvm/ADT/Statistic.h"
23#include "llvm/IR/Instruction.h"
25#include "llvm/Pass.h"
31using namespace llvm;
32
33#define DEBUG_TYPE "dce"
34
35STATISTIC(DCEEliminated, "Number of insts removed");
36DEBUG_COUNTER(DCECounter, "dce-transform",
37 "Controls which instructions are eliminated");
38
39//===--------------------------------------------------------------------===//
40// RedundantDbgInstElimination pass implementation
41//
42
43namespace {
44struct RedundantDbgInstElimination : public FunctionPass {
45 static char ID; // Pass identification, replacement for typeid
46 RedundantDbgInstElimination() : FunctionPass(ID) {
48 }
49 bool runOnFunction(Function &F) override {
50 if (skipFunction(F))
51 return false;
52 bool Changed = false;
53 for (auto &BB : F)
54 Changed |= RemoveRedundantDbgInstrs(&BB);
55 return Changed;
56 }
57
58 void getAnalysisUsage(AnalysisUsage &AU) const override {
59 AU.setPreservesCFG();
60 }
61};
62}
63
64char RedundantDbgInstElimination::ID = 0;
65INITIALIZE_PASS(RedundantDbgInstElimination, "redundant-dbg-inst-elim",
66 "Redundant Dbg Instruction Elimination", false, false)
67
69 return new RedundantDbgInstElimination();
70}
71
74 bool Changed = false;
75 for (auto &BB : F)
76 Changed |= RemoveRedundantDbgInstrs(&BB);
77 if (!Changed)
81 return PA;
82}
83
84//===--------------------------------------------------------------------===//
85// DeadCodeElimination pass implementation
86//
87
90 const TargetLibraryInfo *TLI) {
91 if (isInstructionTriviallyDead(I, TLI)) {
92 if (!DebugCounter::shouldExecute(DCECounter))
93 return false;
94
97
98 // Null out all of the instruction's operands to see if any operand becomes
99 // dead as we go.
100 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
101 Value *OpV = I->getOperand(i);
102 I->setOperand(i, nullptr);
103
104 if (!OpV->use_empty() || I == OpV)
105 continue;
106
107 // If the operand is an instruction that became dead as we nulled out the
108 // operand, and if it is 'trivially' dead, delete it in a future loop
109 // iteration.
110 if (Instruction *OpI = dyn_cast<Instruction>(OpV))
111 if (isInstructionTriviallyDead(OpI, TLI))
112 WorkList.insert(OpI);
113 }
114
115 I->eraseFromParent();
116 ++DCEEliminated;
117 return true;
118 }
119 return false;
120}
121
123 bool MadeChange = false;
125 // Iterate over the original function, only adding insts to the worklist
126 // if they actually need to be revisited. This avoids having to pre-init
127 // the worklist with the entire function's worth of instructions.
129 // We're visiting this instruction now, so make sure it's not in the
130 // worklist from an earlier visit.
131 if (!WorkList.count(&I))
132 MadeChange |= DCEInstruction(&I, WorkList, TLI);
133 }
134
135 while (!WorkList.empty()) {
136 Instruction *I = WorkList.pop_back_val();
137 MadeChange |= DCEInstruction(I, WorkList, TLI);
138 }
139 return MadeChange;
140}
141
144 return PreservedAnalyses::all();
145
148 return PA;
149}
150
151namespace {
152struct DCELegacyPass : public FunctionPass {
153 static char ID; // Pass identification, replacement for typeid
154 DCELegacyPass() : FunctionPass(ID) {
156 }
157
158 bool runOnFunction(Function &F) override {
159 if (skipFunction(F))
160 return false;
161
162 TargetLibraryInfo *TLI =
163 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
164
165 return eliminateDeadCode(F, TLI);
166 }
167
168 void getAnalysisUsage(AnalysisUsage &AU) const override {
170 AU.setPreservesCFG();
171 }
172};
173}
174
175char DCELegacyPass::ID = 0;
176INITIALIZE_PASS(DCELegacyPass, "dce", "Dead Code Elimination", false, false)
177
179 return new DCELegacyPass();
180}
static bool DCEInstruction(Instruction *I, SmallSetVector< Instruction *, 16 > &WorkList, const TargetLibraryInfo *TLI)
Definition: DCE.cpp:88
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
Definition: DebugCounter.h:182
static bool runOnFunction(Function &F, bool PostInlining)
static void eliminateDeadCode(Function &F)
Definition: IRMutator.cpp:80
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
print must be executed print the must be executed context for all instructions
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:774
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:265
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:113
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: DCE.cpp:142
static bool shouldExecute(unsigned CounterName)
Definition: DebugCounter.h:72
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
Definition: Pass.cpp:174
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:98
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
void preserveSet()
Mark an analysis set as preserved.
Definition: PassManager.h:188
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: DCE.cpp:73
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:208
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:141
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:72
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:301
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
LLVM Value Representation.
Definition: Value.h:74
bool use_empty() const
Definition: Value.h:344
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool RemoveRedundantDbgInstrs(BasicBlock *BB)
Try to remove redundant dbg.value instructions from given basic block.
Pass * createRedundantDbgInstEliminationPass()
void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
Definition: Utils.cpp:1367
FunctionPass * createDeadCodeEliminationPass()
Definition: DCE.cpp:178
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:748
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
Definition: Local.cpp:398
void initializeDCELegacyPassPass(PassRegistry &)
bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
void initializeRedundantDbgInstEliminationPass(PassRegistry &)