Skip to content

Commit e64f3cc

Browse files
committed
Reapply "[DebugInfo] Add DWARF emission for DBG_VALUE_LIST"
This reverts commit 429c6ec.
1 parent 987ee6e commit e64f3cc

File tree

10 files changed

+620
-206
lines changed

10 files changed

+620
-206
lines changed

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -918,9 +918,6 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
918918
OS << V->getName();
919919
OS << " <- ";
920920

921-
// The second operand is only an offset if it's an immediate.
922-
bool MemLoc = MI->isIndirectDebugValue();
923-
auto Offset = StackOffset::getFixed(MemLoc ? MI->getOperand(1).getImm() : 0);
924921
const DIExpression *Expr = MI->getDebugExpression();
925922
if (Expr->getNumElements()) {
926923
OS << '[';
@@ -934,56 +931,71 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
934931
}
935932

936933
// Register or immediate value. Register 0 means undef.
937-
if (MI->getDebugOperand(0).isFPImm()) {
938-
APFloat APF = APFloat(MI->getDebugOperand(0).getFPImm()->getValueAPF());
939-
if (MI->getDebugOperand(0).getFPImm()->getType()->isFloatTy()) {
940-
OS << (double)APF.convertToFloat();
941-
} else if (MI->getDebugOperand(0).getFPImm()->getType()->isDoubleTy()) {
942-
OS << APF.convertToDouble();
943-
} else {
944-
// There is no good way to print long double. Convert a copy to
945-
// double. Ah well, it's only a comment.
946-
bool ignored;
947-
APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
948-
&ignored);
949-
OS << "(long double) " << APF.convertToDouble();
934+
for (const MachineOperand &Op : MI->debug_operands()) {
935+
if (&Op != MI->debug_operands().begin())
936+
OS << ", ";
937+
switch (Op.getType()) {
938+
case MachineOperand::MO_FPImmediate: {
939+
APFloat APF = APFloat(Op.getFPImm()->getValueAPF());
940+
if (Op.getFPImm()->getType()->isFloatTy()) {
941+
OS << (double)APF.convertToFloat();
942+
} else if (Op.getFPImm()->getType()->isDoubleTy()) {
943+
OS << APF.convertToDouble();
944+
} else {
945+
// There is no good way to print long double. Convert a copy to
946+
// double. Ah well, it's only a comment.
947+
bool ignored;
948+
APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
949+
&ignored);
950+
OS << "(long double) " << APF.convertToDouble();
951+
}
952+
break;
950953
}
951-
} else if (MI->getDebugOperand(0).isImm()) {
952-
OS << MI->getDebugOperand(0).getImm();
953-
} else if (MI->getDebugOperand(0).isCImm()) {
954-
MI->getDebugOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
955-
} else if (MI->getDebugOperand(0).isTargetIndex()) {
956-
auto Op = MI->getDebugOperand(0);
957-
OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
958-
// NOTE: Want this comment at start of line, don't emit with AddComment.
959-
AP.OutStreamer->emitRawComment(OS.str());
960-
return true;
961-
} else {
962-
Register Reg;
963-
if (MI->getDebugOperand(0).isReg()) {
964-
Reg = MI->getDebugOperand(0).getReg();
965-
} else {
966-
assert(MI->getDebugOperand(0).isFI() && "Unknown operand type");
967-
const TargetFrameLowering *TFI = AP.MF->getSubtarget().getFrameLowering();
968-
Offset += TFI->getFrameIndexReference(
969-
*AP.MF, MI->getDebugOperand(0).getIndex(), Reg);
970-
MemLoc = true;
954+
case MachineOperand::MO_Immediate: {
955+
OS << Op.getImm();
956+
break;
957+
}
958+
case MachineOperand::MO_CImmediate: {
959+
Op.getCImm()->getValue().print(OS, false /*isSigned*/);
960+
break;
971961
}
972-
if (Reg == 0) {
973-
// Suppress offset, it is not meaningful here.
974-
OS << "undef";
962+
case MachineOperand::MO_TargetIndex: {
963+
OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
975964
// NOTE: Want this comment at start of line, don't emit with AddComment.
976965
AP.OutStreamer->emitRawComment(OS.str());
977-
return true;
966+
break;
967+
}
968+
case MachineOperand::MO_Register:
969+
case MachineOperand::MO_FrameIndex: {
970+
Register Reg;
971+
Optional<StackOffset> Offset;
972+
if (Op.isReg()) {
973+
Reg = Op.getReg();
974+
} else {
975+
const TargetFrameLowering *TFI =
976+
AP.MF->getSubtarget().getFrameLowering();
977+
Offset = TFI->getFrameIndexReference(*AP.MF, Op.getIndex(), Reg);
978+
}
979+
if (!Reg) {
980+
// Suppress offset, it is not meaningful here.
981+
OS << "undef";
982+
break;
983+
}
984+
// The second operand is only an offset if it's an immediate.
985+
if (MI->isIndirectDebugValue())
986+
Offset = StackOffset::getFixed(MI->getDebugOffset().getImm());
987+
if (Offset)
988+
OS << '[';
989+
OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
990+
if (Offset)
991+
OS << '+' << Offset->getFixed() << ']';
992+
break;
993+
}
994+
default:
995+
llvm_unreachable("Unknown operand type");
978996
}
979-
if (MemLoc)
980-
OS << '[';
981-
OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
982997
}
983998

984-
if (MemLoc)
985-
OS << '+' << Offset.getFixed() << ']';
986-
987999
// NOTE: Want this comment at start of line, don't emit with AddComment.
9881000
AP.OutStreamer->emitRawComment(OS.str());
9891001
return true;

llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,6 @@ namespace {
3737
using EntryIndex = DbgValueHistoryMap::EntryIndex;
3838
}
3939

40-
// If @MI is a DBG_VALUE with debug value described by a
41-
// defined register, returns the number of this register.
42-
// In the other case, returns 0.
43-
static Register isDescribedByReg(const MachineInstr &MI) {
44-
assert(MI.isDebugValue());
45-
assert(MI.getNumOperands() == 4);
46-
// If the location of variable is an entry value (DW_OP_LLVM_entry_value)
47-
// do not consider it as a register location.
48-
if (MI.getDebugExpression()->isEntryValue())
49-
return 0;
50-
// If location of variable is described using a register (directly or
51-
// indirectly), this register is always a first operand.
52-
return MI.getDebugOperand(0).isReg() ? MI.getDebugOperand(0).getReg()
53-
: Register();
54-
}
55-
5640
void InstructionOrdering::initialize(const MachineFunction &MF) {
5741
// We give meta instructions the same ordinal as the preceding instruction
5842
// because this class is written for the task of comparing positions of
@@ -333,24 +317,44 @@ static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
333317
}
334318

335319
/// Create a clobbering entry and end all open debug value entries
336-
/// for \p Var that are described by \p RegNo using that entry.
320+
/// for \p Var that are described by \p RegNo using that entry. Inserts into \p
321+
/// FellowRegisters the set of Registers that were also used to describe \p Var
322+
/// alongside \p RegNo.
337323
static void clobberRegEntries(InlinedEntity Var, unsigned RegNo,
338324
const MachineInstr &ClobberingInstr,
339325
DbgValueEntriesMap &LiveEntries,
340-
DbgValueHistoryMap &HistMap) {
326+
DbgValueHistoryMap &HistMap,
327+
SmallVectorImpl<Register> &FellowRegisters) {
341328
EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr);
342-
343329
// Close all entries whose values are described by the register.
344330
SmallVector<EntryIndex, 4> IndicesToErase;
331+
// If a given register appears in a live DBG_VALUE_LIST for Var alongside the
332+
// clobbered register, and never appears in a live DBG_VALUE* for Var without
333+
// the clobbered register, then it is no longer linked to the variable.
334+
SmallSet<Register, 4> MaybeRemovedRegisters;
335+
SmallSet<Register, 4> KeepRegisters;
345336
for (auto Index : LiveEntries[Var]) {
346337
auto &Entry = HistMap.getEntry(Var, Index);
347338
assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
348-
if (isDescribedByReg(*Entry.getInstr()) == RegNo) {
339+
if (Entry.getInstr()->isDebugEntryValue())
340+
continue;
341+
if (Entry.getInstr()->hasDebugOperandForReg(RegNo)) {
349342
IndicesToErase.push_back(Index);
350343
Entry.endEntry(ClobberIndex);
344+
for (auto &MO : Entry.getInstr()->debug_operands())
345+
if (MO.isReg() && MO.getReg() && MO.getReg() != RegNo)
346+
MaybeRemovedRegisters.insert(MO.getReg());
347+
} else {
348+
for (auto &MO : Entry.getInstr()->debug_operands())
349+
if (MO.isReg() && MO.getReg())
350+
KeepRegisters.insert(MO.getReg());
351351
}
352352
}
353353

354+
for (Register Reg : MaybeRemovedRegisters)
355+
if (!KeepRegisters.contains(Reg))
356+
FellowRegisters.push_back(Reg);
357+
354358
// Drop all entries that have ended.
355359
for (auto Index : IndicesToErase)
356360
LiveEntries[Var].erase(Index);
@@ -378,17 +382,24 @@ static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV,
378382
IndicesToErase.push_back(Index);
379383
Entry.endEntry(NewIndex);
380384
}
381-
if (Register Reg = isDescribedByReg(DV))
382-
TrackedRegs[Reg] |= !Overlaps;
385+
if (!DV.isDebugEntryValue())
386+
for (const MachineOperand &Op : DV.debug_operands())
387+
if (Op.isReg() && Op.getReg())
388+
TrackedRegs[Op.getReg()] |= !Overlaps;
383389
}
384390

385391
// If the new debug value is described by a register, add tracking of
386392
// that register if it is not already tracked.
387-
if (Register NewReg = isDescribedByReg(DV)) {
388-
if (!TrackedRegs.count(NewReg))
389-
addRegDescribedVar(RegVars, NewReg, Var);
390-
LiveEntries[Var].insert(NewIndex);
391-
TrackedRegs[NewReg] = true;
393+
if (!DV.isDebugEntryValue()) {
394+
for (const MachineOperand &Op : DV.debug_operands()) {
395+
if (Op.isReg() && Op.getReg()) {
396+
Register NewReg = Op.getReg();
397+
if (!TrackedRegs.count(NewReg))
398+
addRegDescribedVar(RegVars, NewReg, Var);
399+
LiveEntries[Var].insert(NewIndex);
400+
TrackedRegs[NewReg] = true;
401+
}
402+
}
392403
}
393404

394405
// Drop tracking of registers that are no longer used.
@@ -411,9 +422,16 @@ static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
411422
DbgValueEntriesMap &LiveEntries,
412423
const MachineInstr &ClobberingInstr) {
413424
// Iterate over all variables described by this register and add this
414-
// instruction to their history, clobbering it.
415-
for (const auto &Var : I->second)
416-
clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap);
425+
// instruction to their history, clobbering it. All registers that also
426+
// describe the clobbered variables (i.e. in variadic debug values) will have
427+
// those Variables removed from their DescribedVars.
428+
for (const auto &Var : I->second) {
429+
SmallVector<Register, 4> FellowRegisters;
430+
clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap,
431+
FellowRegisters);
432+
for (Register RegNo : FellowRegisters)
433+
dropRegDescribedVar(RegVars, RegNo, Var);
434+
}
417435
RegVars.erase(I);
418436
}
419437

llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ Optional<DbgVariableLocation>
3535
DbgVariableLocation::extractFromMachineInstruction(
3636
const MachineInstr &Instruction) {
3737
DbgVariableLocation Location;
38-
if (!Instruction.isDebugValue())
38+
// Variables calculated from multiple locations can't be represented here.
39+
if (Instruction.getNumDebugOperands() != 1)
3940
return None;
4041
if (!Instruction.getDebugOperand(0).isReg())
4142
return None;
@@ -46,6 +47,15 @@ DbgVariableLocation::extractFromMachineInstruction(
4647
int64_t Offset = 0;
4748
const DIExpression *DIExpr = Instruction.getDebugExpression();
4849
auto Op = DIExpr->expr_op_begin();
50+
// We can handle a DBG_VALUE_LIST iff it has exactly one location operand that
51+
// appears exactly once at the start of the expression.
52+
if (Instruction.isDebugValueList()) {
53+
if (Instruction.getNumDebugOperands() == 1 &&
54+
Op->getOp() == dwarf::DW_OP_LLVM_arg)
55+
++Op;
56+
else
57+
return None;
58+
}
4959
while (Op != DIExpr->expr_op_end()) {
5060
switch (Op->getOp()) {
5161
case dwarf::DW_OP_constu: {
@@ -261,7 +271,8 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
261271
continue;
262272

263273
auto IsDescribedByReg = [](const MachineInstr *MI) {
264-
return MI->getDebugOperand(0).isReg() && MI->getDebugOperand(0).getReg();
274+
return any_of(MI->debug_operands(),
275+
[](auto &MO) { return MO.isReg() && MO.getReg(); });
265276
};
266277

267278
// The first mention of a function argument gets the CurrentFnBegin label,

0 commit comments

Comments
 (0)