summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/LiveDebugValues.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugValues.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues.cpp244
1 files changed, 137 insertions, 107 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugValues.cpp b/llvm/lib/CodeGen/LiveDebugValues.cpp
index 8d523377fb4..5a495594045 100644
--- a/llvm/lib/CodeGen/LiveDebugValues.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues.cpp
@@ -219,8 +219,7 @@ private:
const ConstantInt *CImm;
} Loc;
- VarLoc(const MachineInstr &MI, LexicalScopes &LS,
- VarLocKind K = InvalidKind)
+ VarLoc(const MachineInstr &MI, LexicalScopes &LS)
: Var(MI), Expr(MI.getDebugExpression()), MI(MI),
UVS(MI.getDebugLoc(), LS) {
static_assert((sizeof(Loc) == sizeof(uint64_t)),
@@ -244,18 +243,77 @@ private:
"entry values must be register locations");
}
- /// The constructor for spill locations.
- VarLoc(const MachineInstr &MI, unsigned SpillBase, int SpillOffset,
- LexicalScopes &LS, const MachineInstr &OrigMI)
- : Var(MI), Expr(MI.getDebugExpression()), MI(OrigMI),
- UVS(MI.getDebugLoc(), LS) {
- assert(MI.isDebugValue() && "not a DBG_VALUE");
- assert(MI.getNumOperands() == 4 && "malformed DBG_VALUE");
- Kind = SpillLocKind;
- Loc.SpillLocation = {SpillBase, SpillOffset};
+ /// Take the variable and machine-location in DBG_VALUE MI, and build an
+ /// entry location using the given expression.
+ static VarLoc CreateEntryLoc(const MachineInstr &MI, LexicalScopes &LS,
+ const DIExpression *EntryExpr) {
+ VarLoc VL(MI, LS);
+ VL.Kind = EntryValueKind;
+ VL.Expr = EntryExpr;
+ return VL;
+ }
+
+ /// Copy the register location in DBG_VALUE MI, updating the register to
+ /// be NewReg.
+ static VarLoc CreateCopyLoc(const MachineInstr &MI, LexicalScopes &LS,
+ unsigned NewReg) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Loc.RegNo = NewReg;
+ return VL;
+ }
+
+ /// Take the variable described by DBG_VALUE MI, and create a VarLoc
+ /// locating it in the specified spill location.
+ static VarLoc CreateSpillLoc(const MachineInstr &MI, unsigned SpillBase,
+ int SpillOffset, LexicalScopes &LS) {
+ VarLoc VL(MI, LS);
+ assert(VL.Kind == RegisterKind);
+ VL.Kind = SpillLocKind;
+ VL.Loc.SpillLocation = {SpillBase, SpillOffset};
+ return VL;
}
- // Is the Loc field a constant or constant object?
+ /// Create a DBG_VALUE representing this VarLoc in the given function.
+ /// Copies variable-specific information such as DILocalVariable and
+ /// inlining information from the original DBG_VALUE instruction, which may
+ /// have been several transfers ago.
+ MachineInstr *BuildDbgValue(MachineFunction &MF) const {
+ const DebugLoc &DbgLoc = MI.getDebugLoc();
+ bool Indirect = MI.isIndirectDebugValue();
+ const auto &IID = MI.getDesc();
+ const DILocalVariable *Var = MI.getDebugVariable();
+ const DIExpression *DIExpr = MI.getDebugExpression();
+
+ switch (Kind) {
+ case EntryValueKind:
+ // An entry value is a register location -- but with an updated
+ // expression.
+ return BuildMI(MF, DbgLoc, IID, Indirect, Loc.RegNo, Var, Expr);
+ case RegisterKind:
+ // Register locations are like the source DBG_VALUE, but with the
+ // register number from this VarLoc.
+ return BuildMI(MF, DbgLoc, IID, Indirect, Loc.RegNo, Var, DIExpr);
+ case SpillLocKind: {
+ // Spills are indirect DBG_VALUEs, with a base register and offset.
+ // Use the original DBG_VALUEs expression to build the spilt location
+ // on top of. FIXME: spill locations created before this pass runs
+ // are not recognized, and not handled here.
+ auto *SpillExpr = DIExpression::prepend(
+ DIExpr, DIExpression::ApplyOffset, Loc.SpillLocation.SpillOffset);
+ unsigned Base = Loc.SpillLocation.SpillBase;
+ return BuildMI(MF, DbgLoc, IID, true, Base, Var, SpillExpr);
+ }
+ case ImmediateKind: {
+ MachineOperand MO = MI.getOperand(0);
+ return BuildMI(MF, DbgLoc, IID, Indirect, MO, Var, DIExpr);
+ }
+ case InvalidKind:
+ llvm_unreachable("Tried to produce DBG_VALUE for invalid VarLoc");
+ }
+ }
+
+ /// 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,
@@ -271,7 +329,31 @@ private:
bool dominates(MachineBasicBlock &MBB) const { return UVS.dominates(&MBB); }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void dump() const { MI.dump(); }
+ // TRI can be null.
+ void dump(const TargetRegisterInfo *TRI, raw_ostream &Out = dbgs()) const {
+ dbgs() << "VarLoc(";
+ switch (Kind) {
+ case RegisterKind:
+ case EntryValueKind:
+ dbgs() << printReg(Loc.RegNo, TRI);
+ break;
+ case SpillLocKind:
+ dbgs() << printReg(Loc.SpillLocation.SpillBase, TRI);
+ dbgs() << "[" << Loc.SpillLocation.SpillOffset << "]";
+ break;
+ case ImmediateKind:
+ dbgs() << Loc.Immediate;
+ break;
+ case InvalidKind:
+ llvm_unreachable("Invalid VarLoc in dump method");
+ }
+
+ dbgs() << ", \"" << Var.getVar()->getName() << "\", " << *Expr << ", ";
+ if (Var.getInlinedAt())
+ dbgs() << "!" << Var.getInlinedAt()->getMetadataID() << ")\n";
+ else
+ dbgs() << "(null))\n";
+ }
#endif
bool operator==(const VarLoc &Other) const {
@@ -291,8 +373,8 @@ private:
using VarLocSet = SparseBitVector<>;
using VarLocInMBB = SmallDenseMap<const MachineBasicBlock *, VarLocSet>;
struct TransferDebugPair {
- MachineInstr *TransferInst;
- MachineInstr *DebugInst;
+ MachineInstr *TransferInst; /// Instruction where this transfer occurs.
+ unsigned LocationID; /// Location number for the transfer dest.
};
using TransferMap = SmallVector<TransferDebugPair, 4>;
@@ -561,7 +643,7 @@ void LiveDebugValues::printVarLocInMBB(const MachineFunction &MF,
const VarLoc &VL = VarLocIDs[VLL];
Out << " Var: " << VL.Var.getVar()->getName();
Out << " MI: ";
- VL.dump();
+ VL.dump(TRI, Out);
}
}
Out << "\n";
@@ -624,7 +706,6 @@ void LiveDebugValues::emitEntryValues(MachineInstr &MI,
TransferMap &Transfers,
DebugParamMap &DebugEntryVals,
SparseBitVector<> &KillSet) {
- MachineFunction *MF = MI.getParent()->getParent();
for (unsigned ID : KillSet) {
if (!VarLocIDs[ID].Var.getVar()->isParameter())
continue;
@@ -639,20 +720,12 @@ void LiveDebugValues::emitEntryValues(MachineInstr &MI,
auto ParamDebugInstr = DebugEntryVals[CurrDebugInstr->getDebugVariable()];
DIExpression *NewExpr = DIExpression::prepend(
ParamDebugInstr->getDebugExpression(), DIExpression::EntryValue);
- MachineInstr *EntryValDbgMI =
- BuildMI(*MF, ParamDebugInstr->getDebugLoc(), ParamDebugInstr->getDesc(),
- ParamDebugInstr->isIndirectDebugValue(),
- ParamDebugInstr->getOperand(0).getReg(),
- ParamDebugInstr->getDebugVariable(), NewExpr);
-
- if (ParamDebugInstr->isIndirectDebugValue())
- EntryValDbgMI->getOperand(1).setImm(
- ParamDebugInstr->getOperand(1).getImm());
-
- Transfers.push_back({&MI, EntryValDbgMI});
- VarLoc VL(*EntryValDbgMI, LS);
- unsigned EntryValLocID = VarLocIDs.insert(VL);
- OpenRanges.insert(EntryValLocID, VL.Var);
+
+ VarLoc EntryLoc = VarLoc::CreateEntryLoc(*ParamDebugInstr, LS, NewExpr);
+
+ unsigned EntryValLocID = VarLocIDs.insert(EntryLoc);
+ Transfers.push_back({&MI, EntryValLocID});
+ OpenRanges.insert(EntryValLocID, EntryLoc.Var);
}
}
@@ -666,21 +739,19 @@ void LiveDebugValues::insertTransferDebugPair(
VarLocMap &VarLocIDs, unsigned OldVarID, TransferKind Kind,
unsigned NewReg) {
const MachineInstr *DebugInstr = &VarLocIDs[OldVarID].MI;
- MachineFunction *MF = MI.getParent()->getParent();
- MachineInstr *NewDebugInstr;
auto ProcessVarLoc = [&MI, &OpenRanges, &Transfers, &DebugInstr,
- &VarLocIDs](VarLoc &VL, MachineInstr *NewDebugInstr) {
+ &VarLocIDs](VarLoc &VL) {
unsigned LocId = VarLocIDs.insert(VL);
// Close this variable's previous location range.
DebugVariable V(*DebugInstr);
OpenRanges.erase(V);
+ // Record the new location as an open range, and a postponed transfer
+ // inserting a DBG_VALUE for this location.
OpenRanges.insert(LocId, VL.Var);
- // The newly created DBG_VALUE instruction NewDebugInstr must be inserted
- // after MI. Keep track of the pairing.
- TransferDebugPair MIP = {&MI, NewDebugInstr};
+ TransferDebugPair MIP = {&MI, LocId};
Transfers.push_back(MIP);
};
@@ -692,37 +763,25 @@ void LiveDebugValues::insertTransferDebugPair(
"No register supplied when handling a copy of a debug value");
// Create a DBG_VALUE instruction to describe the Var in its new
// register location.
- NewDebugInstr = BuildMI(
- *MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(),
- DebugInstr->isIndirectDebugValue(), NewReg,
- DebugInstr->getDebugVariable(), DebugInstr->getDebugExpression());
- if (DebugInstr->isIndirectDebugValue())
- NewDebugInstr->getOperand(1).setImm(DebugInstr->getOperand(1).getImm());
- VarLoc VL(*NewDebugInstr, LS);
- ProcessVarLoc(VL, NewDebugInstr);
- LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for register copy: ";
- NewDebugInstr->print(dbgs(), /*IsStandalone*/false,
- /*SkipOpers*/false, /*SkipDebugLoc*/false,
- /*AddNewLine*/true, TII));
+ VarLoc VL = VarLoc::CreateCopyLoc(*DebugInstr, LS, NewReg);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for register copy:";
+ VL.dump(TRI);
+ });
return;
}
case TransferKind::TransferSpill: {
// Create a DBG_VALUE instruction to describe the Var in its spilled
// location.
VarLoc::SpillLoc SpillLocation = extractSpillBaseRegAndOffset(MI);
- auto *SpillExpr = DIExpression::prepend(DebugInstr->getDebugExpression(),
- DIExpression::ApplyOffset,
- SpillLocation.SpillOffset);
- NewDebugInstr = BuildMI(
- *MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(), true,
- SpillLocation.SpillBase, DebugInstr->getDebugVariable(), SpillExpr);
- VarLoc VL(*NewDebugInstr, SpillLocation.SpillBase,
- SpillLocation.SpillOffset, LS, *DebugInstr);
- ProcessVarLoc(VL, NewDebugInstr);
- LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for spill: ";
- NewDebugInstr->print(dbgs(), /*IsStandalone*/false,
- /*SkipOpers*/false, /*SkipDebugLoc*/false,
- /*AddNewLine*/true, TII));
+ VarLoc VL = VarLoc::CreateSpillLoc(*DebugInstr, SpillLocation.SpillBase,
+ SpillLocation.SpillOffset, LS);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for spill:";
+ VL.dump(TRI);
+ });
return;
}
case TransferKind::TransferRestore: {
@@ -732,15 +791,12 @@ void LiveDebugValues::insertTransferDebugPair(
DIBuilder DIB(*const_cast<Function &>(MF->getFunction()).getParent());
// DebugInstr refers to the pre-spill location, therefore we can reuse
// its expression.
- NewDebugInstr = BuildMI(
- *MF, DebugInstr->getDebugLoc(), DebugInstr->getDesc(), false, NewReg,
- DebugInstr->getDebugVariable(), DebugInstr->getDebugExpression());
- VarLoc VL(*NewDebugInstr, LS);
- ProcessVarLoc(VL, NewDebugInstr);
- LLVM_DEBUG(dbgs() << "Creating DBG_VALUE inst for register restore: ";
- NewDebugInstr->print(dbgs(), /*IsStandalone*/false,
- /*SkipOpers*/false, /*SkipDebugLoc*/false,
- /*AddNewLine*/true, TII));
+ VarLoc VL = VarLoc::CreateCopyLoc(*DebugInstr, LS, NewReg);
+ ProcessVarLoc(VL);
+ LLVM_DEBUG({
+ dbgs() << "Creating VarLoc for restore:";
+ VL.dump(TRI);
+ });
return;
}
}
@@ -895,11 +951,9 @@ void LiveDebugValues::transferSpillOrRestoreInst(MachineInstr &MI,
// At this stage, we already know which DBG_VALUEs are for spills and
// where they are located; it's best to fix handle overwrites now.
KillSet.set(ID);
- MachineInstr *NewDebugInstr =
- BuildMI(*MF, VL.MI.getDebugLoc(), VL.MI.getDesc(),
- VL.MI.isIndirectDebugValue(), 0, // $noreg
- VL.MI.getDebugVariable(), VL.MI.getDebugExpression());
- Transfers.push_back({&MI, NewDebugInstr});
+ VarLoc UndefVL = VarLoc::CreateCopyLoc(VL.MI, LS, 0);
+ unsigned UndefLocID = VarLocIDs.insert(UndefVL);
+ Transfers.push_back({&MI, UndefLocID});
}
}
OpenRanges.erase(KillSet, VarLocIDs);
@@ -990,7 +1044,7 @@ bool LiveDebugValues::transferTerminator(MachineBasicBlock *CurMBB,
: OpenRanges.getVarLocs()) {
// Copy OpenRanges to OutLocs, if not already present.
dbgs() << "Add to OutLocs in MBB #" << CurMBB->getNumber() << ": ";
- VarLocIDs[ID].dump();
+ VarLocIDs[ID].dump(TRI);
});
VarLocSet &VLS = OutLocs[CurMBB];
Changed = VLS != OpenRanges.getVarLocs();
@@ -1192,35 +1246,9 @@ void LiveDebugValues::flushPendingLocs(VarLocInMBB &PendingInLocs,
// The ID location is live-in to MBB -- work out what kind of machine
// location it is and create a DBG_VALUE.
const VarLoc &DiffIt = VarLocIDs[ID];
- const MachineInstr *DebugInstr = &DiffIt.MI;
- MachineInstr *MI = nullptr;
-
- if (DiffIt.isConstant()) {
- MachineOperand MO(DebugInstr->getOperand(0));
- MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
- DebugInstr->getDesc(), false, MO,
- DebugInstr->getDebugVariable(),
- DebugInstr->getDebugExpression());
- } else {
- auto *DebugExpr = DebugInstr->getDebugExpression();
- Register Reg = DebugInstr->getOperand(0).getReg();
- bool IsIndirect = DebugInstr->isIndirectDebugValue();
-
- if (DiffIt.Kind == VarLoc::SpillLocKind) {
- // This is is a spilt location; DebugInstr refers to the unspilt
- // location. We need to rebuild the spilt location expression and
- // point the DBG_VALUE at the frame register.
- DebugExpr = DIExpression::prepend(
- DebugInstr->getDebugExpression(), DIExpression::ApplyOffset,
- DiffIt.Loc.SpillLocation.SpillOffset);
- Reg = TRI->getFrameRegister(*DebugInstr->getMF());
- IsIndirect = true;
- }
+ MachineInstr *MI = DiffIt.BuildDbgValue(*MBB.getParent());
+ MBB.insert(MBB.instr_begin(), MI);
- MI = BuildMI(MBB, MBB.instr_begin(), DebugInstr->getDebugLoc(),
- DebugInstr->getDesc(), IsIndirect, Reg,
- DebugInstr->getDebugVariable(), DebugExpr);
- }
(void)MI;
LLVM_DEBUG(dbgs() << "Inserted: "; MI->dump(););
}
@@ -1381,8 +1409,10 @@ bool LiveDebugValues::ExtendRanges(MachineFunction &MF) {
// Add any DBG_VALUE instructions created by location transfers.
for (auto &TR : Transfers) {
- auto *MBB = TR.TransferInst->getParent();
- MBB->insertAfterBundle(TR.TransferInst->getIterator(), TR.DebugInst);
+ MachineBasicBlock *MBB = TR.TransferInst->getParent();
+ const VarLoc &VL = VarLocIDs[TR.LocationID];
+ MachineInstr *MI = VL.BuildDbgValue(MF);
+ MBB->insertAfterBundle(TR.TransferInst->getIterator(), MI);
}
Transfers.clear();
OpenPOWER on IntegriCloud