aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp')
-rw-r--r--llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp83
1 files changed, 82 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp b/llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
index fe71a5f..de6129a 100644
--- a/llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
+++ b/llvm/lib/CodeGen/RemoveRedundantDebugValues.cpp
@@ -6,12 +6,15 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/InitializePasses.h"
@@ -27,6 +30,7 @@
using namespace llvm;
STATISTIC(NumRemovedBackward, "Number of DBG_VALUEs removed (backward scan)");
+STATISTIC(NumRemovedForward, "Number of DBG_VALUEs removed (forward scan)");
namespace {
@@ -66,6 +70,81 @@ RemoveRedundantDebugValues::RemoveRedundantDebugValues()
initializeRemoveRedundantDebugValuesPass(*PassRegistry::getPassRegistry());
}
+// This analysis aims to remove redundant DBG_VALUEs by going forward
+// in the basic block by considering the first DBG_VALUE as a valid
+// until its first (location) operand is not clobbered/modified.
+// For example:
+// (1) DBG_VALUE $edi, !"var1", ...
+// (2) <block of code that does affect $edi>
+// (3) DBG_VALUE $edi, !"var1", ...
+// ...
+// in this case, we can remove (3).
+// TODO: Support DBG_VALUE_LIST and other debug instructions.
+static bool reduceDbgValsForwardScan(MachineBasicBlock &MBB) {
+ LLVM_DEBUG(dbgs() << "\n == Forward Scan == \n");
+
+ SmallVector<MachineInstr *, 8> DbgValsToBeRemoved;
+ DenseMap<DebugVariable, std::pair<MachineOperand *, const DIExpression *>>
+ VariableMap;
+ const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
+
+ for (auto &MI : MBB) {
+ if (MI.isDebugValue()) {
+ DebugVariable Var(MI.getDebugVariable(), NoneType(),
+ MI.getDebugLoc()->getInlinedAt());
+ auto VMI = VariableMap.find(Var);
+ // Just stop tracking this variable, until we cover DBG_VALUE_LIST.
+ // 1 DBG_VALUE $rax, "x", DIExpression()
+ // ...
+ // 2 DBG_VALUE_LIST "x", DIExpression(...), $rax, $rbx
+ // ...
+ // 3 DBG_VALUE $rax, "x", DIExpression()
+ if (MI.isDebugValueList() && VMI != VariableMap.end()) {
+ VariableMap.erase(VMI);
+ continue;
+ }
+
+ MachineOperand &Loc = MI.getDebugOperand(0);
+ if (!Loc.isReg()) {
+ // If it it's not a register, just stop tracking such variable.
+ if (VMI != VariableMap.end())
+ VariableMap.erase(VMI);
+ continue;
+ }
+
+ // We have found a new value for a variable.
+ if (VMI == VariableMap.end() ||
+ VMI->second.first->getReg() != Loc.getReg() ||
+ VMI->second.second != MI.getDebugExpression()) {
+ VariableMap[Var] = {&Loc, MI.getDebugExpression()};
+ continue;
+ }
+
+ // Found an identical DBG_VALUE, so it can be considered
+ // for later removal.
+ DbgValsToBeRemoved.push_back(&MI);
+ }
+
+ if (MI.isMetaInstruction())
+ continue;
+
+ // Stop tracking any location that is clobbered by this instruction.
+ for (auto &Var : VariableMap) {
+ auto &LocOp = Var.second.first;
+ if (MI.modifiesRegister(LocOp->getReg(), TRI))
+ VariableMap.erase(Var.first);
+ }
+ }
+
+ for (auto &Instr : DbgValsToBeRemoved) {
+ LLVM_DEBUG(dbgs() << "removing "; Instr->dump());
+ Instr->eraseFromParent();
+ ++NumRemovedForward;
+ }
+
+ return !DbgValsToBeRemoved.empty();
+}
+
// This analysis aims to remove redundant DBG_VALUEs by going backward
// in the basic block and removing all but the last DBG_VALUE for any
// given variable in a set of consecutive DBG_VALUE instructions.
@@ -129,8 +208,10 @@ bool RemoveRedundantDebugValues::reduceDbgValues(MachineFunction &MF) {
bool Changed = false;
- for (auto &MBB : MF)
+ for (auto &MBB : MF) {
Changed |= reduceDbgValsBackwardScan(MBB);
+ Changed |= reduceDbgValsForwardScan(MBB);
+ }
return Changed;
}