MCDwarf: Refactor line table handling into a single data structure
authorDavid Blaikie <dblaikie@gmail.com>
Thu, 13 Mar 2014 17:55:28 +0000 (17:55 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Thu, 13 Mar 2014 17:55:28 +0000 (17:55 +0000)
This replaces several "compile unit ID -> thing" mappings in favor of
one mapping from CUID to the whole line table structure (files,
directories, and lines).

This is another step along the way to refactoring out reusable
components of line table handling for use when generating debug_line.dwo
for fission type units.

Also, might be a good basis to fold some of this handling down into
MCStreamers to avoid the special case of "One line table when doing asm
printing, line table per CU otherwise" by building it into the different
MCStreamer implementations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203821 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCContext.h
include/llvm/MC/MCDwarf.h
lib/MC/MCContext.cpp
lib/MC/MCDwarf.cpp
lib/MC/MCObjectStreamer.cpp

index e93a97a96e64124459401e5bd36f6b73d90f4c29..f0e8f0729b202a2cb1a2b98b6498b166f7f28876 100644 (file)
@@ -108,9 +108,7 @@ namespace llvm {
     /// We now emit a line table for each compile unit. To reduce the prologue
     /// size of each line table, the files and directories used by each compile
     /// unit are separated.
-    typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap;
-    MCDwarfFilesMap MCDwarfFilesCUMap;
-    std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap;
+    std::map<unsigned, MCDwarfFileTable> MCDwarfFileTablesCUMap;
 
     /// The current dwarf line information from the last dwarf .loc directive.
     MCDwarfLoc CurrentDwarfLoc;
@@ -146,13 +144,8 @@ namespace llvm {
     /// Darwin).
     bool AllowTemporaryLabels;
 
-    /// The dwarf line information from the .loc directives for the sections
-    /// with assembled machine instructions have after seeing .loc directives.
-    std::map<unsigned, MCLineSection> MCLineSections;
     /// The Compile Unit ID that we are currently processing.
     unsigned DwarfCompileUnitID;
-    /// The line table start symbol for each Compile Unit.
-    DenseMap<unsigned, MCSymbol *> MCLineTableSymbols;
 
     void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
 
@@ -298,26 +291,38 @@ namespace llvm {
 
     bool hasDwarfFiles() const {
       // Traverse MCDwarfFilesCUMap and check whether each entry is empty.
-      MCDwarfFilesMap::const_iterator MapB, MapE;
-      for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end();
-           MapB != MapE; MapB++)
-        if (!MapB->second.empty())
+      for (const auto &FileTable : MCDwarfFileTablesCUMap)
+        if (!FileTable.second.getMCDwarfFiles().empty())
            return true;
       return false;
     }
 
+    const std::map<unsigned, MCDwarfFileTable> &getMCDwarfFileTables() const {
+      return MCDwarfFileTablesCUMap;
+    }
+
+    MCDwarfFileTable &getMCDwarfFileTable(unsigned CUID) {
+      return MCDwarfFileTablesCUMap[CUID];
+    }
+
+    const MCDwarfFileTable &getMCDwarfFileTable(unsigned CUID) const {
+      auto I = MCDwarfFileTablesCUMap.find(CUID);
+      assert(I != MCDwarfFileTablesCUMap.end());
+      return I->second;
+    }
+
     const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) {
-      return MCDwarfFilesCUMap[CUID];
+      return getMCDwarfFileTable(CUID).getMCDwarfFiles();
     }
     const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) {
-      return MCDwarfDirsCUMap[CUID];
+      return getMCDwarfFileTable(CUID).getMCDwarfDirs();
     }
 
-    const std::map<unsigned, MCLineSection> &getMCLineSections() const {
-      return MCLineSections;
-    }
-    std::map<unsigned, MCLineSection> &getMCLineSections() {
-      return MCLineSections;
+    bool hasMCLineSections() const {
+      for (const auto &Table : MCDwarfFileTablesCUMap)
+        if (!Table.second.getMCDwarfFiles().empty() || Table.second.getLabel())
+          return true;
+      return false;
     }
     unsigned getDwarfCompileUnitID() {
       return DwarfCompileUnitID;
@@ -325,18 +330,11 @@ namespace llvm {
     void setDwarfCompileUnitID(unsigned CUIndex) {
       DwarfCompileUnitID = CUIndex;
     }
-    const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const {
-      return MCLineTableSymbols;
-    }
     MCSymbol *getMCLineTableSymbol(unsigned ID) const {
-      DenseMap<unsigned, MCSymbol *>::const_iterator CIter =
-        MCLineTableSymbols.find(ID);
-      if (CIter == MCLineTableSymbols.end())
-        return NULL;
-      return CIter->second;
+      return getMCDwarfFileTable(ID).getLabel();
     }
     void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
-      MCLineTableSymbols[ID] = Sym;
+      getMCDwarfFileTable(ID).setLabel(Sym);
     }
 
     /// setCurrentDwarfLoc - saves the information from the currently parsed
index 418c213fcdf7632ef4a69f4eeb21d4752ba92fc2..17476cf2b7f6662696762a1bf8295b1f5dafa644 100644 (file)
@@ -200,6 +200,11 @@ public:
 };
 
 class MCDwarfFileTable {
+  MCSymbol *Label;
+  SmallVector<StringRef, 3> MCDwarfDirs;
+  SmallVector<MCDwarfFile *, 3> MCDwarfFiles;
+  MCLineSection MCLineSections;
+
 public:
   //
   // This emits the Dwarf file and the line tables for all Compile Units.
@@ -208,7 +213,38 @@ public:
   //
   // This emits the Dwarf file and the line tables for a given Compile Unit.
   //
-  static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);
+  const MCSymbol *EmitCU(MCStreamer *MCOS) const;
+
+  const SmallVectorImpl<StringRef> &getMCDwarfDirs() const {
+    return MCDwarfDirs;
+  }
+
+  SmallVectorImpl<StringRef> &getMCDwarfDirs() {
+    return MCDwarfDirs;
+  }
+
+  const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles() const {
+    return MCDwarfFiles;
+  }
+
+  SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles() {
+    return MCDwarfFiles;
+  }
+
+  const MCLineSection &getMCLineSections() const {
+    return MCLineSections;
+  }
+  MCLineSection &getMCLineSections() {
+    return MCLineSections;
+  }
+
+  MCSymbol *getLabel() const {
+    return Label;
+  }
+
+  void setLabel(MCSymbol *Label) {
+    this->Label = Label;
+  }
 };
 
 class MCDwarfLineAddr {
index 718c3cefaa3759b3b26ad2199e9f1f7025039a13..f7e30f5b0678a7e6f5dc1e38252f83b5d3204fcc 100644 (file)
@@ -84,13 +84,10 @@ void MCContext::reset() {
   Symbols.clear();
   Allocator.Reset();
   Instances.clear();
-  MCDwarfFilesCUMap.clear();
-  MCDwarfDirsCUMap.clear();
+  MCDwarfFileTablesCUMap.clear();
   MCGenDwarfLabelEntries.clear();
   DwarfDebugFlags = StringRef();
-  MCLineSections.clear();
   DwarfCompileUnitID = 0;
-  MCLineTableSymbols.clear();
   CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0);
 
   // If we have the MachO uniquing map, free it.
@@ -337,8 +334,9 @@ unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
   // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked
   // to not be less than one.  This needs to be change to be not less than zero.
 
-  SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
-  SmallVectorImpl<StringRef>& MCDwarfDirs = MCDwarfDirsCUMap[CUID];
+  MCDwarfFileTable &Table = MCDwarfFileTablesCUMap[CUID];
+  SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = Table.getMCDwarfFiles();
+  SmallVectorImpl<StringRef>& MCDwarfDirs = Table.getMCDwarfDirs();
   // Make space for this FileNumber in the MCDwarfFiles vector if needed.
   if (FileNumber >= MCDwarfFiles.size()) {
     MCDwarfFiles.resize(FileNumber + 1);
@@ -399,7 +397,7 @@ unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName,
 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
 /// currently is assigned and false otherwise.
 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
-  SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = MCDwarfFilesCUMap[CUID];
+  const SmallVectorImpl<MCDwarfFile *>& MCDwarfFiles = getMCDwarfFiles(CUID);
   if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
     return false;
 
index 4bc751fd3d75bbf3649fe18b20208718255cf9e7..dc0601d0a612ee4b06ffc3784359671c1d01ea0c 100644 (file)
@@ -82,7 +82,8 @@ void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) {
 
   // Add the line entry to this section's entries.
   MCOS->getContext()
-      .getMCLineSections()[MCOS->getContext().getDwarfCompileUnitID()]
+      .getMCDwarfFileTable(MCOS->getContext().getDwarfCompileUnitID())
+      .getMCLineSections()
       .addLineEntry(LineEntry, Section);
 }
 
@@ -205,27 +206,31 @@ EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section,
 //
 const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) {
   MCContext &context = MCOS->getContext();
-  // Switch to the section where the table will be emitted into.
-  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
 
-  const DenseMap<unsigned, MCSymbol *> &MCLineTableSymbols =
-    MCOS->getContext().getMCLineTableSymbols();
   // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does
   // not exist, CUID will be 0 and MCLineTableSymbols will be empty.
   // Handle Compile Unit 0, the line table start symbol is the section symbol.
-  const MCSymbol *LineStartSym = EmitCU(MCOS, 0);
+  auto I = MCOS->getContext().getMCDwarfFileTables().begin(),
+       E = MCOS->getContext().getMCDwarfFileTables().end();
+
+  // Switch to the section where the table will be emitted into.
+  MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
+
+  const MCSymbol *LineStartSym = I->second.EmitCU(MCOS);
   // Handle the rest of the Compile Units.
-  for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++)
-    EmitCU(MCOS, Is);
+  for (++I; I != E; ++I)
+    I->second.EmitCU(MCOS);
 
   return LineStartSym;
 }
 
-const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
+const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS) const {
   MCContext &context = MCOS->getContext();
 
+
+
   // Create a symbol at the beginning of the line table.
-  MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID);
+  MCSymbol *LineStartSym = Label;
   if (!LineStartSym)
     LineStartSym = context.CreateTempSymbol();
   // Set the value of the symbol, as we are at the start of the line table.
@@ -276,8 +281,6 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
   // Put out the directory and file tables.
 
   // First the directory table.
-  const SmallVectorImpl<StringRef> &MCDwarfDirs =
-    context.getMCDwarfDirs(CUID);
   for (unsigned i = 0; i < MCDwarfDirs.size(); i++) {
     MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName
     MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
@@ -285,8 +288,6 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
   MCOS->EmitIntValue(0, 1); // Terminate the directory list
 
   // Second the file table.
-  const SmallVectorImpl<MCDwarfFile *> &MCDwarfFiles =
-    MCOS->getContext().getMCDwarfFiles(CUID);
   for (unsigned i = 1; i < MCDwarfFiles.size(); i++) {
     MCOS->EmitBytes(MCDwarfFiles[i]->getName()); // FileName
     MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string
@@ -302,15 +303,11 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) {
   MCOS->EmitLabel(ProEndSym);
 
   // Put out the line tables.
-  const std::map<unsigned, MCLineSection> &MCLineSections =
-    MCOS->getContext().getMCLineSections();
-  auto Iter = MCLineSections.find(CUID);
-  if (Iter != MCLineSections.end())
-    for (const auto &LineSec : Iter->second.getMCLineEntries())
-      EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
+  for (const auto &LineSec : MCLineSections.getMCLineEntries())
+    EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
 
   if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() &&
-      Iter == MCLineSections.end()) {
+      MCLineSections.getMCLineEntries().empty()) {
     // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
     // it requires:
     // total_length >= prologue_length + 10
@@ -729,7 +726,7 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) {
   MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection());
 
   // If there are no line table entries then do not emit any section contents.
-  if (context.getMCLineSections().empty())
+  if (!context.hasMCLineSections())
     return;
 
   // Output the data for .debug_aranges section.
index 119df0a083dc3fdbc05cfb7257cd0648635e86b8..996cf5c09b8ebf0bd742bcf2243079d62407b427 100644 (file)
@@ -379,8 +379,7 @@ void MCObjectStreamer::EmitZeros(uint64_t NumBytes) {
 void MCObjectStreamer::FinishImpl() {
   // Dump out the dwarf file & directory tables and line tables.
   const MCSymbol *LineSectionSymbol = NULL;
-  if (!getContext().getMCLineTableSymbols().empty() ||
-      getContext().hasDwarfFiles())
+  if (getContext().hasMCLineSections())
     LineSectionSymbol = MCDwarfFileTable::Emit(this);
 
   // If we are generating dwarf for assembly source files dump out the sections.