Skip to content

Commit b9973f8

Browse files
committed
Reland "[DwarfDebug] Dump call site debug info"
The build failure found after the rL365467 has been resolved. Differential Revision: https://reviews.llvm.org/D60716 llvm-svn: 367446
1 parent f7ef705 commit b9973f8

23 files changed

+1143
-52
lines changed

llvm/docs/LangRef.rst

+4
Original file line numberDiff line numberDiff line change
@@ -4769,6 +4769,10 @@ The current supported opcode vocabulary is limited:
47694769
``DW_OP_entry_value`` may also appear after the ``AsmPrinter`` pass when
47704770
a call site parameter value (``DW_AT_call_site_parameter_value``)
47714771
is represented as entry value of the parameter.
4772+
- ``DW_OP_breg`` (or ``DW_OP_bregx``) represents a content on the provided
4773+
signed offset of the specified register. The opcode is only generated by the
4774+
``AsmPrinter`` pass to describe call site parameter value which requires an
4775+
expression over two registers.
47724776

47734777
DWARF specifies three kinds of simple location descriptions: Register, memory,
47744778
and implicit location descriptions. Note that a location description is

llvm/include/llvm/CodeGen/TargetInstrInfo.h

+7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ class TargetSubtargetInfo;
6060

6161
template <class T> class SmallVectorImpl;
6262

63+
using ParamLoadedValue = std::pair<const MachineOperand*, DIExpression*>;
64+
6365
//---------------------------------------------------------------------------
6466
///
6567
/// TargetInstrInfo - Interface to description of machine instruction set
@@ -1691,6 +1693,11 @@ class TargetInstrInfo : public MCInstrInfo {
16911693
return false;
16921694
}
16931695

1696+
/// Produce the expression describing the \p MI loading a value into
1697+
/// the parameter's forwarding register.
1698+
virtual Optional<ParamLoadedValue>
1699+
describeLoadedValue(const MachineInstr &MI) const;
1700+
16941701
private:
16951702
unsigned CallFrameSetupOpcode, CallFrameDestroyOpcode;
16961703
unsigned CatchRetOpcode;

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

+5
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,11 @@ class TargetRegisterInfo : public MCRegisterInfo {
535535
return false;
536536
}
537537

538+
/// This is a wrapper around getCallPreservedMask().
539+
/// Return true if the register is preserved after the call.
540+
virtual bool isCalleeSavedPhysReg(unsigned PhysReg,
541+
const MachineFunction &MF) const;
542+
538543
/// Prior to adding the live-out mask to a stackmap or patchpoint
539544
/// instruction, provide the target the opportunity to adjust it (mainly to
540545
/// remove pseudo-registers that should be ignored).

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

+91-17
Original file line numberDiff line numberDiff line change
@@ -892,32 +892,106 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
892892
ContextCU->addDIEEntry(*AbsDef, dwarf::DW_AT_object_pointer, *ObjectPointer);
893893
}
894894

895-
DIE &DwarfCompileUnit::constructCallSiteEntryDIE(DIE &ScopeDIE,
896-
const DISubprogram &CalleeSP,
897-
bool IsTail,
898-
const MCExpr *PCOffset) {
899-
// Insert a call site entry DIE within ScopeDIE.
900-
DIE &CallSiteDIE =
901-
createAndAddDIE(dwarf::DW_TAG_call_site, ScopeDIE, nullptr);
895+
dwarf::Tag DwarfCompileUnit::getDwarf5OrGNUCallSiteTag(dwarf::Tag Tag) const {
896+
bool ApplyGNUExtensions = DD->getDwarfVersion() == 4 && DD->tuneForGDB();
897+
if (!ApplyGNUExtensions)
898+
return Tag;
899+
switch (Tag) {
900+
case dwarf::DW_TAG_call_site:
901+
return dwarf::DW_TAG_GNU_call_site;
902+
case dwarf::DW_TAG_call_site_parameter:
903+
return dwarf::DW_TAG_GNU_call_site_parameter;
904+
default:
905+
llvm_unreachable("unhandled call site tag");
906+
}
907+
}
902908

903-
// For the purposes of showing tail call frames in backtraces, a key piece of
904-
// information is DW_AT_call_origin, a pointer to the callee DIE.
905-
DIE *CalleeDIE = getOrCreateSubprogramDIE(&CalleeSP);
906-
assert(CalleeDIE && "Could not create DIE for call site entry origin");
907-
addDIEEntry(CallSiteDIE, dwarf::DW_AT_call_origin, *CalleeDIE);
909+
dwarf::Attribute
910+
DwarfCompileUnit::getDwarf5OrGNUCallSiteAttr(dwarf::Attribute Attr) const {
911+
bool ApplyGNUExtensions = DD->getDwarfVersion() == 4 && DD->tuneForGDB();
912+
if (!ApplyGNUExtensions)
913+
return Attr;
914+
switch (Attr) {
915+
case dwarf::DW_AT_call_all_calls:
916+
return dwarf::DW_AT_GNU_all_call_sites;
917+
case dwarf::DW_AT_call_target:
918+
return dwarf::DW_AT_GNU_call_site_target;
919+
case dwarf::DW_AT_call_origin:
920+
return dwarf::DW_AT_abstract_origin;
921+
case dwarf::DW_AT_call_pc:
922+
return dwarf::DW_AT_low_pc;
923+
case dwarf::DW_AT_call_value:
924+
return dwarf::DW_AT_GNU_call_site_value;
925+
case dwarf::DW_AT_call_tail_call:
926+
return dwarf::DW_AT_GNU_tail_call;
927+
default:
928+
llvm_unreachable("unhandled call site attribute");
929+
}
930+
}
908931

909-
if (IsTail) {
910-
// Attach DW_AT_call_tail_call to tail calls for standards compliance.
911-
addFlag(CallSiteDIE, dwarf::DW_AT_call_tail_call);
932+
DIE &DwarfCompileUnit::constructCallSiteEntryDIE(
933+
DIE &ScopeDIE, const DISubprogram *CalleeSP, bool IsTail,
934+
const MCSymbol *PCAddr, const MCExpr *PCOffset, unsigned CallReg) {
935+
// Insert a call site entry DIE within ScopeDIE.
936+
DIE &CallSiteDIE = createAndAddDIE(
937+
getDwarf5OrGNUCallSiteTag(dwarf::DW_TAG_call_site), ScopeDIE, nullptr);
938+
939+
if (CallReg) {
940+
// Indirect call.
941+
addAddress(CallSiteDIE,
942+
getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_target),
943+
MachineLocation(CallReg));
912944
} else {
913-
// Attach the return PC to allow the debugger to disambiguate call paths
914-
// from one function to another.
945+
DIE *CalleeDIE = getOrCreateSubprogramDIE(CalleeSP);
946+
assert(CalleeDIE && "Could not create DIE for call site entry origin");
947+
addDIEEntry(CallSiteDIE,
948+
getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_origin),
949+
*CalleeDIE);
950+
}
951+
952+
if (IsTail)
953+
// Attach DW_AT_call_tail_call to tail calls for standards compliance.
954+
addFlag(CallSiteDIE,
955+
getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_tail_call));
956+
957+
// Attach the return PC to allow the debugger to disambiguate call paths
958+
// from one function to another.
959+
if (DD->getDwarfVersion() == 4 && DD->tuneForGDB()) {
960+
assert(PCAddr && "Missing PC information for a call");
961+
addLabelAddress(CallSiteDIE, dwarf::DW_AT_low_pc, PCAddr);
962+
} else if (!IsTail || DD->tuneForGDB()) {
915963
assert(PCOffset && "Missing return PC information for a call");
916964
addAddressExpr(CallSiteDIE, dwarf::DW_AT_call_return_pc, PCOffset);
917965
}
966+
918967
return CallSiteDIE;
919968
}
920969

970+
void DwarfCompileUnit::constructCallSiteParmEntryDIEs(
971+
DIE &CallSiteDIE, SmallVector<DbgCallSiteParam, 4> &Params) {
972+
for (const auto &Param : Params) {
973+
unsigned Register = Param.getRegister();
974+
auto CallSiteDieParam =
975+
DIE::get(DIEValueAllocator,
976+
getDwarf5OrGNUCallSiteTag(dwarf::DW_TAG_call_site_parameter));
977+
insertDIE(CallSiteDieParam);
978+
addAddress(*CallSiteDieParam, dwarf::DW_AT_location,
979+
MachineLocation(Register));
980+
981+
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
982+
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
983+
DwarfExpr.setCallSiteParamValueFlag();
984+
985+
DwarfDebug::emitDebugLocValue(*Asm, nullptr, Param.getValue(), DwarfExpr);
986+
987+
addBlock(*CallSiteDieParam,
988+
getDwarf5OrGNUCallSiteAttr(dwarf::DW_AT_call_value),
989+
DwarfExpr.finalize());
990+
991+
CallSiteDIE.addChild(CallSiteDieParam);
992+
}
993+
}
994+
921995
DIE *DwarfCompileUnit::constructImportedEntityDIE(
922996
const DIImportedEntity *Module) {
923997
DIE *IMDie = DIE::get(DIEValueAllocator, (dwarf::Tag)Module->getTag());

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h

+25-4
Original file line numberDiff line numberDiff line change
@@ -227,12 +227,33 @@ class DwarfCompileUnit final : public DwarfUnit {
227227

228228
void constructAbstractSubprogramScopeDIE(LexicalScope *Scope);
229229

230+
/// This takes the official DWARF 5 tag and returns the appropriate
231+
/// GNU tag if needed.
232+
dwarf::Tag getDwarf5OrGNUCallSiteTag(dwarf::Tag Tag) const;
233+
/// This takes the official DWARF 5 attribute and returns the appropriate
234+
/// GNU attribute if needed.
235+
dwarf::Attribute getDwarf5OrGNUCallSiteAttr(dwarf::Attribute Attr) const;
236+
230237
/// Construct a call site entry DIE describing a call within \p Scope to a
231-
/// callee described by \p CalleeSP. \p IsTail specifies whether the call is
232-
/// a tail call. \p PCOffset must be non-zero for non-tail calls or be the
238+
/// callee described by \p CalleeSP.
239+
/// \p IsTail specifies whether the call is a tail call.
240+
/// \p PCAddr (used for GDB + DWARF 4 tuning) points to the PC value after
241+
/// the call instruction.
242+
/// \p PCOffset (used for cases other than GDB + DWARF 4 tuning) must be
243+
/// non-zero for non-tail calls (in the case of non-gdb tuning, since for
244+
/// GDB + DWARF 5 tuning we still generate PC info for tail calls) or be the
233245
/// function-local offset to PC value after the call instruction.
234-
DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram &CalleeSP,
235-
bool IsTail, const MCExpr *PCOffset);
246+
/// \p CallReg is a register location for an indirect call. For direct calls
247+
/// the \p CallReg is set to 0.
248+
DIE &constructCallSiteEntryDIE(DIE &ScopeDIE, const DISubprogram *CalleeSP,
249+
bool IsTail, const MCSymbol *PCAddr,
250+
const MCExpr *PCOffset, unsigned CallReg);
251+
/// Construct call site parameter DIEs for the \p CallSiteDIE. The \p Params
252+
/// were collected by the \ref collectCallSiteParameters.
253+
/// Note: The order of parameters does not matter, since debuggers recognize
254+
/// call site parameters by the DW_AT_location attribute.
255+
void constructCallSiteParmEntryDIEs(DIE &CallSiteDIE,
256+
SmallVector<DbgCallSiteParam, 4> &Params);
236257

237258
/// Construct import_module DIE.
238259
DIE *constructImportedEntityDIE(const DIImportedEntity *Module);

0 commit comments

Comments
 (0)