[llvm] r263817 - [codeview] Only emit function ids for inlined functions

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 18 11:54:32 PDT 2016


Author: rnk
Date: Fri Mar 18 13:54:32 2016
New Revision: 263817

URL: http://llvm.org/viewvc/llvm-project?rev=263817&view=rev
Log:
[codeview] Only emit function ids for inlined functions

We aren't referencing any other kind of function currently.
Should save a bit on our debug info size.

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
    llvm/trunk/test/DebugInfo/COFF/inlining-files.ll
    llvm/trunk/test/DebugInfo/COFF/inlining-levels.ll
    llvm/trunk/test/DebugInfo/COFF/inlining.ll
    llvm/trunk/test/DebugInfo/COFF/local-variables.ll
    llvm/trunk/test/DebugInfo/COFF/register-variables.ll

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp?rev=263817&r1=263816&r2=263817&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp Fri Mar 18 13:54:32 2016
@@ -108,12 +108,15 @@ unsigned CodeViewDebug::maybeRecordFile(
 CodeViewDebug::InlineSite &
 CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
                              const DISubprogram *Inlinee) {
-  auto Insertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});
-  InlineSite *Site = &Insertion.first->second;
-  if (Insertion.second) {
+  auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});
+  InlineSite *Site = &SiteInsertion.first->second;
+  if (SiteInsertion.second) {
     Site->SiteFuncId = NextFuncId++;
     Site->Inlinee = Inlinee;
-    InlinedSubprograms.insert(Inlinee);
+    auto InlineeInsertion =
+        SubprogramIndices.insert({Inlinee, InlinedSubprograms.size()});
+    if (InlineeInsertion.second)
+      InlinedSubprograms.push_back(Inlinee);
   }
   return *Site;
 }
@@ -214,7 +217,7 @@ void CodeViewDebug::endModule() {
   // aligned.
 
   // Make a subsection for all the inlined subprograms.
-  emitInlineeLinesSubsection();
+  emitInlineeFuncIdsAndLines();
 
   // Emit per-function debug information.
   for (auto &P : FnDebugInfo)
@@ -241,20 +244,24 @@ static void emitNullTerminatedSymbolName
 }
 
 void CodeViewDebug::emitTypeInformation() {
-  // Start the .debug$T section with 0x4.
-  OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
-  OS.AddComment("Debug section magic");
-  OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
-
+  // Do nothing if we have no debug info or no inlined subprograms.  The types
+  // we currently emit exist only to support inlined call site info.
   NamedMDNode *CU_Nodes =
       MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
   if (!CU_Nodes)
     return;
+  if (InlinedSubprograms.empty())
+    return;
+
+  // Start the .debug$T section with 0x4.
+  OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
+  OS.AddComment("Debug section magic");
+  OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4);
 
   // This type info currently only holds function ids for use with inline call
   // frame info. All functions are assigned a simple 'void ()' type. Emit that
   // type here.
-  TypeIndex ArgListIdx = getNextTypeIndex();
+  unsigned ArgListIndex = getNextTypeIndex();
   OS.AddComment("Type record length");
   OS.EmitIntValue(2 + sizeof(ArgList), 2);
   OS.AddComment("Leaf type: LF_ARGLIST");
@@ -262,7 +269,7 @@ void CodeViewDebug::emitTypeInformation(
   OS.AddComment("Number of arguments");
   OS.EmitIntValue(0, 4);
 
-  TypeIndex VoidProcIdx = getNextTypeIndex();
+  unsigned VoidFnTyIdx = getNextTypeIndex();
   OS.AddComment("Type record length");
   OS.EmitIntValue(2 + sizeof(ProcedureType), 2);
   OS.AddComment("Leaf type: LF_PROCEDURE");
@@ -276,37 +283,35 @@ void CodeViewDebug::emitTypeInformation(
   OS.AddComment("# of parameters");
   OS.EmitIntValue(0, 2);
   OS.AddComment("Argument list type index");
-  OS.EmitIntValue(ArgListIdx.getIndex(), 4);
-
-  for (MDNode *N : CU_Nodes->operands()) {
-    auto *CUNode = cast<DICompileUnit>(N);
-    for (auto *SP : CUNode->getSubprograms()) {
-      StringRef DisplayName = SP->getDisplayName();
-      OS.AddComment("Type record length");
-      MCSymbol *FuncBegin = MMI->getContext().createTempSymbol(),
-               *FuncEnd = MMI->getContext().createTempSymbol();
-      OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 2);
-      OS.EmitLabel(FuncBegin);
-      OS.AddComment("Leaf type: LF_FUNC_ID");
-      OS.EmitIntValue(LF_FUNC_ID, 2);
-
-      OS.AddComment("Scope type index");
-      OS.EmitIntValue(TypeIndex().getIndex(), 4);
-      OS.AddComment("Function type");
-      OS.EmitIntValue(VoidProcIdx.getIndex(), 4);
-      {
-        OS.AddComment("Function name");
-        emitNullTerminatedSymbolName(OS, DisplayName);
-      }
-      OS.EmitLabel(FuncEnd);
+  OS.EmitIntValue(ArgListIndex, 4);
 
-      TypeIndex FuncIdIdx = getNextTypeIndex();
-      SubprogramToFuncId.insert(std::make_pair(SP, FuncIdIdx));
+  // Emit LF_FUNC_ID records for all inlined subprograms to the type stream.
+  // Allocate one type index for each func id.
+  unsigned NextIdx = getNextTypeIndex(InlinedSubprograms.size());
+  assert(NextIdx == FuncIdTypeIndexStart && "func id type indices broken");
+  for (auto *SP : InlinedSubprograms) {
+    StringRef DisplayName = SP->getDisplayName();
+    OS.AddComment("Type record length");
+    MCSymbol *FuncBegin = MMI->getContext().createTempSymbol(),
+             *FuncEnd = MMI->getContext().createTempSymbol();
+    OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 2);
+    OS.EmitLabel(FuncBegin);
+    OS.AddComment("Leaf type: LF_FUNC_ID");
+    OS.EmitIntValue(LF_FUNC_ID, 2);
+
+    OS.AddComment("Scope type index");
+    OS.EmitIntValue(0, 4);
+    OS.AddComment("Function type");
+    OS.EmitIntValue(VoidFnTyIdx, 4);
+    {
+      OS.AddComment("Function name");
+      emitNullTerminatedSymbolName(OS, DisplayName);
     }
+    OS.EmitLabel(FuncEnd);
   }
 }
 
-void CodeViewDebug::emitInlineeLinesSubsection() {
+void CodeViewDebug::emitInlineeFuncIdsAndLines() {
   if (InlinedSubprograms.empty())
     return;
 
@@ -324,9 +329,9 @@ void CodeViewDebug::emitInlineeLinesSubs
   OS.AddComment("Inlinee lines signature");
   OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);
 
+  unsigned InlineeIndex = FuncIdTypeIndexStart;
   for (const DISubprogram *SP : InlinedSubprograms) {
     OS.AddBlankLine();
-    TypeIndex TypeId = SubprogramToFuncId[SP];
     unsigned FileId = maybeRecordFile(SP->getFile());
     OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " +
                   SP->getFilename() + Twine(':') + Twine(SP->getLine()));
@@ -335,11 +340,14 @@ void CodeViewDebug::emitInlineeLinesSubs
     // 1.
     unsigned FileOffset = (FileId - 1) * 8;
     OS.AddComment("Type index of inlined function");
-    OS.EmitIntValue(TypeId.getIndex(), 4);
+    OS.EmitIntValue(InlineeIndex, 4);
     OS.AddComment("Offset into filechecksum table");
     OS.EmitIntValue(FileOffset, 4);
     OS.AddComment("Starting line number");
     OS.EmitIntValue(SP->getLine(), 4);
+
+    // The next inlined subprogram has the next function id.
+    InlineeIndex++;
   }
 
   OS.EmitLabel(InlineEnd);
@@ -362,8 +370,8 @@ void CodeViewDebug::emitInlinedCallSite(
   MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(),
            *InlineEnd = MMI->getContext().createTempSymbol();
 
-  assert(SubprogramToFuncId.count(Site.Inlinee));
-  TypeIndex InlineeIdx = SubprogramToFuncId[Site.Inlinee];
+  assert(SubprogramIndices.count(Site.Inlinee));
+  unsigned InlineeIdx = FuncIdTypeIndexStart + SubprogramIndices[Site.Inlinee];
 
   // SymbolRecord
   OS.AddComment("Record length");
@@ -377,7 +385,7 @@ void CodeViewDebug::emitInlinedCallSite(
   OS.AddComment("PtrEnd");
   OS.EmitIntValue(0, 4);
   OS.AddComment("Inlinee type index");
-  OS.EmitIntValue(InlineeIdx.getIndex(), 4);
+  OS.EmitIntValue(InlineeIdx, 4);
 
   unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
   unsigned StartLineNum = Site.Inlinee->getLine();

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h?rev=263817&r1=263816&r2=263817&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/CodeViewDebug.h Fri Mar 18 13:54:32 2016
@@ -99,8 +99,21 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
   };
   FunctionInfo *CurFn;
 
+  /// The next available function index for use with our .cv_* directives. Not
+  /// to be confused with type indices for LF_FUNC_ID records.
   unsigned NextFuncId = 0;
 
+  /// The next available type index.
+  unsigned NextTypeIndex = llvm::codeview::TypeIndex::FirstNonSimpleIndex;
+
+  /// Get the next type index and reserve it. Can be used to reserve more than
+  /// one type index.
+  unsigned getNextTypeIndex(unsigned NumRecords = 1) {
+    unsigned Result = NextTypeIndex;
+    NextTypeIndex += NumRecords;
+    return Result;
+  }
+
   InlineSite &getInlineSite(const DILocation *InlinedAt,
                             const DISubprogram *Inlinee);
 
@@ -115,17 +128,18 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
   /// Map from DIFile to .cv_file id.
   DenseMap<const DIFile *, unsigned> FileIdMap;
 
-  SmallSetVector<const DISubprogram *, 4> InlinedSubprograms;
+  /// Map from subprogram to index in InlinedSubprograms.
+  DenseMap<const DISubprogram *, size_t> SubprogramIndices;
 
-  DenseMap<const DISubprogram *, codeview::TypeIndex> SubprogramToFuncId;
+  /// All inlined subprograms in the order they should be emitted.
+  SmallVector<const DISubprogram *, 4> InlinedSubprograms;
 
-  unsigned TypeCount = 0;
-
-  /// Gets the next type index and increments the count of types streamed so
-  /// far.
-  codeview::TypeIndex getNextTypeIndex() {
-    return codeview::TypeIndex(codeview::TypeIndex::FirstNonSimpleIndex + TypeCount++);
-  }
+  /// The first type index that refers to an LF_FUNC_ID record. We have one
+  /// record per inlined subprogram.
+  /// FIXME: Keep in sync with emitTypeInformation until we buffer type records
+  /// on the side as we go. Once we buffer type records, we can allocate type
+  /// indices on demand without interleaving our assembly output.
+  unsigned FuncIdTypeIndexStart = NextTypeIndex + 2;
 
   typedef std::map<const DIFile *, std::string> FileToFilepathMapTy;
   FileToFilepathMapTy FileToFilepathMap;
@@ -144,7 +158,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDe
 
   void emitTypeInformation();
 
-  void emitInlineeLinesSubsection();
+  void emitInlineeFuncIdsAndLines();
 
   void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI);
 

Modified: llvm/trunk/test/DebugInfo/COFF/inlining-files.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inlining-files.ll?rev=263817&r1=263816&r2=263817&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/inlining-files.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/inlining-files.ll Fri Mar 18 13:54:32 2016
@@ -24,7 +24,7 @@
 ; OBJ:    InlineSite {
 ; OBJ:      PtrParent: 0x0
 ; OBJ:      PtrEnd: 0x0
-; OBJ:      Inlinee: file_change (0x1003)
+; OBJ:      Inlinee: file_change (0x1002)
 ; OBJ:      BinaryAnnotations [
 ; OBJ:        ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x6, LineOffset: 1}
 ; OBJ:        ChangeFile: D:\src\llvm\build\t.inc (0x8)

Modified: llvm/trunk/test/DebugInfo/COFF/inlining-levels.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inlining-levels.ll?rev=263817&r1=263816&r2=263817&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/inlining-levels.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/inlining-levels.ll Fri Mar 18 13:54:32 2016
@@ -20,13 +20,13 @@
 ; OBJ:   SubSectionType: Symbols (0xF1)
 ; OBJ:   ProcStart {
 ; OBJ:   InlineSite {
-; OBJ:     Inlinee: h (0x1003)
+; OBJ:     Inlinee: h (0x1004)
 ; OBJ:   }
 ; OBJ:   InlineSite {
-; OBJ:     Inlinee: g (0x1004)
+; OBJ:     Inlinee: g (0x1003)
 ; OBJ:   }
 ; OBJ:   InlineSite {
-; OBJ:     Inlinee: f (0x1005)
+; OBJ:     Inlinee: f (0x1002)
 ; OBJ:   }
 ; OBJ:   InlineSiteEnd {
 ; OBJ:   }

Modified: llvm/trunk/test/DebugInfo/COFF/inlining.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/inlining.ll?rev=263817&r1=263816&r2=263817&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/inlining.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/inlining.ll Fri Mar 18 13:54:32 2016
@@ -45,11 +45,11 @@
 ; ASM: [[inline_beg]]:
 ; ASM: .long   0
 ; ASM: # Inlined function bar starts at t.cpp:8
-; ASM: .long   4099
-; ASM: .long   0
-; ASM: .long   8
+; ASM: .long   4098                    # Type index of inlined function
+; ASM: .long   0                       # Offset into filechecksum table
+; ASM: .long   8                       # Starting line number
 ; ASM: # Inlined function foo starts at t.cpp:2
-; ASM: .long   4100
+; ASM: .long   4099
 ; ASM: .long   0
 ; ASM: .long   2
 ; ASM: [[inline_end]]:
@@ -69,16 +69,48 @@
 ; ASM: .short  4430
 ; ASM: .short  4430
 
+; We should only the LF_FUNC_ID records that we needed to reference.
+; OBJ: CodeViewTypes [
+; OBJ:   Section: .debug$T (4)
+; OBJ:   ArgList {
+; OBJ:     TypeLeafKind: LF_ARGLIST (0x1201)
+; OBJ:     TypeIndex: 0x1000
+; OBJ:     NumArgs: 0
+; OBJ:   }
+; OBJ:   ProcedureType {
+; OBJ:     TypeLeafKind: LF_PROCEDURE (0x1008)
+; OBJ:     TypeIndex: 0x1001
+; OBJ:     ReturnType: void (0x3)
+; OBJ:     NumParameters: 0
+; OBJ:     ArgListType: () (0x1000)
+; OBJ:   }
+; OBJ:   FuncId {
+; OBJ:     TypeLeafKind: LF_FUNC_ID (0x1601)
+; OBJ:     TypeIndex: 0x1002
+; OBJ:     ParentScope: 0x0
+; OBJ:     FunctionType: void () (0x1001)
+; OBJ:     Name: bar
+; OBJ:   }
+; OBJ:   FuncId {
+; OBJ:     TypeLeafKind: LF_FUNC_ID (0x1601)
+; OBJ:     TypeIndex: 0x1003
+; OBJ:     ParentScope: 0x0
+; OBJ:     FunctionType: void () (0x1001)
+; OBJ:     Name: foo
+; OBJ:   }
+; OBJ-NOT: TypeLeafKind: LF_FUNC_ID
+; OBJ: ]
+
 ; OBJ: Subsection [
 ; OBJ:   SubSectionType: InlineeLines (0xF6)
 ; OBJ:   SubSectionSize: 0x1C
 ; OBJ:   InlineeSourceLine {
-; OBJ:     Inlinee: bar (0x1003)
+; OBJ:     Inlinee: bar (0x1002)
 ; OBJ:     FileID: D:\src\llvm\build\t.cpp (0x0)
 ; OBJ:     SourceLineNum: 8
 ; OBJ:   }
 ; OBJ:   InlineeSourceLine {
-; OBJ:     Inlinee: foo (0x1004)
+; OBJ:     Inlinee: foo (0x1003)
 ; OBJ:     FileID: D:\src\llvm\build\t.cpp (0x0)
 ; OBJ:     SourceLineNum: 2
 ; OBJ:   }
@@ -103,7 +135,7 @@
 ; OBJ:   InlineSite {
 ; OBJ:     PtrParent: 0x0
 ; OBJ:     PtrEnd: 0x0
-; OBJ:     Inlinee: bar (0x1003)
+; OBJ:     Inlinee: bar (0x1002)
 ; OBJ:     BinaryAnnotations [
 ; OBJ-NEXT:  ChangeCodeOffsetAndLineOffset: {CodeOffset: 0x8, LineOffset: 1}
 ; OBJ-NEXT:  ChangeLineOffset: -6
@@ -119,7 +151,7 @@
 ; OBJ:   InlineSite {
 ; OBJ:     PtrParent: 0x0
 ; OBJ:     PtrEnd: 0x0
-; OBJ:     Inlinee: foo (0x1004)
+; OBJ:     Inlinee: foo (0x1003)
 ; OBJ:     BinaryAnnotations [
 ; OBJ-NEXT:  ChangeCodeOffsetAndLineOffset: {CodeOffset: 0xF, LineOffset: 1}
 ; OBJ-NEXT:  ChangeCodeOffsetAndLineOffset: {CodeOffset: 0xA, LineOffset: 1}

Modified: llvm/trunk/test/DebugInfo/COFF/local-variables.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/local-variables.ll?rev=263817&r1=263816&r2=263817&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/local-variables.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/local-variables.ll Fri Mar 18 13:54:32 2016
@@ -162,7 +162,7 @@
 ; OBJ:    InlineSite {
 ; OBJ:      PtrParent: 0x0
 ; OBJ:      PtrEnd: 0x0
-; OBJ:      Inlinee: will_be_inlined (0x1003)
+; OBJ:      Inlinee: will_be_inlined (0x1002)
 ; OBJ:      BinaryAnnotations [
 ; OBJ:        ChangeLineOffset: 1
 ; OBJ:        ChangeCodeOffset: 0x14
@@ -192,7 +192,7 @@
 ; OBJ:    InlineSite {
 ; OBJ:      PtrParent: 0x0
 ; OBJ:      PtrEnd: 0x0
-; OBJ:      Inlinee: will_be_inlined (0x1003)
+; OBJ:      Inlinee: will_be_inlined (0x1002)
 ; OBJ:      BinaryAnnotations [
 ; OBJ:        ChangeLineOffset: 1
 ; OBJ:        ChangeCodeOffset: 0x35

Modified: llvm/trunk/test/DebugInfo/COFF/register-variables.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/register-variables.ll?rev=263817&r1=263816&r2=263817&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/register-variables.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/register-variables.ll Fri Mar 18 13:54:32 2016
@@ -152,7 +152,7 @@
 ; OBJ:   InlineSite {
 ; OBJ:     PtrParent: 0x0
 ; OBJ:     PtrEnd: 0x0
-; OBJ:     Inlinee: inlineinc (0x1003)
+; OBJ:     Inlinee: inlineinc (0x1002)
 ; OBJ:   }
 ; OBJ:   Local {
 ; OBJ:     Type: int (0x74)




More information about the llvm-commits mailing list