LLVM  15.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"
17 #include "llvm/IR/Function.h"
18 #include "llvm/InitializePasses.h"
19 #include "llvm/Pass.h"
20 #include "llvm/PassRegistry.h"
21 
22 /// \file RemoveRedundantDebugValues.cpp
23 ///
24 /// The RemoveRedundantDebugValues pass removes redundant DBG_VALUEs that
25 /// appear in MIR after the register allocator.
26 
27 #define DEBUG_TYPE "removeredundantdebugvalues"
28 
29 using namespace llvm;
30 
31 STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
32 STATISTIC(NumRemovedForward, "Number of DBG_VALUEs removed (forward scan)");
33 
34 namespace {
35 
36 class RemoveRedundantDebugValues : public MachineFunctionPass {
37 public:
38  static char ID;
39 
40  RemoveRedundantDebugValues();
41 
42  bool reduceDbgValues(MachineFunction &MF);
43 
44  /// Remove redundant debug value MIs for the given machine function.
45  bool runOnMachineFunction(MachineFunction &MF) override;
46 
47  void getAnalysisUsage(AnalysisUsage &AU) const override {
48  AU.setPreservesCFG();
50  }
51 };
52 
53 } // namespace
54 
55 //===----------------------------------------------------------------------===//
56 // Implementation
57 //===----------------------------------------------------------------------===//
58 
60 
62 
63 INITIALIZE_PASS(RemoveRedundantDebugValues, DEBUG_TYPE,
64  "Remove Redundant DEBUG_VALUE analysis", false, false)
65 
66 /// Default construct and initialize the pass.
67 RemoveRedundantDebugValues::RemoveRedundantDebugValues()
70 }
71 
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.
75 // For example:
76 // (1) DBG_VALUE $edi, !"var1", ...
77 // (2) <block of code that does affect $edi>
78 // (3) DBG_VALUE $edi, !"var1", ...
79 // ...
80 // in this case, we can remove (3).
81 // TODO: Support DBG_VALUE_LIST and other debug instructions.
83  LLVM_DEBUG(dbgs() << "\n == Forward Scan == \n");
84 
85  SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
87  VariableMap;
88  const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
89 
90  for (auto &MI : MBB) {
91  if (MI.isDebugValue()) {
92  DebugVariable Var(MI.getDebugVariable(), NoneType(),
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()
97  // ...
98  // 2 DBG_VALUE_LIST "x", DIExpression(...), $rax, $rbx
99  // ...
100  // 3 DBG_VALUE $rax, "x", DIExpression()
101  if (MI.isDebugValueList() && VMI != VariableMap.end()) {
102  VariableMap.erase(VMI);
103  continue;
104  }
105 
106  MachineOperand &Loc = MI.getDebugOperand(0);
107  if (!Loc.isReg()) {
108  // If it it's not a register, just stop tracking such variable.
109  if (VMI != VariableMap.end())
110  VariableMap.erase(VMI);
111  continue;
112  }
113 
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()};
119  continue;
120  }
121 
122  // Found an identical DBG_VALUE, so it can be considered
123  // for later removal.
124  DbgValsToBeRemoved.push_back(&MI);
125  }
126 
127  if (MI.isMetaInstruction())
128  continue;
129 
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);
135  }
136  }
137 
138  for (auto &Instr : DbgValsToBeRemoved) {
139  LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
140  Instr->eraseFromParent();
141  ++NumRemovedForward;
142  }
143 
144  return !DbgValsToBeRemoved.empty();
145 }
146 
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.
150 // For example:
151 // (1) DBG_VALUE $edi, !"var1", ...
152 // (2) DBG_VALUE $esi, !"var2", ...
153 // (3) DBG_VALUE $edi, !"var1", ...
154 // ...
155 // in this case, we can remove (1).
157  LLVM_DEBUG(dbgs() << "\n == Backward Scan == \n");
158  SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
159  SmallDenseSet<DebugVariable> VariableSet;
160 
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:
167  // DBG_VALUE 0, ...
168  // we just don't consider such instructions as candidates
169  // for redundant removal.
170  if (MI.isNonListDebugValue()) {
171  MachineOperand &Loc = MI.getDebugOperand(0);
172  if (!Loc.isReg()) {
173  // If we have already encountered this variable, just stop
174  // tracking it.
175  if (!R.second)
176  VariableSet.erase(Var);
177  continue;
178  }
179  }
180 
181  // We have already encountered the value for this variable,
182  // so this one can be deleted.
183  if (!R.second)
184  DbgValsToBeRemoved.push_back(&MI);
185  continue;
186  }
187 
188  // If we encountered a non-DBG_VALUE, try to find the next
189  // sequence with consecutive DBG_VALUE instructions.
190  VariableSet.clear();
191  }
192 
193  for (auto &Instr : DbgValsToBeRemoved) {
194  LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
195  Instr->eraseFromParent();
196  ++NumRemovedBackward;
197  }
198 
199  return !DbgValsToBeRemoved.empty();
200 }
201 
202 bool RemoveRedundantDebugValues::reduceDbgValues(MachineFunction &MF) {
203  LLVM_DEBUG(dbgs() << "\nDebug Value Reduction\n");
204 
205  bool Changed = false;
206 
207  for (auto &MBB : MF) {
208  Changed |= reduceDbgValsBackwardScan(MBB);
209  Changed |= reduceDbgValsForwardScan(MBB);
210  }
211 
212  return Changed;
213 }
214 
215 bool RemoveRedundantDebugValues::runOnMachineFunction(MachineFunction &MF) {
216  // Skip functions without debugging information.
217  if (!MF.getFunction().getSubprogram())
218  return false;
219 
220  // Skip functions from NoDebug compilation units.
221  if (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
223  return false;
224 
225  bool Changed = reduceDbgValues(MF);
226  return Changed;
227 }
DEBUG_TYPE
#define DEBUG_TYPE
Definition: RemoveRedundantDebugValues.cpp:27
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::SmallVectorImpl::erase
iterator erase(const_iterator CI)
Definition: SmallVector.h:724
reduceDbgValsBackwardScan
static bool reduceDbgValsBackwardScan(MachineBasicBlock &MBB)
Definition: RemoveRedundantDebugValues.cpp:156
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:1185
Statistic.h
llvm::Function::getSubprogram
DISubprogram * getSubprogram() const
Get the attached subprogram.
Definition: Metadata.cpp:1573
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:125
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:304
DenseMap.h
llvm::reverse
auto reverse(ContainerTy &&C, std::enable_if_t< has_rbegin< ContainerTy >::value > *=nullptr)
Definition: STLExtras.h:380
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
PassRegistry.h
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1618
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition: MachineFunctionPass.cpp:103
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:82
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
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:48
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:640
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:320
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
llvm::NoneType
NoneType
A simple null object to allow implicit construction of Optional<T> and similar types without having t...
Definition: None.h:23
llvm::DenseMap
Definition: DenseMap.h:716
llvm::DebugVariable
Identifies a unique instance of a variable.
Definition: DebugInfoMetadata.h:3610
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:152
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:234
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
llvm::MachineFunction
Definition: MachineFunction.h:241
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:1322
llvm::AnalysisUsage::setPreservesCFG
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:263
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:606
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:84
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:61
InitializePasses.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:63
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37