LLVM 22.0.0git
RemoveRedundantDebugValues.cpp
Go to the documentation of this file.
1//===- RemoveRedundantDebugValues.cpp - Remove Redundant Debug Value MIs --===//
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
10#include "llvm/ADT/DenseMap.h"
11#include "llvm/ADT/DenseSet.h"
13#include "llvm/ADT/Statistic.h"
18#include "llvm/IR/Function.h"
20#include "llvm/Pass.h"
21#include "llvm/PassRegistry.h"
22
23/// \file RemoveRedundantDebugValues.cpp
24///
25/// The RemoveRedundantDebugValues pass removes redundant DBG_VALUEs that
26/// appear in MIR after the register allocator.
27
28#define DEBUG_TYPE "removeredundantdebugvalues"
29
30using namespace llvm;
31
32STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
33STATISTIC(NumRemovedForward, "Number of DBG_VALUEs removed (forward scan)");
34
35namespace {
36
37struct RemoveRedundantDebugValuesImpl {
38 bool reduceDbgValues(MachineFunction &MF);
39};
40
41class RemoveRedundantDebugValuesLegacy : public MachineFunctionPass {
42public:
43 static char ID;
44
45 RemoveRedundantDebugValuesLegacy();
46 /// Remove redundant debug value MIs for the given machine function.
47 bool runOnMachineFunction(MachineFunction &MF) override;
48
49 void getAnalysisUsage(AnalysisUsage &AU) const override {
50 AU.setPreservesCFG();
52 }
53};
54
55} // namespace
56
57//===----------------------------------------------------------------------===//
58// Implementation
59//===----------------------------------------------------------------------===//
60
61char RemoveRedundantDebugValuesLegacy::ID = 0;
62
63char &llvm::RemoveRedundantDebugValuesID = RemoveRedundantDebugValuesLegacy::ID;
64
65INITIALIZE_PASS(RemoveRedundantDebugValuesLegacy, DEBUG_TYPE,
66 "Remove Redundant DEBUG_VALUE analysis", false, false)
67
68/// Default construct and initialize the pass.
69RemoveRedundantDebugValuesLegacy::RemoveRedundantDebugValuesLegacy()
73}
74
75// This analysis aims to remove redundant DBG_VALUEs by going forward
76// in the basic block by considering the first DBG_VALUE as a valid
77// until its first (location) operand is not clobbered/modified.
78// For example:
79// (1) DBG_VALUE $edi, !"var1", ...
80// (2) <block of code that does affect $edi>
81// (3) DBG_VALUE $edi, !"var1", ...
82// ...
83// in this case, we can remove (3).
84// TODO: Support DBG_VALUE_LIST and other debug instructions.
86 LLVM_DEBUG(dbgs() << "\n == Forward Scan == \n");
87
88 SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
90 VariableMap;
91 const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
92
93 for (auto &MI : MBB) {
94 if (MI.isDebugValue()) {
95 DebugVariable Var(MI.getDebugVariable(), std::nullopt,
96 MI.getDebugLoc()->getInlinedAt());
97 auto VMI = VariableMap.find(Var);
98 // Just stop tracking this variable, until we cover DBG_VALUE_LIST.
99 // 1 DBG_VALUE $rax, "x", DIExpression()
100 // ...
101 // 2 DBG_VALUE_LIST "x", DIExpression(...), $rax, $rbx
102 // ...
103 // 3 DBG_VALUE $rax, "x", DIExpression()
104 if (MI.isDebugValueList() && VMI != VariableMap.end()) {
105 VariableMap.erase(VMI);
106 continue;
107 }
108
109 MachineOperand &Loc = MI.getDebugOperand(0);
110 if (!Loc.isReg()) {
111 // If it's not a register, just stop tracking such variable.
112 if (VMI != VariableMap.end())
113 VariableMap.erase(VMI);
114 continue;
115 }
116
117 // We have found a new value for a variable.
118 if (VMI == VariableMap.end() ||
119 VMI->second.first->getReg() != Loc.getReg() ||
120 VMI->second.second != MI.getDebugExpression()) {
121 VariableMap[Var] = {&Loc, MI.getDebugExpression()};
122 continue;
123 }
124
125 // Found an identical DBG_VALUE, so it can be considered
126 // for later removal.
127 DbgValsToBeRemoved.push_back(&MI);
128 }
129
130 if (MI.isMetaInstruction())
131 continue;
132
133 // Stop tracking any location that is clobbered by this instruction.
134 for (auto &Var : VariableMap) {
135 auto &LocOp = Var.second.first;
136 if (MI.modifiesRegister(LocOp->getReg(), TRI))
137 VariableMap.erase(Var.first);
138 }
139 }
140
141 for (auto &Instr : DbgValsToBeRemoved) {
142 LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
143 Instr->eraseFromParent();
144 ++NumRemovedForward;
145 }
146
147 return !DbgValsToBeRemoved.empty();
148}
149
150// This analysis aims to remove redundant DBG_VALUEs by going backward
151// in the basic block and removing all but the last DBG_VALUE for any
152// given variable in a set of consecutive DBG_VALUE instructions.
153// For example:
154// (1) DBG_VALUE $edi, !"var1", ...
155// (2) DBG_VALUE $esi, !"var2", ...
156// (3) DBG_VALUE $edi, !"var1", ...
157// ...
158// in this case, we can remove (1).
160 LLVM_DEBUG(dbgs() << "\n == Backward Scan == \n");
161 SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
163
164 for (MachineInstr &MI : llvm::reverse(MBB)) {
165 if (MI.isDebugValue()) {
166 DebugVariable Var(MI.getDebugVariable(), MI.getDebugExpression(),
167 MI.getDebugLoc()->getInlinedAt());
168 auto R = VariableSet.insert(Var);
169 // If it is a DBG_VALUE describing a constant as:
170 // DBG_VALUE 0, ...
171 // we just don't consider such instructions as candidates
172 // for redundant removal.
173 if (MI.isNonListDebugValue()) {
174 MachineOperand &Loc = MI.getDebugOperand(0);
175 if (!Loc.isReg()) {
176 // If we have already encountered this variable, just stop
177 // tracking it.
178 if (!R.second)
179 VariableSet.erase(Var);
180 continue;
181 }
182 }
183
184 // We have already encountered the value for this variable,
185 // so this one can be deleted.
186 if (!R.second)
187 DbgValsToBeRemoved.push_back(&MI);
188 continue;
189 }
190
191 // If we encountered a non-DBG_VALUE, try to find the next
192 // sequence with consecutive DBG_VALUE instructions.
193 VariableSet.clear();
194 }
195
196 for (auto &Instr : DbgValsToBeRemoved) {
197 LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
198 Instr->eraseFromParent();
199 ++NumRemovedBackward;
200 }
201
202 return !DbgValsToBeRemoved.empty();
203}
204
205bool RemoveRedundantDebugValuesImpl::reduceDbgValues(MachineFunction &MF) {
206 LLVM_DEBUG(dbgs() << "\nDebug Value Reduction\n");
207
208 bool Changed = false;
209
210 for (auto &MBB : MF) {
211 Changed |= reduceDbgValsBackwardScan(MBB);
212 Changed |= reduceDbgValsForwardScan(MBB);
213 }
214
215 return Changed;
216}
217
218bool RemoveRedundantDebugValuesLegacy::runOnMachineFunction(
219 MachineFunction &MF) {
220 // Skip functions without debugging information or functions from NoDebug
221 // compilation units.
222 if (!MF.getFunction().getSubprogram() ||
223 (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
225 return false;
226
227 return RemoveRedundantDebugValuesImpl().reduceDbgValues(MF);
228}
229
233 // Skip functions without debugging information or functions from NoDebug
234 // compilation units.
235 if (!MF.getFunction().getSubprogram() ||
236 (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
238 return PreservedAnalyses::all();
239
240 if (!RemoveRedundantDebugValuesImpl().reduceDbgValues(MF))
241 return PreservedAnalyses::all();
242
244 PA.preserveSet<CFGAnalyses>();
245 return PA;
246}
MachineBasicBlock & MBB
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
IRTranslator LLVM IR MI
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:56
static bool reduceDbgValsForwardScan(MachineBasicBlock &MBB)
static bool reduceDbgValsBackwardScan(MachineBasicBlock &MBB)
#define DEBUG_TYPE
This file defines the SmallVector class.
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
#define LLVM_DEBUG(...)
Definition: Debug.h:119
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:270
Represents analyses that only rely on functions' control flow.
Definition: Analysis.h:73
Identifies a unique instance of a variable.
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:165
bool erase(const KeyT &Val)
Definition: DenseMap.h:303
iterator end()
Definition: DenseMap.h:81
DISubprogram * getSubprogram() const
Get the attached subprogram.
Definition: Metadata.cpp:1915
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
Definition: MachineInstr.h:72
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:118
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition: DenseSet.h:283
bool empty() const
Definition: SmallVector.h:82
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
bool erase(const ValueT &V)
Definition: DenseSet.h:100
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
LLVM_ABI void initializeRemoveRedundantDebugValuesLegacyPass(PassRegistry &)
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:428
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI char & RemoveRedundantDebugValuesID
RemoveRedundantDebugValues pass.