LLVM  14.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 
9 #include "llvm/ADT/DenseMap.h"
10 #include "llvm/ADT/DenseSet.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/Statistic.h"
15 #include "llvm/CodeGen/Passes.h"
19 #include "llvm/IR/Function.h"
20 #include "llvm/InitializePasses.h"
21 #include "llvm/Pass.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 
30 using namespace llvm;
31 
32 STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
33 STATISTIC(NumRemovedForward, "Number of DBG_VALUEs removed (forward scan)");
34 
35 namespace {
36 
37 class RemoveRedundantDebugValues : public MachineFunctionPass {
38 public:
39  static char ID;
40 
41  RemoveRedundantDebugValues();
42 
43  bool reduceDbgValues(MachineFunction &MF);
44 
45  /// Remove redundant debug value MIs for the given machine function.
46  bool runOnMachineFunction(MachineFunction &MF) override;
47 
48  void getAnalysisUsage(AnalysisUsage &AU) const override {
49  AU.setPreservesCFG();
51  }
52 };
53 
54 } // namespace
55 
56 //===----------------------------------------------------------------------===//
57 // Implementation
58 //===----------------------------------------------------------------------===//
59 
61 
63 
64 INITIALIZE_PASS(RemoveRedundantDebugValues, DEBUG_TYPE,
65  "Remove Redundant DEBUG_VALUE analysis", false, false)
66 
67 /// Default construct and initialize the pass.
68 RemoveRedundantDebugValues::RemoveRedundantDebugValues()
71 }
72 
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.
84  LLVM_DEBUG(dbgs() << "\n == Forward Scan == \n");
85 
86  SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
88  VariableMap;
89  const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
90 
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;
105  }
106 
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;
113  }
114 
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;
121  }
122 
123  // Found an identical DBG_VALUE, so it can be considered
124  // for later removal.
125  DbgValsToBeRemoved.push_back(&MI);
126  }
127 
128  if (MI.isMetaInstruction())
129  continue;
130 
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);
136  }
137  }
138 
139  for (auto &Instr : DbgValsToBeRemoved) {
140  LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
141  Instr->eraseFromParent();
142  ++NumRemovedForward;
143  }
144 
145  return !DbgValsToBeRemoved.empty();
146 }
147 
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).
158  LLVM_DEBUG(dbgs() << "\n == Backward Scan == \n");
159  SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
160  SmallDenseSet<DebugVariable> VariableSet;
161 
163  I != E; ++I) {
164  MachineInstr *MI = &*I;
165 
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;
182  }
183  }
184 
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;
190  }
191 
192  // If we encountered a non-DBG_VALUE, try to find the next
193  // sequence with consecutive DBG_VALUE instructions.
194  VariableSet.clear();
195  }
196 
197  for (auto &Instr : DbgValsToBeRemoved) {
198  LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
199  Instr->eraseFromParent();
200  ++NumRemovedBackward;
201  }
202 
203  return !DbgValsToBeRemoved.empty();
204 }
205 
206 bool RemoveRedundantDebugValues::reduceDbgValues(MachineFunction &MF) {
207  LLVM_DEBUG(dbgs() << "\nDebug Value Reduction\n");
208 
209  bool Changed = false;
210 
211  for (auto &MBB : MF) {
212  Changed |= reduceDbgValsBackwardScan(MBB);
213  Changed |= reduceDbgValsForwardScan(MBB);
214  }
215 
216  return Changed;
217 }
218 
219 bool RemoveRedundantDebugValues::runOnMachineFunction(MachineFunction &MF) {
220  // Skip functions without debugging information.
221  if (!MF.getFunction().getSubprogram())
222  return false;
223 
224  // Skip functions from NoDebug compilation units.
225  if (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
227  return false;
228 
229  bool Changed = reduceDbgValues(MF);
230  return Changed;
231 }
DEBUG_TYPE
#define DEBUG_TYPE
Definition: RemoveRedundantDebugValues.cpp:28
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::SmallVectorImpl::erase
iterator erase(const_iterator CI)
Definition: SmallVector.h:705
reduceDbgValsBackwardScan
static bool reduceDbgValsBackwardScan(MachineBasicBlock &MBB)
Definition: RemoveRedundantDebugValues.cpp:157
DebugInfoMetadata.h
Pass.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
Statistic.h
llvm::Function::getSubprogram
DISubprogram * getSubprogram() const
Get the attached subprogram.
Definition: Metadata.cpp:1541
llvm::SmallDenseSet
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition: DenseSet.h:286
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
MachineBasicBlock.h
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::erase
bool erase(const KeyT &Val)
Definition: DenseMap.h:302
DenseMap.h
llvm::detail::DenseSetImpl< ValueT, SmallDenseMap< ValueT, detail::DenseSetEmpty, 4, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1559
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:102
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
reduceDbgValsForwardScan
static bool reduceDbgValsForwardScan(MachineBasicBlock &MBB)
Definition: RemoveRedundantDebugValues.cpp:83
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
DenseSet.h
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::MachineBasicBlock::rend
reverse_iterator rend()
Definition: MachineBasicBlock.h:278
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
Passes.h
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:634
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::NoneType
NoneType
A simple null object to allow implicit construction of Optional<T> and similar types without having t...
Definition: None.h:22
llvm::DenseMap
Definition: DenseMap.h:714
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::DebugVariable
Identifies a unique instance of a variable.
Definition: DebugInfoMetadata.h:3670
MachineFunctionPass.h
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:150
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::MachineFunction
Definition: MachineFunction.h:234
llvm::detail::DenseSetImpl< ValueT, SmallDenseMap< ValueT, detail::DenseSetEmpty, 4, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::clear
void clear()
Definition: DenseSet.h:92
llvm::DICompileUnit::NoDebug
@ NoDebug
Definition: DebugInfoMetadata.h:1343
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:253
llvm::MachineBasicBlock::rbegin
reverse_iterator rbegin()
Definition: MachineBasicBlock.h:272
TargetSubtargetInfo.h
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:600
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end
iterator end()
Definition: DenseMap.h:83
Function.h
llvm::initializeRemoveRedundantDebugValuesPass
void initializeRemoveRedundantDebugValuesPass(PassRegistry &)
SmallVector.h
llvm::detail::DenseSetImpl< ValueT, SmallDenseMap< ValueT, detail::DenseSetEmpty, 4, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::erase
bool erase(const ValueT &V)
Definition: DenseSet.h:101
llvm::RemoveRedundantDebugValuesID
char & RemoveRedundantDebugValuesID
RemoveRedundantDebugValues pass.
Definition: RemoveRedundantDebugValues.cpp:62
llvm::MachineInstrBundleIterator
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i....
Definition: MachineInstrBundleIterator.h:108
InitializePasses.h
TargetRegisterInfo.h
INITIALIZE_PASS
INITIALIZE_PASS(RemoveRedundantDebugValues, DEBUG_TYPE, "Remove Redundant DEBUG_VALUE analysis", false, false) RemoveRedundantDebugValues
Default construct and initialize the pass.
Definition: RemoveRedundantDebugValues.cpp:64
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38