DebugInfo: Improve reuse of file table entries in asm debug info
authorDavid Blaikie <dblaikie@gmail.com>
Mon, 17 Mar 2014 01:52:11 +0000 (01:52 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Mon, 17 Mar 2014 01:52:11 +0000 (01:52 +0000)
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
include/llvm/MC/MCDwarf.h
include/llvm/MC/MCStreamer.h
lib/MC/MCAsmStreamer.cpp
lib/MC/MCDwarf.cpp
lib/MC/MCNullStreamer.cpp
lib/MC/MCParser/AsmParser.cpp
lib/MC/MCStreamer.cpp
test/MC/MachO/gen-dwarf-cpp.s

index b3df2252109f9089f71bafc584c229cc1be9ca2e..b51a5a589f42ea279841d0448fd6b6018be492d1 100644 (file)
@@ -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; }
index abd2f7a2d6919a16dab1933f4bee6157e97e58d6..3b6045061443f99545ee9fe9fd85ee7573478e68 100644 (file)
@@ -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<std::string, 3> MCDwarfDirs;
   SmallVector<MCDwarfFile, 3> MCDwarfFiles;
+  StringMap<unsigned> SourceIdMap;
   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;
 };
 
@@ -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;
index 18f0e772ef0ab21beca3f5c25419f78ee733bd4c..fc7a3b8648210b846c4690c9a648390e79cf4fc4 100644 (file)
@@ -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.
index 75db7a96bbfcc144e28bc9f061156c531a3c392c..b40305d0fc2ac67649d725a053ec907fb0c51963 100644 (file)
@@ -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);
index 181e73dd432f1d3580e5d7eb394404ad2598ddfc..72ecfa6cb45b9cdd0d9a0754a8b1b3952247e0dd 100644 (file)
@@ -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<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.
   MCDwarfFiles.resize(FileNumber + 1);
 
index 181000b249c89bbe17e4a7d462584b6b6a5cbf89..894eada57d6b10653b9db5db4f7ac7999f972797 100644 (file)
@@ -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,
index f3cf8f2d1c7af2017492efbfab402f8962b79bfc..fbbd4365bcbd4beab3eb20b4778a69cc97d8cd6e 100644 (file)
@@ -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<MCDwarfFile> &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");
   }
 
index 0837389581482bcac18b17cae38c7a663c065cb8..ec3b5f9be41e29b05da48f362610df4e9bd037c5 100644 (file)
@@ -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,
index c32bcbf580f53cbdbb0152e24b4f1ae67cc96f70..d5cda27ec58e8dba7564eb738767c3dd6a2fa992 100644 (file)
@@ -4,6 +4,7 @@
 # 100 "t.s" 1
 .globl _bar
 _bar:
+       movl    $0, %eax
 # 3 "inc/g.s"
        movl    $0, %eax
 L1:    leave