From: Reid Kleckner Date: Fri, 18 Mar 2016 18:54:32 +0000 (+0000) Subject: [codeview] Only emit function ids for inlined functions X-Git-Tag: llvmorg-3.9.0-rc1~11453 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fbd7787d7e7ef84973c087bef2e7351717cd2fc9;p=platform%2Fupstream%2Fllvm.git [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. llvm-svn: 263817 --- diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 51a71df..9a9ac39 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -108,12 +108,15 @@ unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) { 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(MCStreamer &OS, StringRef S) { } 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(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); - - TypeIndex FuncIdIdx = getNextTypeIndex(); - SubprogramToFuncId.insert(std::make_pair(SP, FuncIdIdx)); + OS.EmitIntValue(ArgListIndex, 4); + + // 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::emitInlineeLinesSubsection() { 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::emitInlineeLinesSubsection() { // 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(const FunctionInfo &FI, 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(const FunctionInfo &FI, 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(); diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h index ce1d8b5..06221d9 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -99,8 +99,21 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { }; 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 CodeViewDebug : public DebugHandlerBase { /// Map from DIFile to .cv_file id. DenseMap FileIdMap; - SmallSetVector InlinedSubprograms; + /// Map from subprogram to index in InlinedSubprograms. + DenseMap SubprogramIndices; - DenseMap SubprogramToFuncId; + /// All inlined subprograms in the order they should be emitted. + SmallVector 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 FileToFilepathMapTy; FileToFilepathMapTy FileToFilepathMap; @@ -144,7 +158,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase { void emitTypeInformation(); - void emitInlineeLinesSubsection(); + void emitInlineeFuncIdsAndLines(); void emitDebugInfoForFunction(const Function *GV, FunctionInfo &FI); diff --git a/llvm/test/DebugInfo/COFF/inlining-files.ll b/llvm/test/DebugInfo/COFF/inlining-files.ll index 6a4cff8..261f0b6 100644 --- a/llvm/test/DebugInfo/COFF/inlining-files.ll +++ b/llvm/test/DebugInfo/COFF/inlining-files.ll @@ -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) diff --git a/llvm/test/DebugInfo/COFF/inlining-levels.ll b/llvm/test/DebugInfo/COFF/inlining-levels.ll index ef6e869..6b09fe2 100644 --- a/llvm/test/DebugInfo/COFF/inlining-levels.ll +++ b/llvm/test/DebugInfo/COFF/inlining-levels.ll @@ -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: } diff --git a/llvm/test/DebugInfo/COFF/inlining.ll b/llvm/test/DebugInfo/COFF/inlining.ll index 2c0ff92..26a2673 100644 --- a/llvm/test/DebugInfo/COFF/inlining.ll +++ b/llvm/test/DebugInfo/COFF/inlining.ll @@ -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} diff --git a/llvm/test/DebugInfo/COFF/local-variables.ll b/llvm/test/DebugInfo/COFF/local-variables.ll index dcfcec5..2c9141f 100644 --- a/llvm/test/DebugInfo/COFF/local-variables.ll +++ b/llvm/test/DebugInfo/COFF/local-variables.ll @@ -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 diff --git a/llvm/test/DebugInfo/COFF/register-variables.ll b/llvm/test/DebugInfo/COFF/register-variables.ll index d970e16..80cd672 100644 --- a/llvm/test/DebugInfo/COFF/register-variables.ll +++ b/llvm/test/DebugInfo/COFF/register-variables.ll @@ -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)