xref: /llvm-project/llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp (revision df686842bc522b74755e8acbe3de8594e2c36bbd)
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/DenseSet.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/ADT/Statistic.h"
12 #include "llvm/CodeGen/MachineBasicBlock.h"
13 #include "llvm/CodeGen/MachineFunctionPass.h"
14 #include "llvm/CodeGen/Passes.h"
15 #include "llvm/IR/DebugInfoMetadata.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/InitializePasses.h"
18 #include "llvm/Pass.h"
19 
20 /// \file RemoveRedundantDebugValues.cpp
21 ///
22 /// The RemoveRedundantDebugValues pass removes redundant DBG_VALUEs that
23 /// appear in MIR after the register allocator.
24 
25 #define DEBUG_TYPE "removeredundantdebugvalues"
26 
27 using namespace llvm;
28 
29 STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
30 
31 namespace {
32 
33 class RemoveRedundantDebugValues : public MachineFunctionPass {
34 public:
35   static char ID;
36 
37   RemoveRedundantDebugValues();
38 
39   bool reduceDbgValues(MachineFunction &MF);
40 
41   /// Remove redundant debug value MIs for the given machine function.
42   bool runOnMachineFunction(MachineFunction &MF) override;
43 
44   void getAnalysisUsage(AnalysisUsage &AU) const override {
45     AU.setPreservesCFG();
46     MachineFunctionPass::getAnalysisUsage(AU);
47   }
48 };
49 
50 } // namespace
51 
52 //===----------------------------------------------------------------------===//
53 //            Implementation
54 //===----------------------------------------------------------------------===//
55 
56 char RemoveRedundantDebugValues::ID = 0;
57 
58 char &llvm::RemoveRedundantDebugValuesID = RemoveRedundantDebugValues::ID;
59 
60 INITIALIZE_PASS(RemoveRedundantDebugValues, DEBUG_TYPE,
61                 "Remove Redundant DEBUG_VALUE analysis", false, false)
62 
63 /// Default construct and initialize the pass.
64 RemoveRedundantDebugValues::RemoveRedundantDebugValues()
65     : MachineFunctionPass(ID) {
66   initializeRemoveRedundantDebugValuesPass(*PassRegistry::getPassRegistry());
67 }
68 
69 // This analysis aims to remove redundant DBG_VALUEs by going backward
70 // in the basic block and removing all but the last DBG_VALUE for any
71 // given variable in a set of consecutive DBG_VALUE instructions.
72 // For example:
73 //   (1) DBG_VALUE $edi, !"var1", ...
74 //   (2) DBG_VALUE $esi, !"var2", ...
75 //   (3) DBG_VALUE $edi, !"var1", ...
76 //   ...
77 // in this case, we can remove (1).
78 static bool reduceDbgValsBackwardScan(MachineBasicBlock &MBB) {
79   LLVM_DEBUG(dbgs() << "\n == Backward Scan == \n");
80   SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
81   SmallDenseSet<DebugVariable> VariableSet;
82 
83   for (MachineBasicBlock::reverse_iterator I = MBB.rbegin(), E = MBB.rend();
84        I != E; ++I) {
85     MachineInstr *MI = &*I;
86 
87     if (MI->isDebugValue()) {
88       DebugVariable Var(MI->getDebugVariable(), MI->getDebugExpression(),
89                         MI->getDebugLoc()->getInlinedAt());
90       auto R = VariableSet.insert(Var);
91       // If it is a DBG_VALUE describing a constant as:
92       //   DBG_VALUE 0, ...
93       // we just don't consider such instructions as candidates
94       // for redundant removal.
95       if (MI->isNonListDebugValue()) {
96         MachineOperand &Loc = MI->getDebugOperand(0);
97         if (!Loc.isReg()) {
98           // If we have already encountered this variable, just stop
99           // tracking it.
100           if (!R.second)
101             VariableSet.erase(Var);
102           continue;
103         }
104       }
105 
106       // We have already encountered the value for this variable,
107       // so this one can be deleted.
108       if (!R.second)
109         DbgValsToBeRemoved.push_back(MI);
110       continue;
111     }
112 
113     // If we encountered a non-DBG_VALUE, try to find the next
114     // sequence with consecutive DBG_VALUE instructions.
115     VariableSet.clear();
116   }
117 
118   for (auto &Instr : DbgValsToBeRemoved) {
119     LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
120     Instr->eraseFromParent();
121     ++NumRemovedBackward;
122   }
123 
124   return !DbgValsToBeRemoved.empty();
125 }
126 
127 bool RemoveRedundantDebugValues::reduceDbgValues(MachineFunction &MF) {
128   LLVM_DEBUG(dbgs() << "\nDebug Value Reduction\n");
129 
130   bool Changed = false;
131 
132   for (auto &MBB : MF)
133     Changed |= reduceDbgValsBackwardScan(MBB);
134 
135   return Changed;
136 }
137 
138 bool RemoveRedundantDebugValues::runOnMachineFunction(MachineFunction &MF) {
139   // Skip functions without debugging information.
140   if (!MF.getFunction().getSubprogram())
141     return false;
142 
143   // Skip functions from NoDebug compilation units.
144   if (MF.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
145       DICompileUnit::NoDebug)
146     return false;
147 
148   bool Changed = reduceDbgValues(MF);
149   return Changed;
150 }
151