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