1 //===- RemoveRedundantDebugValues.cpp - Remove Redundant Debug Value MIs --===//
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 #include "llvm/ADT/DenseMap.h"
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/Statistic.h"
13 #include "llvm/CodeGen/MachineBasicBlock.h"
14 #include "llvm/CodeGen/MachineFunctionPass.h"
15 #include "llvm/CodeGen/TargetSubtargetInfo.h"
16 #include "llvm/IR/DebugInfoMetadata.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/InitializePasses.h"
19 #include "llvm/Pass.h"
20 #include "llvm/PassRegistry.h"
22 /// \file RemoveRedundantDebugValues.cpp
24 /// The RemoveRedundantDebugValues pass removes redundant DBG_VALUEs that
25 /// appear in MIR after the register allocator.
27 #define DEBUG_TYPE "removeredundantdebugvalues"
31 STATISTIC(NumRemovedBackward
, "Number of DBG_VALUEs removed (backward scan)");
32 STATISTIC(NumRemovedForward
, "Number of DBG_VALUEs removed (forward scan)");
36 class RemoveRedundantDebugValues
: public MachineFunctionPass
{
40 RemoveRedundantDebugValues();
42 bool reduceDbgValues(MachineFunction
&MF
);
44 /// Remove redundant debug value MIs for the given machine function.
45 bool runOnMachineFunction(MachineFunction
&MF
) override
;
47 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
49 MachineFunctionPass::getAnalysisUsage(AU
);
55 //===----------------------------------------------------------------------===//
57 //===----------------------------------------------------------------------===//
59 char RemoveRedundantDebugValues::ID
= 0;
61 char &llvm::RemoveRedundantDebugValuesID
= RemoveRedundantDebugValues::ID
;
63 INITIALIZE_PASS(RemoveRedundantDebugValues
, DEBUG_TYPE
,
64 "Remove Redundant DEBUG_VALUE analysis", false, false)
66 /// Default construct and initialize the pass.
67 RemoveRedundantDebugValues::RemoveRedundantDebugValues()
68 : MachineFunctionPass(ID
) {
69 initializeRemoveRedundantDebugValuesPass(*PassRegistry::getPassRegistry());
72 // This analysis aims to remove redundant DBG_VALUEs by going forward
73 // in the basic block by considering the first DBG_VALUE as a valid
74 // until its first (location) operand is not clobbered/modified.
76 // (1) DBG_VALUE $edi, !"var1", ...
77 // (2) <block of code that does affect $edi>
78 // (3) DBG_VALUE $edi, !"var1", ...
80 // in this case, we can remove (3).
81 // TODO: Support DBG_VALUE_LIST and other debug instructions.
82 static bool reduceDbgValsForwardScan(MachineBasicBlock
&MBB
) {
83 LLVM_DEBUG(dbgs() << "\n == Forward Scan == \n");
85 SmallVector
<MachineInstr
*, 8> DbgValsToBeRemoved
;
86 DenseMap
<DebugVariable
, std::pair
<MachineOperand
*, const DIExpression
*>>
88 const auto *TRI
= MBB
.getParent()->getSubtarget().getRegisterInfo();
90 for (auto &MI
: MBB
) {
91 if (MI
.isDebugValue()) {
92 DebugVariable
Var(MI
.getDebugVariable(), std::nullopt
,
93 MI
.getDebugLoc()->getInlinedAt());
94 auto VMI
= VariableMap
.find(Var
);
95 // Just stop tracking this variable, until we cover DBG_VALUE_LIST.
96 // 1 DBG_VALUE $rax, "x", DIExpression()
98 // 2 DBG_VALUE_LIST "x", DIExpression(...), $rax, $rbx
100 // 3 DBG_VALUE $rax, "x", DIExpression()
101 if (MI
.isDebugValueList() && VMI
!= VariableMap
.end()) {
102 VariableMap
.erase(VMI
);
106 MachineOperand
&Loc
= MI
.getDebugOperand(0);
108 // If it's not a register, just stop tracking such variable.
109 if (VMI
!= VariableMap
.end())
110 VariableMap
.erase(VMI
);
114 // We have found a new value for a variable.
115 if (VMI
== VariableMap
.end() ||
116 VMI
->second
.first
->getReg() != Loc
.getReg() ||
117 VMI
->second
.second
!= MI
.getDebugExpression()) {
118 VariableMap
[Var
] = {&Loc
, MI
.getDebugExpression()};
122 // Found an identical DBG_VALUE, so it can be considered
123 // for later removal.
124 DbgValsToBeRemoved
.push_back(&MI
);
127 if (MI
.isMetaInstruction())
130 // Stop tracking any location that is clobbered by this instruction.
131 for (auto &Var
: VariableMap
) {
132 auto &LocOp
= Var
.second
.first
;
133 if (MI
.modifiesRegister(LocOp
->getReg(), TRI
))
134 VariableMap
.erase(Var
.first
);
138 for (auto &Instr
: DbgValsToBeRemoved
) {
139 LLVM_DEBUG(dbgs() << "removing "; Instr
->dump());
140 Instr
->eraseFromParent();
144 return !DbgValsToBeRemoved
.empty();
147 // This analysis aims to remove redundant DBG_VALUEs by going backward
148 // in the basic block and removing all but the last DBG_VALUE for any
149 // given variable in a set of consecutive DBG_VALUE instructions.
151 // (1) DBG_VALUE $edi, !"var1", ...
152 // (2) DBG_VALUE $esi, !"var2", ...
153 // (3) DBG_VALUE $edi, !"var1", ...
155 // in this case, we can remove (1).
156 static bool reduceDbgValsBackwardScan(MachineBasicBlock
&MBB
) {
157 LLVM_DEBUG(dbgs() << "\n == Backward Scan == \n");
158 SmallVector
<MachineInstr
*, 8> DbgValsToBeRemoved
;
159 SmallDenseSet
<DebugVariable
> VariableSet
;
161 for (MachineInstr
&MI
: llvm::reverse(MBB
)) {
162 if (MI
.isDebugValue()) {
163 DebugVariable
Var(MI
.getDebugVariable(), MI
.getDebugExpression(),
164 MI
.getDebugLoc()->getInlinedAt());
165 auto R
= VariableSet
.insert(Var
);
166 // If it is a DBG_VALUE describing a constant as:
168 // we just don't consider such instructions as candidates
169 // for redundant removal.
170 if (MI
.isNonListDebugValue()) {
171 MachineOperand
&Loc
= MI
.getDebugOperand(0);
173 // If we have already encountered this variable, just stop
176 VariableSet
.erase(Var
);
181 // We have already encountered the value for this variable,
182 // so this one can be deleted.
184 DbgValsToBeRemoved
.push_back(&MI
);
188 // If we encountered a non-DBG_VALUE, try to find the next
189 // sequence with consecutive DBG_VALUE instructions.
193 for (auto &Instr
: DbgValsToBeRemoved
) {
194 LLVM_DEBUG(dbgs() << "removing "; Instr
->dump());
195 Instr
->eraseFromParent();
196 ++NumRemovedBackward
;
199 return !DbgValsToBeRemoved
.empty();
202 bool RemoveRedundantDebugValues::reduceDbgValues(MachineFunction
&MF
) {
203 LLVM_DEBUG(dbgs() << "\nDebug Value Reduction\n");
205 bool Changed
= false;
207 for (auto &MBB
: MF
) {
208 Changed
|= reduceDbgValsBackwardScan(MBB
);
209 Changed
|= reduceDbgValsForwardScan(MBB
);
215 bool RemoveRedundantDebugValues::runOnMachineFunction(MachineFunction
&MF
) {
216 // Skip functions without debugging information.
217 if (!MF
.getFunction().getSubprogram())
220 // Skip functions from NoDebug compilation units.
221 if (MF
.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
222 DICompileUnit::NoDebug
)
225 bool Changed
= reduceDbgValues(MF
);