summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/LiveDebugVariables.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-09-20 18:19:08 +0000
committerReid Kleckner <rnk@google.com>2017-09-20 18:19:08 +0000
commit4e040287919c339506d6f795e42b41325fd22171 (patch)
tree464f82f4c71958684d5e213681fc7e12820643a3 /llvm/lib/CodeGen/LiveDebugVariables.cpp
parent6c84ffbf5fd9d50995eee0a8fbf9efafe08790d7 (diff)
downloadbcm5719-llvm-4e040287919c339506d6f795e42b41325fd22171.tar.gz
bcm5719-llvm-4e040287919c339506d6f795e42b41325fd22171.zip
Re-land "[DebugInfo] Insert DW_OP_deref when spilling indirect DBG_VALUEs"
After r313775, it's easier to maintain a parallel BitVector of spilled locations indexed by location number. I wasn't able to build a good reduced test case for this iteration of the bug, but I added a more direct assertion that spilled values must use frame index locations. If this bug reappears, it won't only fire on the NEON vector code that we detected it on, but on medium-sized integer-only programs as well. llvm-svn: 313786
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugVariables.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugVariables.cpp112
1 files changed, 72 insertions, 40 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 93cb7c3838e..37ff30a92a0 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -108,8 +108,8 @@ class LDVImpl;
/// held by the same virtual register. The equivalence class is the transitive
/// closure of that relation.
class UserValue {
- const MDNode *Variable; ///< The debug info variable we are part of.
- const MDNode *Expression; ///< Any complex address expression.
+ const DILocalVariable *Variable; ///< The debug info variable we are part of.
+ const DIExpression *Expression; ///< Any complex address expression.
bool IsIndirect; ///< true if this is a register-indirect+offset value.
DebugLoc dl; ///< The debug location for the variable. This is
///< used by dwarf writer to find lexical scope.
@@ -127,8 +127,9 @@ class UserValue {
SmallSet<SlotIndex, 2> trimmedDefs;
/// insertDebugValue - Insert a DBG_VALUE into MBB at Idx for LocNo.
- void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo,
- LiveIntervals &LIS, const TargetInstrInfo &TII);
+ void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
+ unsigned LocNo, bool Spilled, LiveIntervals &LIS,
+ const TargetInstrInfo &TII);
/// splitLocation - Replace OldLocNo ranges with NewRegs ranges where NewRegs
/// is live. Returns true if any changes were made.
@@ -137,8 +138,8 @@ class UserValue {
public:
/// UserValue - Create a new UserValue.
- UserValue(const MDNode *var, const MDNode *expr, bool i, DebugLoc L,
- LocMap::Allocator &alloc)
+ UserValue(const DILocalVariable *var, const DIExpression *expr, bool i,
+ DebugLoc L, LocMap::Allocator &alloc)
: Variable(var), Expression(expr), IsIndirect(i), dl(std::move(L)),
leader(this), locInts(alloc) {}
@@ -154,8 +155,8 @@ public:
UserValue *getNext() const { return next; }
/// match - Does this UserValue match the parameters?
- bool match(const MDNode *Var, const MDNode *Expr, const DILocation *IA,
- bool indirect) const {
+ bool match(const DILocalVariable *Var, const DIExpression *Expr,
+ const DILocation *IA, bool indirect) const {
return Var == Variable && Expr == Expression && dl->getInlinedAt() == IA &&
indirect == IsIndirect;
}
@@ -259,12 +260,14 @@ public:
LiveIntervals &LIS);
/// rewriteLocations - Rewrite virtual register locations according to the
- /// provided virtual register map.
- void rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI);
+ /// provided virtual register map. Record which locations were spilled.
+ void rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
+ BitVector &SpilledLocations);
/// emitDebugValues - Recreate DBG_VALUE instruction from data structures.
- void emitDebugValues(VirtRegMap *VRM,
- LiveIntervals &LIS, const TargetInstrInfo &TRI);
+ void emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
+ const TargetInstrInfo &TRI,
+ const BitVector &SpilledLocations);
/// getDebugLoc - Return DebugLoc of this UserValue.
DebugLoc getDebugLoc() { return dl;}
@@ -294,11 +297,11 @@ class LDVImpl {
VRMap virtRegToEqClass;
/// Map user variable to eq class leader.
- using UVMap = DenseMap<const MDNode *, UserValue *>;
+ using UVMap = DenseMap<const DILocalVariable *, UserValue *>;
UVMap userVarMap;
/// getUserValue - Find or create a UserValue.
- UserValue *getUserValue(const MDNode *Var, const MDNode *Expr,
+ UserValue *getUserValue(const DILocalVariable *Var, const DIExpression *Expr,
bool IsIndirect, const DebugLoc &DL);
/// lookupVirtReg - Find the EC leader for VirtReg or null.
@@ -423,8 +426,9 @@ void UserValue::mapVirtRegs(LDVImpl *LDV) {
LDV->mapVirtReg(locations[i].getReg(), this);
}
-UserValue *LDVImpl::getUserValue(const MDNode *Var, const MDNode *Expr,
- bool IsIndirect, const DebugLoc &DL) {
+UserValue *LDVImpl::getUserValue(const DILocalVariable *Var,
+ const DIExpression *Expr, bool IsIndirect,
+ const DebugLoc &DL) {
UserValue *&Leader = userVarMap[Var];
if (Leader) {
UserValue *UV = Leader->getLeader();
@@ -463,11 +467,11 @@ bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) {
}
// Get or create the UserValue for (variable,offset).
- bool IsIndirect = MI.isIndirectDebugValue();
+ bool IsIndirect = MI.getOperand(1).isImm();
if (IsIndirect)
assert(MI.getOperand(1).getImm() == 0 && "DBG_VALUE with nonzero offset");
- const MDNode *Var = MI.getDebugVariable();
- const MDNode *Expr = MI.getDebugExpression();
+ const DILocalVariable *Var = MI.getDebugVariable();
+ const DIExpression *Expr = MI.getDebugExpression();
//here.
UserValue *UV = getUserValue(Var, Expr, IsIndirect, MI.getDebugLoc());
UV->addDef(Idx, MI.getOperand(0));
@@ -940,15 +944,20 @@ splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs, LiveIntervals &LIS) {
static_cast<LDVImpl*>(pImpl)->splitRegister(OldReg, NewRegs);
}
-void UserValue::rewriteLocations(VirtRegMap &VRM,
- const TargetRegisterInfo &TRI) {
+void UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI,
+ BitVector &SpilledLocations) {
// 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
- // position of the previously or newly inserted element.
+ // position of the previously or newly inserted element. The boolean value
+ // tracks if the location was produced by a spill.
+ // 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;
SmallVector<unsigned, 4> LocNoMap(locations.size());
for (unsigned I = 0, E = locations.size(); I != E; ++I) {
+ bool Spilled = false;
MachineOperand Loc = locations[I];
// Only virtual registers are rewritten.
if (Loc.isReg() && Loc.getReg() &&
@@ -963,6 +972,7 @@ void UserValue::rewriteLocations(VirtRegMap &VRM,
} else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) {
// FIXME: Translate SubIdx to a stackslot offset.
Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg));
+ Spilled = true;
} else {
Loc.setReg(0);
Loc.setSubReg(0);
@@ -971,14 +981,22 @@ void UserValue::rewriteLocations(VirtRegMap &VRM,
// 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, false});
- LocNoMap[I] = std::distance(NewLocations.begin(), InsertResult.first);
+ auto InsertResult = NewLocations.insert({Loc, Spilled});
+ unsigned NewLocNo = std::distance(NewLocations.begin(), InsertResult.first);
+ LocNoMap[I] = NewLocNo;
}
- // Rewrite the locations.
+ // Rewrite the locations and record which ones were spill slots.
locations.clear();
- for (const auto &Pair : NewLocations)
+ SpilledLocations.clear();
+ SpilledLocations.resize(NewLocations.size());
+ for (auto &Pair : NewLocations) {
locations.push_back(Pair.first);
+ if (Pair.second) {
+ unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);
+ SpilledLocations.set(NewLocNo);
+ }
+ }
// Update the interval map, but only coalesce left, since intervals to the
// right use the old location numbers. This should merge two contiguous
@@ -1016,7 +1034,7 @@ findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx,
}
void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
- unsigned LocNo,
+ unsigned LocNo, bool Spilled,
LiveIntervals &LIS,
const TargetInstrInfo &TII) {
MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS);
@@ -1026,25 +1044,38 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx,
assert(cast<DILocalVariable>(Variable)
->isValidLocationForIntrinsic(getDebugLoc()) &&
"Expected inlined-at fields to agree");
- if (Loc.isReg())
- BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE),
- IsIndirect, Loc.getReg(), Variable, Expression);
+
+ // 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.
+ bool NewIndirect = IsIndirect || Spilled;
+ const DIExpression *Expr = Expression;
+ if (Spilled && IsIndirect)
+ Expr = DIExpression::prepend(Expr, DIExpression::WithDeref);
+
+ assert((!Spilled || Loc.isFI()) &&
+ "a spilled location must be a frame index");
+
+ MachineInstrBuilder MIB =
+ BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
+ .add(Loc);
+ if (NewIndirect)
+ MIB.addImm(0U);
else
- BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_VALUE))
- .add(Loc)
- .addImm(0U)
- .addMetadata(Variable)
- .addMetadata(Expression);
+ MIB.addReg(0U, RegState::Debug);
+ MIB.addMetadata(Variable).addMetadata(Expr);
}
void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
- const TargetInstrInfo &TII) {
+ const TargetInstrInfo &TII,
+ const BitVector &SpilledLocations) {
MachineFunction::iterator MFEnd = VRM->getMachineFunction().end();
for (LocMap::const_iterator I = locInts.begin(); I.valid();) {
SlotIndex Start = I.start();
SlotIndex Stop = I.stop();
unsigned LocNo = I.value();
+ bool Spilled = LocNo != UndefLocNo ? SpilledLocations.test(LocNo) : false;
// If the interval start was trimmed to the lexical scope insert the
// DBG_VALUE at the previous index (otherwise it appears after the
@@ -1057,7 +1088,7 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
SlotIndex MBBEnd = LIS.getMBBEndIdx(&*MBB);
DEBUG(dbgs() << " BB#" << MBB->getNumber() << '-' << MBBEnd);
- insertDebugValue(&*MBB, Start, LocNo, LIS, TII);
+ insertDebugValue(&*MBB, Start, LocNo, Spilled, LIS, TII);
// This interval may span multiple basic blocks.
// Insert a DBG_VALUE into each one.
while(Stop > MBBEnd) {
@@ -1067,7 +1098,7 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
break;
MBBEnd = LIS.getMBBEndIdx(&*MBB);
DEBUG(dbgs() << " BB#" << MBB->getNumber() << '-' << MBBEnd);
- insertDebugValue(&*MBB, Start, LocNo, LIS, TII);
+ insertDebugValue(&*MBB, Start, LocNo, Spilled, LIS, TII);
}
DEBUG(dbgs() << '\n');
if (MBB == MFEnd)
@@ -1082,10 +1113,11 @@ void LDVImpl::emitDebugValues(VirtRegMap *VRM) {
if (!MF)
return;
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
+ BitVector SpilledLocations;
for (unsigned i = 0, e = userValues.size(); i != e; ++i) {
DEBUG(userValues[i]->print(dbgs(), TRI));
- userValues[i]->rewriteLocations(*VRM, *TRI);
- userValues[i]->emitDebugValues(VRM, *LIS, *TII);
+ userValues[i]->rewriteLocations(*VRM, *TRI, SpilledLocations);
+ userValues[i]->emitDebugValues(VRM, *LIS, *TII, SpilledLocations);
}
EmitDone = true;
}
OpenPOWER on IntegriCloud