forked from OSchip/llvm-project
Add some first skeleton work for the DWARF5 Fission proposal. Emit
part of the compile unit CU and start separating out information into the various sections that will be pulled out later. WIP. llvm-svn: 169061
This commit is contained in:
parent
bb1e98318f
commit
9c2ecd93d0
|
@ -153,7 +153,7 @@ DIType DbgVariable::getType() const {
|
|||
} // end llvm namespace
|
||||
|
||||
DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
|
||||
: Asm(A), MMI(Asm->MMI), FirstCU(0),
|
||||
: Asm(A), MMI(Asm->MMI), FirstCU(0), FissionCU(0),
|
||||
AbbreviationsSet(InitAbbreviationsSetSize),
|
||||
SourceIdMap(DIEValueAllocator), StringPool(DIEValueAllocator),
|
||||
PrevLabel(NULL) {
|
||||
|
@ -650,6 +650,9 @@ CompileUnit *DwarfDebug::constructCompileUnit(const MDNode *N) {
|
|||
|
||||
if (!FirstCU)
|
||||
FirstCU = NewCU;
|
||||
if (useDwarfFission() && !FissionCU)
|
||||
FissionCU = constructFissionCU(N);
|
||||
|
||||
CUMap.insert(std::make_pair(N, NewCU));
|
||||
return NewCU;
|
||||
}
|
||||
|
@ -927,8 +930,9 @@ void DwarfDebug::endModule() {
|
|||
// TODO: Fill this in for Fission sections and separate
|
||||
// out information into new sections.
|
||||
|
||||
// Emit all the DIEs into a debug info section.
|
||||
// Emit the debug info section and compile units.
|
||||
emitDebugInfo();
|
||||
emitDebugInfoDWO();
|
||||
|
||||
// Corresponding abbreviations into a abbrev section.
|
||||
emitAbbreviations();
|
||||
|
@ -975,7 +979,9 @@ void DwarfDebug::endModule() {
|
|||
for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
|
||||
E = CUMap.end(); I != E; ++I)
|
||||
delete I->second;
|
||||
FirstCU = NULL; // Reset for the next Module, if any.
|
||||
// Reset these for the next Module if we have one.
|
||||
FirstCU = NULL;
|
||||
FissionCU = NULL;
|
||||
}
|
||||
|
||||
// Find abstract variable, if any, associated with Var.
|
||||
|
@ -1665,6 +1671,15 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset) {
|
|||
|
||||
// Compute the size and offset of all the DIEs.
|
||||
void DwarfDebug::computeSizeAndOffsets() {
|
||||
if (FissionCU) {
|
||||
unsigned Offset =
|
||||
sizeof(int32_t) + // Length of Compilation Unit Info
|
||||
sizeof(int16_t) + // DWARF version number
|
||||
sizeof(int32_t) + // Offset Into Abbrev. Section
|
||||
sizeof(int8_t); // Pointer Size (in bytes)
|
||||
|
||||
computeSizeAndOffset(FissionCU->getCUDie(), Offset);
|
||||
}
|
||||
for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
|
||||
E = CUMap.end(); I != E; ++I) {
|
||||
// Compute size of compile unit header.
|
||||
|
@ -1795,11 +1810,8 @@ void DwarfDebug::emitDIE(DIE *Die) {
|
|||
}
|
||||
}
|
||||
|
||||
// Emit the debug info section.
|
||||
void DwarfDebug::emitDebugInfo() {
|
||||
// Start debug info section.
|
||||
Asm->OutStreamer.SwitchSection(
|
||||
Asm->getObjFileLowering().getDwarfInfoSection());
|
||||
void DwarfDebug::emitCompileUnits(const MCSection *Section) {
|
||||
Asm->OutStreamer.SwitchSection(Section);
|
||||
for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
|
||||
E = CUMap.end(); I != E; ++I) {
|
||||
CompileUnit *TheCU = I->second;
|
||||
|
@ -1830,6 +1842,14 @@ void DwarfDebug::emitDebugInfo() {
|
|||
}
|
||||
}
|
||||
|
||||
// Emit the debug info section.
|
||||
void DwarfDebug::emitDebugInfo() {
|
||||
if (!useDwarfFission())
|
||||
emitCompileUnits(Asm->getObjFileLowering().getDwarfInfoSection());
|
||||
else
|
||||
emitFissionSkeletonCU(Asm->getObjFileLowering().getDwarfInfoSection());
|
||||
}
|
||||
|
||||
// Emit the abbreviation section.
|
||||
void DwarfDebug::emitAbbreviations() {
|
||||
// Check to see if it is worth the effort.
|
||||
|
@ -2286,3 +2306,77 @@ void DwarfDebug::emitDebugInlineInfo() {
|
|||
|
||||
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
|
||||
}
|
||||
|
||||
// DWARF5 Experimental Fission emitters.
|
||||
|
||||
// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_stmt_list,
|
||||
// DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_dwo_name, DW_AT_dwo_id,
|
||||
// DW_AT_ranges_base, DW_AT_addr_base. If DW_AT_ranges is present,
|
||||
// DW_AT_low_pc and DW_AT_high_pc are not used, and vice versa.
|
||||
CompileUnit *DwarfDebug::constructFissionCU(const MDNode *N) {
|
||||
DICompileUnit DIUnit(N);
|
||||
StringRef FN = DIUnit.getFilename();
|
||||
CompilationDir = DIUnit.getDirectory();
|
||||
unsigned ID = getOrCreateSourceID(FN, CompilationDir);
|
||||
|
||||
DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
|
||||
CompileUnit *NewCU = new CompileUnit(ID, DIUnit.getLanguage(), Die,
|
||||
Asm, this);
|
||||
// FIXME: This should be the .dwo file.
|
||||
NewCU->addString(Die, dwarf::DW_AT_GNU_dwo_name, FN);
|
||||
|
||||
// FIXME: We also need DW_AT_addr_base and DW_AT_dwo_id.
|
||||
|
||||
// 2.17.1 requires that we use DW_AT_low_pc for a single entry point
|
||||
// into an entity.
|
||||
NewCU->addUInt(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0);
|
||||
// DW_AT_stmt_list is a offset of line number information for this
|
||||
// compile unit in debug_line section.
|
||||
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
|
||||
NewCU->addLabel(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4,
|
||||
Asm->GetTempSymbol("section_line"));
|
||||
else
|
||||
NewCU->addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
|
||||
|
||||
if (!CompilationDir.empty())
|
||||
NewCU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
|
||||
|
||||
return NewCU;
|
||||
}
|
||||
|
||||
void DwarfDebug::emitFissionSkeletonCU(const MCSection *Section) {
|
||||
Asm->OutStreamer.SwitchSection(Section);
|
||||
DIE *Die = FissionCU->getCUDie();
|
||||
|
||||
// Emit the compile units header.
|
||||
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("skel_info_begin",
|
||||
FissionCU->getID()));
|
||||
|
||||
// Emit size of content not including length itself
|
||||
unsigned ContentSize = Die->getSize() +
|
||||
sizeof(int16_t) + // DWARF version number
|
||||
sizeof(int32_t) + // Offset Into Abbrev. Section
|
||||
sizeof(int8_t); // Pointer Size (in bytes)
|
||||
|
||||
Asm->OutStreamer.AddComment("Length of Compilation Unit Info");
|
||||
Asm->EmitInt32(ContentSize);
|
||||
Asm->OutStreamer.AddComment("DWARF version number");
|
||||
Asm->EmitInt16(dwarf::DWARF_VERSION);
|
||||
Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
|
||||
Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
|
||||
DwarfAbbrevSectionSym);
|
||||
Asm->OutStreamer.AddComment("Address Size (in bytes)");
|
||||
Asm->EmitInt8(Asm->getDataLayout().getPointerSize());
|
||||
|
||||
emitDIE(Die);
|
||||
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("skel_info_end", FissionCU->getID()));
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Emit the .debug_info.dwo section for fission. This contains the compile
|
||||
// units that would normally be in debug_info.
|
||||
void DwarfDebug::emitDebugInfoDWO() {
|
||||
assert(useDwarfFission() && "Got fission?");
|
||||
emitCompileUnits(Asm->getObjFileLowering().getDwarfInfoDWOSection());
|
||||
}
|
||||
|
|
|
@ -205,6 +205,9 @@ class DwarfDebug {
|
|||
|
||||
CompileUnit *FirstCU;
|
||||
|
||||
// The CU left in the original object file for Fission debug info.
|
||||
CompileUnit *FissionCU;
|
||||
|
||||
// Maps MDNode with its corresponding CompileUnit.
|
||||
DenseMap <const MDNode *, CompileUnit *> CUMap;
|
||||
|
||||
|
@ -369,6 +372,9 @@ private:
|
|||
/// open.
|
||||
void endSections();
|
||||
|
||||
/// \brief Emit all of the compile units to the target section.
|
||||
void emitCompileUnits(const MCSection *);
|
||||
|
||||
/// \brief Emit the debug info section.
|
||||
void emitDebugInfo();
|
||||
|
||||
|
@ -413,6 +419,17 @@ private:
|
|||
/// \brief Emit inline info using custom format.
|
||||
void emitDebugInlineInfo();
|
||||
|
||||
/// DWARF 5 Experimental Fission Emitters
|
||||
|
||||
/// \brief Construct the fission compile unit for the debug info section.
|
||||
CompileUnit *constructFissionCU(const MDNode *);
|
||||
|
||||
/// \brief Emit the fission debug info section.
|
||||
void emitFissionSkeletonCU(const MCSection *);
|
||||
|
||||
/// \brief Emit the debug info dwo section.
|
||||
void emitDebugInfoDWO();
|
||||
|
||||
/// \brief Create new CompileUnit for the given metadata node with tag
|
||||
/// DW_TAG_compile_unit.
|
||||
CompileUnit *constructCompileUnit(const MDNode *N);
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
; RUN: llc -dwarf-fission=Enable -O0 %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o %t
|
||||
; RUN: llvm-dwarfdump %t | FileCheck %s
|
||||
|
||||
@a = common global i32 0, align 4
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
|
||||
!0 = metadata !{i32 786449, i32 0, i32 12, metadata !"baz.c", metadata !"/usr/local/google/home/echristo/tmp", metadata !"clang version 3.3 (trunk 169021) (llvm/trunk 169020)", i1 true, i1 false, metadata !"", i32 0, metadata !1, metadata !1, metadata !1, metadata !3} ; [ DW_TAG_compile_unit ] [/usr/local/google/home/echristo/tmp/baz.c] [DW_LANG_C99]
|
||||
!1 = metadata !{metadata !2}
|
||||
!2 = metadata !{i32 0}
|
||||
!3 = metadata !{metadata !4}
|
||||
!4 = metadata !{metadata !5}
|
||||
!5 = metadata !{i32 786484, i32 0, null, metadata !"a", metadata !"a", metadata !"", metadata !6, i32 1, metadata !7, i32 0, i32 1, i32* @a} ; [ DW_TAG_variable ] [a] [line 1] [def]
|
||||
!6 = metadata !{i32 786473, metadata !"baz.c", metadata !"/usr/local/google/home/echristo/tmp", null} ; [ DW_TAG_file_type ]
|
||||
!7 = metadata !{i32 786468, null, metadata !"int", null, i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed]
|
||||
|
||||
; Check that the skeleton compile unit contains the proper attributes:
|
||||
; This DIE has the following attributes: DW_AT_comp_dir, DW_AT_stmt_list,
|
||||
; DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_dwo_name, DW_AT_dwo_id,
|
||||
; DW_AT_ranges_base, DW_AT_addr_base.
|
||||
|
||||
; CHECK: DW_TAG_compile_unit [1]
|
||||
; CHECK: DW_AT_GNU_dwo_name [DW_FORM_strp] ( .debug_str[0x00000035] = "baz.c")
|
||||
; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000)
|
||||
; CHECK: DW_AT_stmt_list [DW_FORM_data4] (0x00000000)
|
||||
; CHECK: DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000003b] = "/usr/local/google/home/echristo/tmp")
|
Loading…
Reference in New Issue