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/Passes.h"
16 #include "llvm/CodeGen/TargetRegisterInfo.h"
17 #include "llvm/CodeGen/TargetSubtargetInfo.h"
18 #include "llvm/IR/DebugInfoMetadata.h"
19 #include "llvm/IR/Function.h"
20 #include "llvm/InitializePasses.h"
21 #include "llvm/Pass.h"
23 /// \file RemoveRedundantDebugValues.cpp
25 /// The RemoveRedundantDebugValues pass removes redundant DBG_VALUEs that
26 /// appear in MIR after the register allocator.
28 #define DEBUG_TYPE "removeredundantdebugvalues"
32 STATISTIC(NumRemovedBackward
, "Number of DBG_VALUEs removed (backward scan)");
33 STATISTIC(NumRemovedForward
, "Number of DBG_VALUEs removed (forward scan)");
37 class RemoveRedundantDebugValues
: public MachineFunctionPass
{
41 RemoveRedundantDebugValues();
43 bool reduceDbgValues(MachineFunction
&MF
);
45 /// Remove redundant debug value MIs for the given machine function.
46 bool runOnMachineFunction(MachineFunction
&MF
) override
;
48 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
50 MachineFunctionPass::getAnalysisUsage(AU
);
56 //===----------------------------------------------------------------------===//
58 //===----------------------------------------------------------------------===//
60 char RemoveRedundantDebugValues::ID
= 0;
62 char &llvm::RemoveRedundantDebugValuesID
= RemoveRedundantDebugValues::ID
;
64 INITIALIZE_PASS(RemoveRedundantDebugValues
, DEBUG_TYPE
,
65 "Remove Redundant DEBUG_VALUE analysis", false, false)
67 /// Default construct and initialize the pass.
68 RemoveRedundantDebugValues::RemoveRedundantDebugValues()
69 : MachineFunctionPass(ID
) {
70 initializeRemoveRedundantDebugValuesPass(*PassRegistry::getPassRegistry());
73 // This analysis aims to remove redundant DBG_VALUEs by going forward
74 // in the basic block by considering the first DBG_VALUE as a valid
75 // until its first (location) operand is not clobbered/modified.
77 // (1) DBG_VALUE $edi, !"var1", ...
78 // (2) <block of code that does affect $edi>
79 // (3) DBG_VALUE $edi, !"var1", ...
81 // in this case, we can remove (3).
82 // TODO: Support DBG_VALUE_LIST and other debug instructions.
83 static bool reduceDbgValsForwardScan(MachineBasicBlock
&MBB
) {
84 LLVM_DEBUG(dbgs() << "\n == Forward Scan == \n");
86 SmallVector
<MachineInstr
*, 8> DbgValsToBeRemoved
;
87 DenseMap
<DebugVariable
, std::pair
<MachineOperand
*, const DIExpression
*>>
89 const auto *TRI
= MBB
.getParent()->getSubtarget().getRegisterInfo();
91 for (auto &MI
: MBB
) {
92 if (MI
.isDebugValue()) {
93 DebugVariable
Var(MI
.getDebugVariable(), NoneType(),
94 MI
.getDebugLoc()->getInlinedAt());
95 auto VMI
= VariableMap
.find(Var
);
96 // Just stop tracking this variable, until we cover DBG_VALUE_LIST.
97 // 1 DBG_VALUE $rax, "x", DIExpression()
99 // 2 DBG_VALUE_LIST "x", DIExpression(...), $rax, $rbx
101 // 3 DBG_VALUE $rax, "x", DIExpression()
102 if (MI
.isDebugValueList() && VMI
!= VariableMap
.end()) {
103 VariableMap
.erase(VMI
);
107 MachineOperand
&Loc
= MI
.getDebugOperand(0);
109 // If it it's not a register, just stop tracking such variable.
110 if (VMI
!= VariableMap
.end())
111 VariableMap
.erase(VMI
);
115 // We have found a new value for a variable.
116 if (VMI
== VariableMap
.end() ||
117 VMI
->second
.first
->getReg() != Loc
.getReg() ||
118 VMI
->second
.second
!= MI
.getDebugExpression()) {
119 VariableMap
[Var
] = {&Loc
, MI
.getDebugExpression()};
123 // Found an identical DBG_VALUE, so it can be considered
124 // for later removal.
125 DbgValsToBeRemoved
.push_back(&MI
);
128 if (MI
.isMetaInstruction())
131 // Stop tracking any location that is clobbered by this instruction.
132 for (auto &Var
: VariableMap
) {
133 auto &LocOp
= Var
.second
.first
;
134 if (MI
.modifiesRegister(LocOp
->getReg(), TRI
))
135 VariableMap
.erase(Var
.first
);
139 for (auto &Instr
: DbgValsToBeRemoved
) {
140 LLVM_DEBUG(dbgs() << "removing "; Instr
->dump());
141 Instr
->eraseFromParent();
145 return !DbgValsToBeRemoved
.empty();
148 // This analysis aims to remove redundant DBG_VALUEs by going backward
149 // in the basic block and removing all but the last DBG_VALUE for any
150 // given variable in a set of consecutive DBG_VALUE instructions.
152 // (1) DBG_VALUE $edi, !"var1", ...
153 // (2) DBG_VALUE $esi, !"var2", ...
154 // (3) DBG_VALUE $edi, !"var1", ...
156 // in this case, we can remove (1).
157 static bool reduceDbgValsBackwardScan(MachineBasicBlock
&MBB
) {
158 LLVM_DEBUG(dbgs() << "\n == Backward Scan == \n");
159 SmallVector
<MachineInstr
*, 8> DbgValsToBeRemoved
;
160 SmallDenseSet
<DebugVariable
> VariableSet
;
162 for (MachineBasicBlock::reverse_iterator I
= MBB
.rbegin(), E
= MBB
.rend();
164 MachineInstr
*MI
= &*I
;
166 if (MI
->isDebugValue()) {
167 DebugVariable
Var(MI
->getDebugVariable(), MI
->getDebugExpression(),
168 MI
->getDebugLoc()->getInlinedAt());
169 auto R
= VariableSet
.insert(Var
);
170 // If it is a DBG_VALUE describing a constant as:
172 // we just don't consider such instructions as candidates
173 // for redundant removal.
174 if (MI
->isNonListDebugValue()) {
175 MachineOperand
&Loc
= MI
->getDebugOperand(0);
177 // If we have already encountered this variable, just stop
180 VariableSet
.erase(Var
);
185 // We have already encountered the value for this variable,
186 // so this one can be deleted.
188 DbgValsToBeRemoved
.push_back(MI
);
192 // If we encountered a non-DBG_VALUE, try to find the next
193 // sequence with consecutive DBG_VALUE instructions.
197 for (auto &Instr
: DbgValsToBeRemoved
) {
198 LLVM_DEBUG(dbgs() << "removing "; Instr
->dump());
199 Instr
->eraseFromParent();
200 ++NumRemovedBackward
;
203 return !DbgValsToBeRemoved
.empty();
206 bool RemoveRedundantDebugValues::reduceDbgValues(MachineFunction
&MF
) {
207 LLVM_DEBUG(dbgs() << "\nDebug Value Reduction\n");
209 bool Changed
= false;
211 for (auto &MBB
: MF
) {
212 Changed
|= reduceDbgValsBackwardScan(MBB
);
213 Changed
|= reduceDbgValsForwardScan(MBB
);
219 bool RemoveRedundantDebugValues::runOnMachineFunction(MachineFunction
&MF
) {
220 // Skip functions without debugging information.
221 if (!MF
.getFunction().getSubprogram())
224 // Skip functions from NoDebug compilation units.
225 if (MF
.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
226 DICompileUnit::NoDebug
)
229 bool Changed
= reduceDbgValues(MF
);