aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveDebugVariables.cpp
diff options
context:
space:
mode:
authorDavid Stenberg <david.stenberg@ericsson.com>2018-09-07 13:54:07 +0000
committerDavid Stenberg <david.stenberg@ericsson.com>2018-09-07 13:54:07 +0000
commit45acc9610bc61fe3f76ff192cf70e1757440f383 (patch)
treed32a7cdb33f2038592f3cd6961ce122edeb8d576 /llvm/lib/CodeGen/LiveDebugVariables.cpp
parent9ad0f02749f1a6566693a8d5dc33775b31cddbd5 (diff)
downloadllvm-45acc9610bc61fe3f76ff192cf70e1757440f383.zip
llvm-45acc9610bc61fe3f76ff192cf70e1757440f383.tar.gz
llvm-45acc9610bc61fe3f76ff192cf70e1757440f383.tar.bz2
[DebugInfo] Handle stack slot offsets for spilled sub-registers in LDV
Summary: Extend LDV so that stack slot offsets for spilled sub-registers are added to the emitted debug locations. This is accomplished by querying InstrInfo::getStackSlotRange(). With this change, LDV will add a DW_OP_plus_uconst operation to the expression if a sub-register is spilled. Later on, PEI will add an offset operation for the stack slot, meaning that we will get expressions of the forms: * {DW_OP_constu #fp-offset, DW_OP_minus, DW_OP_plus_uconst #subreg-offset} * {DW_OP_plus_const #fp-offset, DW_OP_minus, DW_OP_plus_uconst #subreg-offset} The two offset operations should ideally be merged. Reviewers: rnk, aprantl, stoklund Reviewed By: aprantl Subscribers: dblaikie, bjope, nemanjai, JDevlieghere, llvm-commits Tags: #debug-info Differential Revision: https://reviews.llvm.org/D51612 llvm-svn: 341659
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugVariables.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugVariables.cpp87
1 files changed, 57 insertions, 30 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 4c002d4..01779b1 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -135,6 +135,10 @@ private:
/// LocMap - Map of where a user value is live, and its location.
using LocMap = IntervalMap<SlotIndex, DbgValueLocation, 4>;
+/// SpillOffsetMap - Map of stack slot offsets for spilled locations.
+/// Non-spilled locations are not added to the map.
+using SpillOffsetMap = DenseMap<unsigned, unsigned>;
+
namespace {
class LDVImpl;
@@ -168,8 +172,8 @@ class UserValue {
/// insertDebugValue - Insert a DBG_VALUE into MBB at Idx for LocNo.
void insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
- SlotIndex StopIdx,
- DbgValueLocation Loc, bool Spilled, LiveIntervals &LIS,
+ SlotIndex StopIdx, DbgValueLocation Loc, bool Spilled,
+ unsigned SpillOffset, LiveIntervals &LIS,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI);
@@ -311,15 +315,18 @@ public:
LiveIntervals &LIS);
/// rewriteLocations - Rewrite virtual register locations according to the
- /// provided virtual register map. Record which locations were spilled.
- void rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
- BitVector &SpilledLocations);
+ /// provided virtual register map. Record the stack slot offsets for the
+ /// locations that were spilled.
+ void rewriteLocations(VirtRegMap &VRM, const MachineFunction &MF,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ SpillOffsetMap &SpillOffsets);
/// emitDebugValues - Recreate DBG_VALUE instruction from data structures.
void emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
- const BitVector &SpilledLocations);
+ const SpillOffsetMap &SpillOffsets);
/// getDebugLoc - Return DebugLoc of this UserValue.
DebugLoc getDebugLoc() { return dl;}
@@ -1052,8 +1059,10 @@ splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs, LiveIntervals &LIS) {
static_cast<LDVImpl*>(pImpl)->splitRegister(OldReg, NewRegs);
}
-void UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
- BitVector &SpilledLocations) {
+void UserValue::rewriteLocations(VirtRegMap &VRM, const MachineFunction &MF,
+ const TargetInstrInfo &TII,
+ const TargetRegisterInfo &TRI,
+ SpillOffsetMap &SpillOffsets) {
// Build a set of new locations with new numbers so we can coalesce our
// IntervalMap if two vreg intervals collapse to the same physical location.
// Use MapVector instead of SetVector because MapVector::insert returns the
@@ -1062,10 +1071,11 @@ void UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
// FIXME: This will be problematic if we ever support direct and indirect
// frame index locations, i.e. expressing both variables in memory and
// 'int x, *px = &x'. The "spilled" bit must become part of the location.
- MapVector<MachineOperand, bool> NewLocations;
+ MapVector<MachineOperand, std::pair<bool, unsigned>> NewLocations;
SmallVector<unsigned, 4> LocNoMap(locations.size());
for (unsigned I = 0, E = locations.size(); I != E; ++I) {
bool Spilled = false;
+ unsigned SpillOffset = 0;
MachineOperand Loc = locations[I];
// Only virtual registers are rewritten.
if (Loc.isReg() && Loc.getReg() &&
@@ -1078,7 +1088,16 @@ void UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
// non-existent sub-register, and %noreg is exactly what we want.
Loc.substPhysReg(VRM.getPhys(VirtReg), TRI);
} else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) {
- // FIXME: Translate SubIdx to a stackslot offset.
+ // Retrieve the stack slot offset.
+ unsigned SpillSize;
+ const MachineRegisterInfo &MRI = MF.getRegInfo();
+ const TargetRegisterClass *TRC = MRI.getRegClass(VirtReg);
+ bool Success = TII.getStackSlotRange(TRC, Loc.getSubReg(), SpillSize,
+ SpillOffset, MF);
+
+ // FIXME: Invalidate the location if the offset couldn't be calculated.
+ (void)Success;
+
Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg));
Spilled = true;
} else {
@@ -1089,20 +1108,22 @@ void UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
// Insert this location if it doesn't already exist and record a mapping
// from the old number to the new number.
- auto InsertResult = NewLocations.insert({Loc, Spilled});
+ auto InsertResult = NewLocations.insert({Loc, {Spilled, SpillOffset}});
unsigned NewLocNo = std::distance(NewLocations.begin(), InsertResult.first);
LocNoMap[I] = NewLocNo;
}
- // Rewrite the locations and record which ones were spill slots.
+ // Rewrite the locations and record the stack slot offsets for spills.
locations.clear();
- SpilledLocations.clear();
- SpilledLocations.resize(NewLocations.size());
+ SpillOffsets.clear();
for (auto &Pair : NewLocations) {
+ bool Spilled;
+ unsigned SpillOffset;
+ std::tie(Spilled, SpillOffset) = Pair.second;
locations.push_back(Pair.first);
- if (Pair.second) {
+ if (Spilled) {
unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);
- SpilledLocations.set(NewLocNo);
+ SpillOffsets[NewLocNo] = SpillOffset;
}
}
@@ -1171,10 +1192,9 @@ findNextInsertLocation(MachineBasicBlock *MBB,
}
void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
- SlotIndex StopIdx,
- DbgValueLocation Loc, bool Spilled,
- LiveIntervals &LIS,
- const TargetInstrInfo &TII,
+ SlotIndex StopIdx, DbgValueLocation Loc,
+ bool Spilled, unsigned SpillOffset,
+ LiveIntervals &LIS, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI) {
SlotIndex MBBEndIdx = LIS.getMBBEndIdx(&*MBB);
// Only search within the current MBB.
@@ -1197,12 +1217,14 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
// If the location was spilled, the new DBG_VALUE will be indirect. If the
// original DBG_VALUE was indirect, we need to add DW_OP_deref to indicate
- // that the original virtual register was a pointer.
+ // that the original virtual register was a pointer. Also, add the stack slot
+ // offset for the spilled register to the expression.
const DIExpression *Expr = Expression;
bool IsIndirect = Loc.wasIndirect();
if (Spilled) {
- if (IsIndirect)
- Expr = DIExpression::prepend(Expr, DIExpression::WithDeref);
+ auto Deref = IsIndirect ? DIExpression::WithDeref : DIExpression::NoDeref;
+ Expr =
+ DIExpression::prepend(Expr, DIExpression::NoDeref, SpillOffset, Deref);
IsIndirect = true;
}
@@ -1221,14 +1243,17 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
- const BitVector &SpilledLocations) {
+ const SpillOffsetMap &SpillOffsets) {
MachineFunction::iterator MFEnd = VRM->getMachineFunction().end();
for (LocMap::const_iterator I = locInts.begin(); I.valid();) {
SlotIndex Start = I.start();
SlotIndex Stop = I.stop();
DbgValueLocation Loc = I.value();
- bool Spilled = !Loc.isUndef() ? SpilledLocations.test(Loc.locNo()) : false;
+ auto SpillIt =
+ !Loc.isUndef() ? SpillOffsets.find(Loc.locNo()) : SpillOffsets.end();
+ bool Spilled = SpillIt != SpillOffsets.end();
+ unsigned SpillOffset = Spilled ? SpillIt->second : 0;
// If the interval start was trimmed to the lexical scope insert the
// DBG_VALUE at the previous index (otherwise it appears after the
@@ -1241,7 +1266,8 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
SlotIndex MBBEnd = LIS.getMBBEndIdx(&*MBB);
LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd);
- insertDebugValue(&*MBB, Start, Stop, Loc, Spilled, LIS, TII, TRI);
+ insertDebugValue(&*MBB, Start, Stop, Loc, Spilled, SpillOffset, LIS, TII,
+ TRI);
// This interval may span multiple basic blocks.
// Insert a DBG_VALUE into each one.
while (Stop > MBBEnd) {
@@ -1251,7 +1277,8 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
break;
MBBEnd = LIS.getMBBEndIdx(&*MBB);
LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd);
- insertDebugValue(&*MBB, Start, Stop, Loc, Spilled, LIS, TII, TRI);
+ insertDebugValue(&*MBB, Start, Stop, Loc, Spilled, SpillOffset, LIS, TII,
+ TRI);
}
LLVM_DEBUG(dbgs() << '\n');
if (MBB == MFEnd)
@@ -1266,11 +1293,11 @@ void LDVImpl::emitDebugValues(VirtRegMap *VRM) {
if (!MF)
return;
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
- BitVector SpilledLocations;
+ SpillOffsetMap SpillOffsets;
for (unsigned i = 0, e = userValues.size(); i != e; ++i) {
LLVM_DEBUG(userValues[i]->print(dbgs(), TRI));
- userValues[i]->rewriteLocations(*VRM, *TRI, SpilledLocations);
- userValues[i]->emitDebugValues(VRM, *LIS, *TII, *TRI, SpilledLocations);
+ userValues[i]->rewriteLocations(*VRM, *MF, *TII, *TRI, SpillOffsets);
+ userValues[i]->emitDebugValues(VRM, *LIS, *TII, *TRI, SpillOffsets);
}
EmitDone = true;
}