From fd69cf9ba4b4a3f29523e2367a569bd84e0fdad8 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Mon, 17 Mar 2014 01:52:11 +0000 Subject: [PATCH] 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 --- include/llvm/MC/MCContext.h | 4 +++- include/llvm/MC/MCDwarf.h | 6 ++++-- include/llvm/MC/MCStreamer.h | 5 +++-- lib/MC/MCAsmStreamer.cpp | 11 +++++++---- lib/MC/MCDwarf.cpp | 13 ++++++++++++- lib/MC/MCNullStreamer.cpp | 8 ++++---- lib/MC/MCParser/AsmParser.cpp | 18 +++++++----------- lib/MC/MCStreamer.cpp | 8 ++++---- test/MC/MachO/gen-dwarf-cpp.s | 1 + 9 files changed, 45 insertions(+), 29 deletions(-) diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h index b3df2252109..b51a5a589f4 100644 --- a/include/llvm/MC/MCContext.h +++ b/include/llvm/MC/MCContext.h @@ -371,7 +371,9 @@ namespace llvm { bool getGenDwarfForAssembly() { return GenDwarfForAssembly; } void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; } unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; } - unsigned nextGenDwarfFileNumber() { return ++GenDwarfFileNumber; } + void setGenDwarfFileNumber(unsigned FileNumber) { + GenDwarfFileNumber = FileNumber; + } const MCSection *getGenDwarfSection() { return GenDwarfSection; } void setGenDwarfSection(const MCSection *Sec) { GenDwarfSection = Sec; } MCSymbol *getGenDwarfSectionStartSym() { return GenDwarfSectionStartSym; } diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index abd2f7a2d69..3b604506144 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -16,6 +16,7 @@ #define LLVM_MC_MCDWARF_H #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/MapVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Dwarf.h" @@ -179,8 +180,9 @@ struct MCDwarfLineTableHeader { MCSymbol *Label; SmallVector MCDwarfDirs; SmallVector MCDwarfFiles; + StringMap SourceIdMap; MCDwarfLineTableHeader() : Label(nullptr) {} - unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber); + unsigned getFile(StringRef Directory, StringRef FileName, unsigned FileNumber = 0); std::pair Emit(MCStreamer *MCOS) const; }; @@ -195,7 +197,7 @@ public: // This emits the Dwarf file and the line tables for a given Compile Unit. 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 { return Header.Label; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 18f0e772ef0..fc7a3b86482 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -628,8 +628,9 @@ public: /// EmitDwarfFileDirective - Associate a filename with a specified logical /// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler /// directive. - virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, unsigned CUID = 0); + virtual unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + unsigned CUID = 0); /// EmitDwarfLocDirective - This implements the DWARF2 // '.loc fileno lineno ...' assembler directive. diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 75db7a96bbf..b40305d0fc2 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -197,8 +197,9 @@ public: unsigned char Value = 0) override; void EmitFileDirective(StringRef Filename) override; - bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, unsigned CUID = 0) override; + unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + unsigned CUID = 0) override; void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, unsigned Discriminator, @@ -843,8 +844,10 @@ void MCAsmStreamer::EmitFileDirective(StringRef Filename) { EmitEOL(); } -bool MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, unsigned CUID) { +unsigned MCAsmStreamer::EmitDwarfFileDirective(unsigned FileNo, + StringRef Directory, + StringRef Filename, + unsigned CUID) { if (!UseDwarfDirectory && !Directory.empty()) { if (sys::path::is_absolute(Filename)) return EmitDwarfFileDirective(FileNo, "", Filename, CUID); diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 181e73dd432..72ecfa6cb45 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -336,7 +336,18 @@ unsigned MCDwarfLineTable::getFile(StringRef Directory, StringRef FileName, 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 &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. MCDwarfFiles.resize(FileNumber + 1); diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 181000b249c..894eada57d6 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -85,10 +85,10 @@ namespace { unsigned char Value = 0) override { return false; } void EmitFileDirective(StringRef Filename) override {} - bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, - StringRef Filename, - unsigned CUID = 0) override { - return false; + unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory, + StringRef Filename, + unsigned CUID = 0) override { + return 0; } void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index f3cf8f2d1c7..fbbd4365bcb 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -640,9 +640,8 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { MCSymbol *SectionStartSym = getContext().CreateTempSymbol(); getStreamer().EmitLabel(SectionStartSym); getContext().setGenDwarfSectionStartSym(SectionStartSym); - getStreamer().EmitDwarfFileDirective(getContext().nextGenDwarfFileNumber(), - StringRef(), - getContext().getMainFileName()); + getContext().setGenDwarfFileNumber(getStreamer().EmitDwarfFileDirective( + 0, StringRef(), getContext().getMainFileName())); } // 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 // 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. - const SmallVectorImpl &MCDwarfFiles = - getContext().getMCDwarfFiles(); if (CppHashFilename.size() != 0) { - if (MCDwarfFiles[getContext().getGenDwarfFileNumber()].Name != - CppHashFilename) - getStreamer().EmitDwarfFileDirective( - getContext().nextGenDwarfFileNumber(), StringRef(), - CppHashFilename); + unsigned FileNumber = getStreamer().EmitDwarfFileDirective( + 0, StringRef(), CppHashFilename); + getContext().setGenDwarfFileNumber(FileNumber); // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's // 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 " "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"); } diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 08373895814..ec3b5f9be41 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -174,10 +174,10 @@ void MCStreamer::EmitZeros(uint64_t NumBytes) { EmitFill(NumBytes, 0); } -bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, - StringRef Directory, - StringRef Filename, unsigned CUID) { - return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID) == 0; +unsigned MCStreamer::EmitDwarfFileDirective(unsigned FileNo, + StringRef Directory, + StringRef Filename, unsigned CUID) { + return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID); } void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, diff --git a/test/MC/MachO/gen-dwarf-cpp.s b/test/MC/MachO/gen-dwarf-cpp.s index c32bcbf580f..d5cda27ec58 100644 --- a/test/MC/MachO/gen-dwarf-cpp.s +++ b/test/MC/MachO/gen-dwarf-cpp.s @@ -4,6 +4,7 @@ # 100 "t.s" 1 .globl _bar _bar: + movl $0, %eax # 3 "inc/g.s" movl $0, %eax L1: leave