aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp110
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h17
2 files changed, 119 insertions, 8 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 10061e1907..c4c9d3f2b3 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -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());
+}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index b6b28fa7e9..35bddee41b 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -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);