Improved macro emission in dwarf.

Changed emitting offset of macinfo entry into compiler unit DIE to use "addSectionLabel" method rather than explicitly calculating size/offset of macro entry.

Differential Revision: http://reviews.llvm.org/D16292

llvm-svn: 259358
This commit is contained in:
Amjad Aboud 2016-02-01 14:09:41 +00:00
parent c578d67407
commit 8bbce8ad8e
7 changed files with 42 additions and 124 deletions

View File

@ -29,48 +29,6 @@ class MCSymbol;
class raw_ostream;
class DwarfTypeUnit;
// AsmStreamerBase - A base abstract interface class defines methods that
// can be implemented to stream objects or can be implemented to
// calculate the size of the streamed objects.
// The derived classes will use an AsmPrinter to implement the methods.
//
// TODO: complete this interface and use it to merge EmitValue and SizeOf
// methods in the DIE classes below.
class AsmStreamerBase {
protected:
const AsmPrinter *AP;
AsmStreamerBase(const AsmPrinter *AP) : AP(AP) {}
public:
virtual ~AsmStreamerBase() {}
virtual unsigned emitULEB128(uint64_t Value, const char *Desc = nullptr,
unsigned PadTo = 0) = 0;
virtual unsigned emitInt8(unsigned char Value) = 0;
virtual unsigned emitBytes(StringRef Data) = 0;
};
/// EmittingAsmStreamer - Implements AbstractAsmStreamer to stream objects.
/// Notice that the return value is not the actual size of the streamed object.
/// For size calculation use SizeReporterAsmStreamer.
class EmittingAsmStreamer : public AsmStreamerBase {
public:
EmittingAsmStreamer(const AsmPrinter *AP) : AsmStreamerBase(AP) {}
unsigned emitULEB128(uint64_t Value, const char *Desc = nullptr,
unsigned PadTo = 0) override;
unsigned emitInt8(unsigned char Value) override;
unsigned emitBytes(StringRef Data) override;
};
/// SizeReporterAsmStreamer - Only reports the size of the streamed objects.
class SizeReporterAsmStreamer : public AsmStreamerBase {
public:
SizeReporterAsmStreamer(const AsmPrinter *AP) : AsmStreamerBase(AP) {}
unsigned emitULEB128(uint64_t Value, const char *Desc = nullptr,
unsigned PadTo = 0) override;
unsigned emitInt8(unsigned char Value) override;
unsigned emitBytes(StringRef Data) override;
};
//===--------------------------------------------------------------------===//
/// DIEAbbrevData - Dwarf abbreviation data, describes one attribute of a
/// Dwarf abbreviation.

View File

@ -31,39 +31,6 @@
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
// EmittingAsmStreamer Implementation
//===----------------------------------------------------------------------===//
unsigned EmittingAsmStreamer::emitULEB128(uint64_t Value, const char *Desc,
unsigned PadTo) {
AP->EmitULEB128(Value, Desc, PadTo);
return 0;
}
unsigned EmittingAsmStreamer::emitInt8(unsigned char Value) {
AP->EmitInt8(Value);
return 0;
}
unsigned EmittingAsmStreamer::emitBytes(StringRef Data) {
AP->OutStreamer->EmitBytes(Data);
return 0;
}
//===----------------------------------------------------------------------===//
// SizeReporterAsmStreamer Implementation
//===----------------------------------------------------------------------===//
unsigned SizeReporterAsmStreamer::emitULEB128(uint64_t Value, const char *Desc,
unsigned PadTo) {
return getULEB128Size(Value);
}
unsigned SizeReporterAsmStreamer::emitInt8(unsigned char Value) { return 1; }
unsigned SizeReporterAsmStreamer::emitBytes(StringRef Data) {
return Data.size();
}
//===----------------------------------------------------------------------===//
// DIEAbbrevData Implementation
//===----------------------------------------------------------------------===//

View File

@ -22,6 +22,7 @@ DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
: DwarfUnit(UID, dwarf::DW_TAG_compile_unit, Node, A, DW, DWU),
Skeleton(nullptr), BaseAddress(nullptr) {
insertDIE(Node, &getUnitDie());
MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");
}
/// addLabelAddress - Add a dwarf label attribute data and value using

View File

@ -39,6 +39,9 @@ class DwarfCompileUnit : public DwarfUnit {
/// The start of the unit within its section.
MCSymbol *LabelBegin;
/// The start of the unit macro info within macro section.
MCSymbol *MacroLabelBegin;
typedef llvm::SmallVector<const MDNode *, 8> ImportedEntityList;
typedef llvm::DenseMap<const MDNode *, ImportedEntityList>
ImportedEntityMap;
@ -189,6 +192,10 @@ public:
return LabelBegin;
}
MCSymbol *getMacroLabelBegin() const {
return MacroLabelBegin;
}
/// Add a new global name to the compile unit.
void addGlobalName(StringRef Name, DIE &Die, const DIScope *Context) override;

View File

@ -561,8 +561,6 @@ void DwarfDebug::finalizeModuleInfo() {
// Collect info for variables that were optimized out.
collectDeadVariables();
unsigned MacroOffset = 0;
std::unique_ptr<AsmStreamerBase> AS(new SizeReporterAsmStreamer(Asm));
// Handle anything that needs to be done on a per-unit basis after
// all other generation.
for (const auto &P : CUMap) {
@ -617,13 +615,11 @@ void DwarfDebug::finalizeModuleInfo() {
}
auto *CUNode = cast<DICompileUnit>(P.first);
if (CUNode->getMacros()) {
// Compile Unit has macros, emit "DW_AT_macro_info" attribute.
U.addUInt(U.getUnitDie(), dwarf::DW_AT_macro_info,
dwarf::DW_FORM_sec_offset, MacroOffset);
// Update macro section offset
MacroOffset += handleMacroNodes(AS.get(), CUNode->getMacros(), U);
}
// If compile Unit has macros, emit "DW_AT_macro_info" attribute.
if (CUNode->getMacros())
U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_macro_info,
U.getMacroLabelBegin(),
TLOF.getDwarfMacinfoSection()->getBeginSymbol());
}
// Compute DIE offsets and sizes.
@ -1865,65 +1861,56 @@ void DwarfDebug::emitDebugRanges() {
}
}
unsigned DwarfDebug::handleMacroNodes(AsmStreamerBase *AS,
DIMacroNodeArray Nodes,
DwarfCompileUnit &U) {
unsigned Size = 0;
void DwarfDebug::handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U) {
for (auto *MN : Nodes) {
if (auto *M = dyn_cast<DIMacro>(MN))
Size += emitMacro(AS, *M);
emitMacro(*M);
else if (auto *F = dyn_cast<DIMacroFile>(MN))
Size += emitMacroFile(AS, *F, U);
emitMacroFile(*F, U);
else
llvm_unreachable("Unexpected DI type!");
}
return Size;
}
unsigned DwarfDebug::emitMacro(AsmStreamerBase *AS, DIMacro &M) {
int Size = 0;
Size += AS->emitULEB128(M.getMacinfoType());
Size += AS->emitULEB128(M.getLine());
void DwarfDebug::emitMacro(DIMacro &M) {
Asm->EmitULEB128(M.getMacinfoType());
Asm->EmitULEB128(M.getLine());
StringRef Name = M.getName();
StringRef Value = M.getValue();
Size += AS->emitBytes(Name);
Asm->OutStreamer->EmitBytes(Name);
if (!Value.empty()) {
// There should be one space between macro name and macro value.
Size += AS->emitInt8(' ');
Size += AS->emitBytes(Value);
Asm->EmitInt8(' ');
Asm->OutStreamer->EmitBytes(Value);
}
Size += AS->emitInt8('\0');
return Size;
Asm->EmitInt8('\0');
}
unsigned DwarfDebug::emitMacroFile(AsmStreamerBase *AS, DIMacroFile &F,
DwarfCompileUnit &U) {
int Size = 0;
void DwarfDebug::emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U) {
assert(F.getMacinfoType() == dwarf::DW_MACINFO_start_file);
Size += AS->emitULEB128(dwarf::DW_MACINFO_start_file);
Size += AS->emitULEB128(F.getLine());
Asm->EmitULEB128(dwarf::DW_MACINFO_start_file);
Asm->EmitULEB128(F.getLine());
DIFile *File = F.getFile();
unsigned FID =
U.getOrCreateSourceID(File->getFilename(), File->getDirectory());
Size += AS->emitULEB128(FID);
Size += handleMacroNodes(AS, F.getElements(), U);
Size += AS->emitULEB128(dwarf::DW_MACINFO_end_file);
return Size;
Asm->EmitULEB128(FID);
handleMacroNodes(F.getElements(), U);
Asm->EmitULEB128(dwarf::DW_MACINFO_end_file);
}
/// Emit macros into a debug macinfo section.
void DwarfDebug::emitDebugMacinfo() {
if (MCSection *Macinfo = Asm->getObjFileLowering().getDwarfMacinfoSection()) {
// Start the dwarf macinfo section.
Asm->OutStreamer->SwitchSection(Macinfo);
}
std::unique_ptr<AsmStreamerBase> AS(new EmittingAsmStreamer(Asm));
Asm->OutStreamer->SwitchSection(
Asm->getObjFileLowering().getDwarfMacinfoSection());
for (const auto &P : CUMap) {
auto &TheCU = *P.second;
auto *SkCU = TheCU.getSkeleton();
DwarfCompileUnit &U = SkCU ? *SkCU : TheCU;
auto *CUNode = cast<DICompileUnit>(P.first);
handleMacroNodes(AS.get(), CUNode->getMacros(), U);
Asm->OutStreamer->EmitLabel(U.getMacroLabelBegin());
handleMacroNodes(CUNode->getMacros(), U);
}
Asm->OutStreamer->AddComment("End Of Macro List Mark");
Asm->EmitInt8(0);

View File

@ -414,11 +414,9 @@ class DwarfDebug : public AsmPrinterHandler {
/// Emit macros into a debug macinfo section.
void emitDebugMacinfo();
unsigned emitMacro(AsmStreamerBase *AS, DIMacro &M);
unsigned emitMacroFile(AsmStreamerBase *AS, DIMacroFile &F,
DwarfCompileUnit &U);
unsigned handleMacroNodes(AsmStreamerBase *AS, DIMacroNodeArray Nodes,
DwarfCompileUnit &U);
void emitMacro(DIMacro &M);
void emitMacroFile(DIMacroFile &F, DwarfCompileUnit &U);
void handleMacroNodes(DIMacroNodeArray Nodes, DwarfCompileUnit &U);
/// DWARF 5 Experimental Split Dwarf Emitters

View File

@ -259,7 +259,7 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) {
SectionKind::getMetadata(), "debug_range");
DwarfMacinfoSection =
Ctx->getMachOSection("__DWARF", "__debug_macinfo", MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
SectionKind::getMetadata(), "debug_macinfo");
DwarfDebugInlineSection =
Ctx->getMachOSection("__DWARF", "__debug_inlined", MachO::S_ATTR_DEBUG,
SectionKind::getMetadata());
@ -510,8 +510,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(Triple T) {
Ctx->getELFSection(".debug_aranges", ELF::SHT_PROGBITS, 0);
DwarfRangesSection =
Ctx->getELFSection(".debug_ranges", ELF::SHT_PROGBITS, 0, "debug_range");
DwarfMacinfoSection =
Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS, 0);
DwarfMacinfoSection = Ctx->getELFSection(".debug_macinfo", ELF::SHT_PROGBITS,
0, "debug_macinfo");
// DWARF5 Experimental Debug Info
@ -700,7 +700,7 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(Triple T) {
".debug_macinfo",
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
COFF::IMAGE_SCN_MEM_READ,
SectionKind::getMetadata());
SectionKind::getMetadata(), "debug_macinfo");
DwarfInfoDWOSection = Ctx->getCOFFSection(
".debug_info.dwo",
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |