[llvm] r257966 - [codeview] Remove custom line info struct in favor of DebugLoc

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 15 16:09:10 PST 2016


Author: rnk
Date: Fri Jan 15 18:09:09 2016
New Revision: 257966

URL: http://llvm.org/viewvc/llvm-project?rev=257966&view=rev
Log:
[codeview] Remove custom line info struct in favor of DebugLoc

The only functional change would be that we might emit multiple filename
segments on code like this:

  void f() {
  #include "p1/../t.h"
  #include "p2/../t.h"
  }

I believe these get separate DIFile metadata nodes, but will have the
same canonicalized absolute path. Previously by computing the path up
front and comparing it we would merge the line info segments.

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=257966&r1=257965&r2=257966&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri Jan 15 18:09:09 2016
@@ -22,20 +22,13 @@ using namespace llvm::codeview;
 
 namespace llvm {
 
-StringRef CodeViewDebug::getFullFilepath(const MDNode *S) {
-  assert(S);
-  assert((isa<DICompileUnit>(S) || isa<DIFile>(S) || isa<DISubprogram>(S) ||
-          isa<DILexicalBlockBase>(S)) &&
-         "Unexpected scope info");
-
-  auto *Scope = cast<DIScope>(S);
-  StringRef Dir = Scope->getDirectory(),
-            Filename = Scope->getFilename();
-  std::string &Filepath =
-      DirAndFilenameToFilepathMap[std::make_pair(Dir, Filename)];
+StringRef CodeViewDebug::getFullFilepath(const DIFile *File) {
+  std::string &Filepath = FileToFilepathMap[File];
   if (!Filepath.empty())
     return Filepath;
 
+  StringRef Dir = File->getDirectory(), Filename = File->getFilename();
+
   // Clang emits directory and relative filename info into the IR, but CodeView
   // operates on full paths.  We could change Clang to emit full paths too, but
   // that would increase the IR size and probably not needed for other users.
@@ -82,36 +75,25 @@ StringRef CodeViewDebug::getFullFilepath
 }
 
 void CodeViewDebug::maybeRecordLocation(DebugLoc DL,
-                                                const MachineFunction *MF) {
-  const MDNode *Scope = DL.getScope();
+                                        const MachineFunction *MF) {
+  // Skip this instruction if it has the same location as the previous one.
+  if (DL == CurFn->LastLoc)
+    return;
+
+  const DIScope *Scope = DL.get()->getScope();
   if (!Scope)
     return;
-  unsigned LineNumber = DL.getLine();
+
   // Skip this line if it is longer than the maximum we can record.
-  if (LineNumber > COFF::CVL_MaxLineNumber)
+  if (DL.getLine() > COFF::CVL_MaxLineNumber)
     return;
 
-  unsigned ColumnNumber = DL.getCol();
-  // Truncate the column number if it is longer than the maximum we can record.
-  if (ColumnNumber > COFF::CVL_MaxColumnNumber)
-    ColumnNumber = 0;
-
-  StringRef Filename = getFullFilepath(Scope);
-
-  // Skip this instruction if it has the same file:line as the previous one.
-  assert(CurFn);
-  if (!CurFn->Instrs.empty()) {
-    const InstrInfoTy &LastInstr = InstrInfo[CurFn->Instrs.back()];
-    if (LastInstr.Filename == Filename && LastInstr.LineNumber == LineNumber &&
-        LastInstr.ColumnNumber == ColumnNumber)
-      return;
-  }
-  FileNameRegistry.add(Filename);
+  CurFn->LastLoc = DL;
 
   MCSymbol *MCL = Asm->MMI->getContext().createTempSymbol();
   Asm->OutStreamer->EmitLabel(MCL);
   CurFn->Instrs.push_back(MCL);
-  InstrInfo[MCL] = InstrInfoTy(Filename, LineNumber, ColumnNumber);
+  LabelsAndLocs[MCL] = DL;
 }
 
 CodeViewDebug::CodeViewDebug(AsmPrinter *AP)
@@ -195,6 +177,10 @@ static void EmitLabelDiff(MCStreamer &St
   Streamer.EmitValue(AddrDelta, Size);
 }
 
+static const DIFile *getFileFromLoc(DebugLoc DL) {
+  return DL.get()->getScope()->getFile();
+}
+
 void CodeViewDebug::emitDebugInfoForFunction(const Function *GV) {
   // For each function there is a separate subsection
   // which holds the PC to file:line table.
@@ -258,13 +244,14 @@ void CodeViewDebug::emitDebugInfoForFunc
   // number of the respective instruction that starts a new segment.
   DenseMap<size_t, size_t> FilenameSegmentLengths;
   size_t LastSegmentEnd = 0;
-  StringRef PrevFilename = InstrInfo[FI.Instrs[0]].Filename;
+  const DIFile *PrevFile = getFileFromLoc(LabelsAndLocs[FI.Instrs[0]]);
   for (size_t J = 1, F = FI.Instrs.size(); J != F; ++J) {
-    if (PrevFilename == InstrInfo[FI.Instrs[J]].Filename)
+    const DIFile *CurFile = getFileFromLoc(LabelsAndLocs[FI.Instrs[J]]);
+    if (PrevFile == CurFile)
       continue;
     FilenameSegmentLengths[LastSegmentEnd] = J - LastSegmentEnd;
     LastSegmentEnd = J;
-    PrevFilename = InstrInfo[FI.Instrs[J]].Filename;
+    PrevFile = CurFile;
   }
   FilenameSegmentLengths[LastSegmentEnd] = FI.Instrs.size() - LastSegmentEnd;
 
@@ -297,8 +284,11 @@ void CodeViewDebug::emitDebugInfoForFunc
     for (size_t ColSegI = LastSegmentStart,
                 ColSegEnd = ColSegI + FilenameSegmentLengths[LastSegmentStart];
          ColSegI != ColSegEnd; ++ColSegI) {
-      unsigned ColumnNumber = InstrInfo[FI.Instrs[ColSegI]].ColumnNumber;
-      assert(ColumnNumber <= COFF::CVL_MaxColumnNumber);
+      unsigned ColumnNumber = LabelsAndLocs[FI.Instrs[ColSegI]].getCol();
+      // Truncate the column number if it is longer than the maximum we can
+      // record.
+      if (ColumnNumber > COFF::CVL_MaxColumnNumber)
+        ColumnNumber = 0;
       Asm->EmitInt16(ColumnNumber); // Start column
       Asm->EmitInt16(0);            // End column
     }
@@ -307,22 +297,21 @@ void CodeViewDebug::emitDebugInfoForFunc
 
   for (size_t J = 0, F = FI.Instrs.size(); J != F; ++J) {
     MCSymbol *Instr = FI.Instrs[J];
-    assert(InstrInfo.count(Instr));
+    assert(LabelsAndLocs.count(Instr));
 
     if (FilenameSegmentLengths.count(J)) {
       // We came to a beginning of a new filename segment.
       FinishPreviousChunk();
-      StringRef CurFilename = InstrInfo[FI.Instrs[J]].Filename;
-      assert(FileNameRegistry.Infos.count(CurFilename));
-      size_t IndexInStringTable =
-          FileNameRegistry.Infos[CurFilename].FilenameID;
+      const DIFile *File = getFileFromLoc(LabelsAndLocs[FI.Instrs[J]]);
+      StringRef CurFilename = getFullFilepath(File);
+      size_t IndexInFileTable = FileNameRegistry.add(CurFilename);
       // Each segment starts with the offset of the filename
       // in the string table.
       Asm->OutStreamer->AddComment(
           "Segment for file '" + Twine(CurFilename) + "' begins");
       MCSymbol *FileSegmentBegin = Asm->MMI->getContext().createTempSymbol();
       Asm->OutStreamer->EmitLabel(FileSegmentBegin);
-      Asm->EmitInt32(8 * IndexInStringTable);
+      Asm->EmitInt32(8 * IndexInFileTable);
 
       // Number of PC records in the lookup table.
       size_t SegmentLength = FilenameSegmentLengths[J];
@@ -337,7 +326,7 @@ void CodeViewDebug::emitDebugInfoForFunc
 
     // The first PC with the given linenumber and the linenumber itself.
     EmitLabelDiff(*Asm->OutStreamer, Fn, Instr);
-    uint32_t LineNumber = InstrInfo[Instr].LineNumber;
+    uint32_t LineNumber = LabelsAndLocs[Instr].getLine();
     assert(LineNumber <= COFF::CVL_MaxLineNumber);
     uint32_t LineData = LineNumber | COFF::CVL_IsStatement;
     Asm->EmitInt32(LineData);

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=257966&r1=257965&r2=257966&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h Fri Jan 15 18:09:09 2016
@@ -36,10 +36,12 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
   // For each function, store a vector of labels to its instructions, as well as
   // to the end of the function.
   struct FunctionInfo {
+    DebugLoc LastLoc;
     SmallVector<MCSymbol *, 10> Instrs;
     MCSymbol *End;
     FunctionInfo() : End(nullptr) {}
-  } *CurFn;
+  };
+  FunctionInfo *CurFn;
 
   typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
   FnDebugInfoTy FnDebugInfo;
@@ -47,20 +49,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
   // order while emitting subsections.
   SmallVector<const Function *, 10> VisitedFunctions;
 
-  // InstrInfoTy - Holds the Filename:LineNumber information for every
-  // instruction with a unique debug location.
-  struct InstrInfoTy {
-    StringRef Filename;
-    unsigned LineNumber;
-    unsigned ColumnNumber;
-
-    InstrInfoTy() : LineNumber(0), ColumnNumber(0) {}
-
-    InstrInfoTy(StringRef Filename, unsigned LineNumber, unsigned ColumnNumber)
-        : Filename(Filename), LineNumber(LineNumber),
-          ColumnNumber(ColumnNumber) {}
-  };
-  DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
+  DenseMap<MCSymbol *, DebugLoc> LabelsAndLocs;
 
   // FileNameRegistry - Manages filenames observed while generating debug info
   // by filtering out duplicates and bookkeeping the offsets in the string
@@ -81,14 +70,17 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
     }
 
     // Add Filename to the registry, if it was not observed before.
-    void add(StringRef Filename) {
-      if (Infos.count(Filename))
-        return;
+    size_t add(StringRef Filename) {
       size_t OldSize = Infos.size();
-      Infos[Filename].FilenameID = OldSize;
-      Infos[Filename].StartOffset = LastOffset;
-      LastOffset += Filename.size() + 1;
-      Filenames.push_back(Filename);
+      bool Inserted;
+      StringMap<PerFileInfo>::iterator It;
+      std::tie(It, Inserted) = Infos.insert(
+          std::make_pair(Filename, PerFileInfo{OldSize, LastOffset}));
+      if (Inserted) {
+        LastOffset += Filename.size() + 1;
+        Filenames.push_back(Filename);
+      }
+      return It->second.FilenameID;
     }
 
     void clear() {
@@ -98,17 +90,16 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
     }
   } FileNameRegistry;
 
-  typedef std::map<std::pair<StringRef, StringRef>, std::string>
-      DirAndFilenameToFilepathMapTy;
-  DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap;
-  StringRef getFullFilepath(const MDNode *S);
+  typedef std::map<const DIFile *, std::string> FileToFilepathMapTy;
+  FileToFilepathMapTy FileToFilepathMap;
+  StringRef getFullFilepath(const DIFile *S);
 
   void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
 
   void clear() {
     assert(CurFn == nullptr);
     FileNameRegistry.clear();
-    InstrInfo.clear();
+    LabelsAndLocs.clear();
   }
 
   void emitDebugInfoForFunction(const Function *GV);




More information about the llvm-commits mailing list