[DebugInfo] Terminate more location-list ranges at the end of blocks
This patch fixes PR40795, where constant-valued variable locations can
"leak" into blocks placed at higher addresses. The root of this is that
DbgEntityHistoryCalculator terminates all register variable locations at
the end of each block, but not constant-value variable locations.
Fixing this requires constant-valued DBG_VALUE instructions to be
broadcast into all blocks where the variable location remains valid, as
documented in the LiveDebugValues section of SourceLevelDebugging.rst,
and correct termination in DbgEntityHistoryCalculator.
Differential Revision: https://reviews.llvm.org/D59431
llvm-svn: 359426
diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp
index 449f10c..e36694d 100644
--- a/llvm/lib/CodeGen/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues.cpp
@@ -143,7 +143,8 @@
enum VarLocKind {
InvalidKind = 0,
RegisterKind,
- SpillLocKind
+ SpillLocKind,
+ ImmediateKind
} Kind = InvalidKind;
/// The value location. Stored separately to avoid repeatedly
@@ -152,6 +153,9 @@
uint64_t RegNo;
SpillLoc SpillLocation;
uint64_t Hash;
+ int64_t Immediate;
+ const ConstantFP *FPImm;
+ const ConstantInt *CImm;
} Loc;
VarLoc(const MachineInstr &MI, LexicalScopes &LS)
@@ -164,6 +168,15 @@
if (int RegNo = isDbgValueDescribedByReg(MI)) {
Kind = RegisterKind;
Loc.RegNo = RegNo;
+ } else if (MI.getOperand(0).isImm()) {
+ Kind = ImmediateKind;
+ Loc.Immediate = MI.getOperand(0).getImm();
+ } else if (MI.getOperand(0).isFPImm()) {
+ Kind = ImmediateKind;
+ Loc.FPImm = MI.getOperand(0).getFPImm();
+ } else if (MI.getOperand(0).isCImm()) {
+ Kind = ImmediateKind;
+ Loc.CImm = MI.getOperand(0).getCImm();
}
}
@@ -178,6 +191,9 @@
Loc.SpillLocation = {SpillBase, SpillOffset};
}
+ // Is the Loc field a constant or constant object?
+ bool isConstant() const { return Kind == ImmediateKind; }
+
/// If this variable is described by a register, return it,
/// otherwise return 0.
unsigned isDescribedByReg() const {
@@ -195,7 +211,8 @@
#endif
bool operator==(const VarLoc &Other) const {
- return Var == Other.Var && Loc.Hash == Other.Loc.Hash;
+ return Kind == Other.Kind && Var == Other.Var &&
+ Loc.Hash == Other.Loc.Hash;
}
/// This operator guarantees that VarLocs are sorted by Variable first.
@@ -408,11 +425,23 @@
OpenRanges.erase(V);
// Add the VarLoc to OpenRanges from this DBG_VALUE.
- // TODO: Currently handles DBG_VALUE which has only reg as location.
- if (isDbgValueDescribedByReg(MI)) {
+ unsigned ID;
+ if (isDbgValueDescribedByReg(MI) || MI.getOperand(0).isImm() ||
+ MI.getOperand(0).isFPImm() || MI.getOperand(0).isCImm()) {
+ // Use normal VarLoc constructor for registers and immediates.
VarLoc VL(MI, LS);
- unsigned ID = VarLocIDs.insert(VL);
+ ID = VarLocIDs.insert(VL);
OpenRanges.insert(ID, VL.Var);
+ } else if (MI.hasOneMemOperand()) {
+ // It's a stack spill -- fetch spill base and offset.
+ VarLoc::SpillLoc SpillLocation = extractSpillBaseRegAndOffset(MI);
+ VarLoc VL(MI, SpillLocation.SpillBase, SpillLocation.SpillOffset, LS);
+ ID = VarLocIDs.insert(VL);
+ OpenRanges.insert(ID, VL.Var);
+ } else {
+ // This must be an undefined location. We should leave OpenRanges closed.
+ assert(MI.getOperand(0).isReg() && MI.getOperand(0).getReg() == 0 &&
+ "Unexpected non-undef DBG_VALUE encountered");
}
}
@@ -806,12 +835,19 @@
// a new DBG_VALUE. process() will end this range however appropriate.
const VarLoc &DiffIt = VarLocIDs[ID];
const MachineInstr *DMI = &DiffIt.MI;
- MachineInstr *MI =
- BuildMI(MBB, MBB.instr_begin(), DMI->getDebugLoc(), DMI->getDesc(),
- DMI->isIndirectDebugValue(), DMI->getOperand(0).getReg(),
- DMI->getDebugVariable(), DMI->getDebugExpression());
- if (DMI->isIndirectDebugValue())
- MI->getOperand(1).setImm(DMI->getOperand(1).getImm());
+ MachineInstr *MI = nullptr;
+ if (DiffIt.isConstant()) {
+ MachineOperand MO(DMI->getOperand(0));
+ MI = BuildMI(MBB, MBB.instr_begin(), DMI->getDebugLoc(), DMI->getDesc(),
+ false, MO, DMI->getDebugVariable(),
+ DMI->getDebugExpression());
+ } else {
+ MI = BuildMI(MBB, MBB.instr_begin(), DMI->getDebugLoc(), DMI->getDesc(),
+ DMI->isIndirectDebugValue(), DMI->getOperand(0).getReg(),
+ DMI->getDebugVariable(), DMI->getDebugExpression());
+ if (DMI->isIndirectDebugValue())
+ MI->getOperand(1).setImm(DMI->getOperand(1).getImm());
+ }
LLVM_DEBUG(dbgs() << "Inserted: "; MI->dump(););
ILS.set(ID);
++NumInserted;