DebugInfo: Improve reuse of file table entries in asm debug info

The previous deduping strategy was woefully inadequate - it only
considered the most recent file used and avoided emitting a duplicate in
that case - never considering the a/b/a scenario.

It was also lacking when it came to directory paths as the previous
filename would never match the current if the filename had been split
into file and directory components.

This change builds caching functionality into the line table at the
lowest level in an optional form (a file number of 0 indicates that one
should be chosen and returned) and will eventually be reused by the
normal source level debugging DWARF emission.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204027 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Blaikie 2014-03-17 01:52:11 +00:00
parent 6a6b6f50af
commit fd69cf9ba4
9 changed files with 45 additions and 29 deletions

View File

@ -371,7 +371,9 @@ namespace llvm {
bool getGenDwarfForAssembly() { return GenDwarfForAssembly; } bool getGenDwarfForAssembly() { return GenDwarfForAssembly; }
void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; } void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; }
unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; } unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; }
unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; } void setGenDwarfFileNumber(unsigned FileNumber) {
GenDwarfFileNumber = FileNumber;
}
const MCSection *getGenDwarfSection() { return GenDwarfSection; } const MCSection *getGenDwarfSection() { return GenDwarfSection; }
void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; } void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; }
MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; } MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; }

View File

@ -16,6 +16,7 @@
#define LLVM_MC_MCDWARF_H #define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/MapVector.h" #include "llvm/ADT/MapVector.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/Support/Dwarf.h" #include "llvm/Support/Dwarf.h"
@ -179,8 +180,9 @@ struct MCDwarfLineTableHeader {
MCSymbol *Label; MCSymbol *Label;
SmallVector<std::string, 3> MCDwarfDirs; SmallVector<std::string, 3> MCDwarfDirs;
SmallVector<MCDwarfFile, 3> MCDwarfFiles; SmallVector<MCDwarfFile, 3> MCDwarfFiles;
StringMap<unsigned> SourceIdMap;
MCDwarfLineTableHeader() : Label(nullptr) {} MCDwarfLineTableHeader() : Label(nullptr) {}
unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber); unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber = 0);
std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const; std::pair<MCSymbol *, MCSymbol *> Emit(MCStreamer *MCOS) const;
}; };
@ -195,7 +197,7 @@ public:
// This emits the Dwarf file and the line tables for a given Compile Unit. // This emits the Dwarf file and the line tables for a given Compile Unit.
const MCSymbol *EmitCU(MCStreamer *MCOS) const; const MCSymbol *EmitCU(MCStreamer *MCOS) const;
unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber); unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber = 0);
MCSymbol *getLabel() const { MCSymbol *getLabel() const {
return Header.Label; return Header.Label;

View File

@ -628,8 +628,9 @@ public:
/// EmitDwarfFileDirective - Associate a filename with a specified logical /// EmitDwarfFileDirective - Associate a filename with a specified logical
/// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler
/// directive. /// directive.
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename, unsigned CUID = 0); StringRef Filename,
unsigned CUID = 0);
/// EmitDwarfLocDirective - This implements the DWARF2 /// EmitDwarfLocDirective - This implements the DWARF2
// '.loc fileno lineno ...' assembler directive. // '.loc fileno lineno ...' assembler directive.

View File

@ -197,8 +197,9 @@ public:
unsigned char Value = 0) override; unsigned char Value = 0) override;
void EmitFileDirective(StringRef Filename) override; void EmitFileDirective(StringRef Filename) override;
bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename, unsigned CUID = 0) override; StringRef Filename,
unsigned CUID = 0) override;
void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags, unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator, unsigned Isa, unsigned Discriminator,
@ -843,8 +844,10 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
EmitEOL(); EmitEOL();
} }
bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo,
StringRef Filename, unsigned CUID) { StringRef Directory,
StringRef Filename,
unsigned CUID) {
if (!UseDwarfDirectory && !Directory.empty()) { if (!UseDwarfDirectory && !Directory.empty()) {
if (sys::path::is_absolute(Filename)) if (sys::path::is_absolute(Filename))
return EmitDwarfFileDirective(FileNo, "", Filename, CUID); return EmitDwarfFileDirective(FileNo, "", Filename, CUID);

View File

@ -336,7 +336,18 @@ unsigned MCDwarfLineTable::getFile(StringRef Directory, StringRef FileName,
return Header.getFile(Directory, FileName, FileNumber); return Header.getFile(Directory, FileName, FileNumber);
} }
unsigned MCDwarfLineTableHeader::getFile(StringRef Directory, StringRef FileName, unsigned FileNumber) { unsigned MCDwarfLineTableHeader::getFile(StringRef Directory,
StringRef FileName,
unsigned FileNumber) {
if (FileNumber == 0) {
FileNumber = SourceIdMap.size() + 1;
assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) &&
"Don't mix autonumbered and explicit numbered line table usage");
StringMapEntry<unsigned> &Ent = SourceIdMap.GetOrCreateValue(
(Directory + Twine('\0') + FileName).str(), FileNumber);
if (Ent.getValue() != FileNumber)
return Ent.getValue();
}
// Make space for this FileNumber in the MCDwarfFiles vector if needed. // Make space for this FileNumber in the MCDwarfFiles vector if needed.
MCDwarfFiles.resize(FileNumber + 1); MCDwarfFiles.resize(FileNumber + 1);

View File

@ -85,10 +85,10 @@ namespace {
unsigned char Value = 0) override { return false; } unsigned char Value = 0) override { return false; }
void EmitFileDirective(StringRef Filename) override {} void EmitFileDirective(StringRef Filename) override {}
bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename, StringRef Filename,
unsigned CUID = 0) override { unsigned CUID = 0) override {
return false; return 0;
} }
void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags, unsigned Column, unsigned Flags,

View File

@ -640,9 +640,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); MCSymbol *SectionStartSym = getContext().CreateTempSymbol();
getStreamer().EmitLabel(SectionStartSym); getStreamer().EmitLabel(SectionStartSym);
getContext().setGenDwarfSectionStartSym(SectionStartSym); getContext().setGenDwarfSectionStartSym(SectionStartSym);
getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective(
StringRef(), 0, StringRef(), getContext().getMainFileName()));
getContext().getMainFileName());
} }
// While we have input, parse each statement. // While we have input, parse each statement.
@ -1589,14 +1588,10 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
// If we previously parsed a cpp hash file line comment then make sure the // If we previously parsed a cpp hash file line comment then make sure the
// current Dwarf File is for the CppHashFilename if not then emit the // current Dwarf File is for the CppHashFilename if not then emit the
// Dwarf File table for it and adjust the line number for the .loc. // Dwarf File table for it and adjust the line number for the .loc.
const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles =
getContext().getMCDwarfFiles();
if (CppHashFilename.size() != 0) { if (CppHashFilename.size() != 0) {
if (MCDwarfFiles[getContext().getGenDwarfFileNumber()].Name != unsigned FileNumber = getStreamer().EmitDwarfFileDirective(
CppHashFilename) 0, StringRef(), CppHashFilename);
getStreamer().EmitDwarfFileDirective( getContext().setGenDwarfFileNumber(FileNumber);
getContext().nextGenDwarfFileNumber(), StringRef(),
CppHashFilename);
// Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's
// cache with the different Loc from the call above we save the last // cache with the different Loc from the call above we save the last
@ -2762,7 +2757,8 @@ bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
"input can't have .file dwarf directives when -g is " "input can't have .file dwarf directives when -g is "
"used to generate dwarf debug info for assembly code"); "used to generate dwarf debug info for assembly code");
if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename)) if (getStreamer().EmitDwarfFileDirective(FileNumber, Directory, Filename) ==
0)
Error(FileNumberLoc, "file number already allocated"); Error(FileNumberLoc, "file number already allocated");
} }

View File

@ -174,10 +174,10 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) {
EmitFill(NumBytes, 0); EmitFill(NumBytes, 0);
} }
bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo,
StringRef Directory, StringRef Directory,
StringRef Filename, unsigned CUID) { StringRef Filename, unsigned CUID) {
return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID) == 0; return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID);
} }
void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,

View File

@ -4,6 +4,7 @@
# 100 "t.s" 1 # 100 "t.s" 1
.globl _bar .globl _bar
_bar: _bar:
movl $0, %eax
# 3 "inc/g.s" # 3 "inc/g.s"
movl $0, %eax movl $0, %eax
L1: leave L1: leave