[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / lib / CodeGen / RemoveRedundantDebugValues.cpp
blobde6129a912d329ca7fc81e94dec3ff97c26a39d3
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 //===----------------------------------------------------------------------===//
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
24 ///
25 /// The RemoveRedundantDebugValues pass removes redundant DBG_VALUEs that
26 /// appear in MIR after the register allocator.
28 #define DEBUG_TYPE "removeredundantdebugvalues"
30 using namespace llvm;
32 STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
33 STATISTIC(NumRemovedForward, "Number of DBG_VALUEs removed (forward scan)");
35 namespace {
37 class RemoveRedundantDebugValues : public MachineFunctionPass {
38 public:
39 static char ID;
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 {
49 AU.setPreservesCFG();
50 MachineFunctionPass::getAnalysisUsage(AU);
54 } // namespace
56 //===----------------------------------------------------------------------===//
57 // Implementation
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.
76 // For example:
77 // (1) DBG_VALUE $edi, !"var1", ...
78 // (2) <block of code that does affect $edi>
79 // (3) DBG_VALUE $edi, !"var1", ...
80 // ...
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 *>>
88 VariableMap;
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()
98 // ...
99 // 2 DBG_VALUE_LIST "x", DIExpression(...), $rax, $rbx
100 // ...
101 // 3 DBG_VALUE $rax, "x", DIExpression()
102 if (MI.isDebugValueList() && VMI != VariableMap.end()) {
103 VariableMap.erase(VMI);
104 continue;
107 MachineOperand &Loc = MI.getDebugOperand(0);
108 if (!Loc.isReg()) {
109 // If it it's not a register, just stop tracking such variable.
110 if (VMI != VariableMap.end())
111 VariableMap.erase(VMI);
112 continue;
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()};
120 continue;
123 // Found an identical DBG_VALUE, so it can be considered
124 // for later removal.
125 DbgValsToBeRemoved.push_back(&MI);
128 if (MI.isMetaInstruction())
129 continue;
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();
142 ++NumRemovedForward;
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.
151 // For example:
152 // (1) DBG_VALUE $edi, !"var1", ...
153 // (2) DBG_VALUE $esi, !"var2", ...
154 // (3) DBG_VALUE $edi, !"var1", ...
155 // ...
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();
163 I != E; ++I) {
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:
171 // DBG_VALUE 0, ...
172 // we just don't consider such instructions as candidates
173 // for redundant removal.
174 if (MI->isNonListDebugValue()) {
175 MachineOperand &Loc = MI->getDebugOperand(0);
176 if (!Loc.isReg()) {
177 // If we have already encountered this variable, just stop
178 // tracking it.
179 if (!R.second)
180 VariableSet.erase(Var);
181 continue;
185 // We have already encountered the value for this variable,
186 // so this one can be deleted.
187 if (!R.second)
188 DbgValsToBeRemoved.push_back(MI);
189 continue;
192 // If we encountered a non-DBG_VALUE, try to find the next
193 // sequence with consecutive DBG_VALUE instructions.
194 VariableSet.clear();
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);
216 return Changed;
219 bool RemoveRedundantDebugValues::runOnMachineFunction(MachineFunction &MF) {
220 // Skip functions without debugging information.
221 if (!MF.getFunction().getSubprogram())
222 return false;
224 // Skip functions from NoDebug compilation units.
225 if (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
226 DICompileUnit::NoDebug)
227 return false;
229 bool Changed = reduceDbgValues(MF);
230 return Changed;