diff options
| author | Reid Kleckner <rnk@google.com> | 2016-05-23 20:23:46 +0000 |
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2016-05-23 20:23:46 +0000 |
| commit | 2280f9325e6993df3d858300b9ab6901a6b78ba4 (patch) | |
| tree | 83a2709f00c14302aac6112dfc5c351e909a46ec /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | |
| parent | 91f6f07bb88fd39be8b5e0fd2fdf12903316c662 (diff) | |
| download | bcm5719-llvm-2280f9325e6993df3d858300b9ab6901a6b78ba4.tar.gz bcm5719-llvm-2280f9325e6993df3d858300b9ab6901a6b78ba4.zip | |
Modify emitTypeInformation to use MemoryTypeTableBuilder, take 2
This effectively revers commit r270389 and re-lands r270106, but it's
almost a rewrite.
The behavior change in r270106 was that we could no longer assume that
each LF_FUNC_ID record got its own type index. This patch adds a map
from DINode* to TypeIndex, so we can stop making that assumption.
This change also emits padding bytes between type records similar to the
way MSVC does. The size of the type record includes the padding bytes.
llvm-svn: 270485
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 119 |
1 files changed, 52 insertions, 67 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 06ac58333bc..0eb3e44fba1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -113,14 +113,34 @@ CodeViewDebug::getInlineSite(const DILocation *InlinedAt, if (SiteInsertion.second) { Site->SiteFuncId = NextFuncId++; Site->Inlinee = Inlinee; - auto InlineeInsertion = - SubprogramIndices.insert({Inlinee, InlinedSubprograms.size()}); - if (InlineeInsertion.second) - InlinedSubprograms.push_back(Inlinee); + InlinedSubprograms.insert(Inlinee); + recordFuncIdForSubprogram(Inlinee); } return *Site; } +TypeIndex CodeViewDebug::getGenericFunctionTypeIndex() { + if (VoidFnTyIdx.getIndex() != 0) + return VoidFnTyIdx; + + ArrayRef<TypeIndex> NoArgs; + ArgListRecord ArgListRec(TypeRecordKind::ArgList, NoArgs); + TypeIndex ArgListIndex = TypeTable.writeArgList(ArgListRec); + + ProcedureRecord Procedure(TypeIndex::Void(), CallingConvention::NearC, + FunctionOptions::None, 0, ArgListIndex); + VoidFnTyIdx = TypeTable.writeProcedure(Procedure); + return VoidFnTyIdx; +} + +void CodeViewDebug::recordFuncIdForSubprogram(const DISubprogram *SP) { + TypeIndex ParentScope = TypeIndex(0); + StringRef DisplayName = SP->getDisplayName(); + FuncIdRecord FuncId(ParentScope, getGenericFunctionTypeIndex(), DisplayName); + TypeIndex TI = TypeTable.writeFuncId(FuncId); + TypeIndices[SP] = TI; +} + void CodeViewDebug::recordLocalVariable(LocalVariable &&Var, const DILocation *InlinedAt) { if (InlinedAt) { @@ -244,72 +264,38 @@ static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S) { } void CodeViewDebug::emitTypeInformation() { - // 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. + // Do nothing if we have no debug info or if no non-trivial types were emitted + // to TypeTable during codegen. NamedMDNode *CU_Nodes = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return; - if (InlinedSubprograms.empty()) + if (TypeTable.empty()) return; // Start the .debug$T section with 0x4. OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection()); OS.AddComment("Debug section magic"); + OS.EmitValueToAlignment(4); 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. - unsigned ArgListIndex = getNextTypeIndex(); - OS.AddComment("Type record length"); - OS.EmitIntValue(ArgListRecord::getLayoutSize(), 2); - OS.AddComment("Leaf type: LF_ARGLIST"); - OS.EmitIntValue(LF_ARGLIST, 2); - OS.AddComment("Number of arguments"); - OS.EmitIntValue(0, 4); - - unsigned VoidFnTyIdx = getNextTypeIndex(); - OS.AddComment("Type record length"); - OS.EmitIntValue(ProcedureRecord::getLayoutSize(), 2); - OS.AddComment("Leaf type: LF_PROCEDURE"); - OS.EmitIntValue(LF_PROCEDURE, 2); - OS.AddComment("Return type index"); - OS.EmitIntValue(TypeIndex::Void().getIndex(), 4); - OS.AddComment("Calling convention"); - OS.EmitIntValue(char(CallingConvention::NearC), 1); - OS.AddComment("Function options"); - OS.EmitIntValue(char(FunctionOptions::None), 1); - OS.AddComment("# of parameters"); - OS.EmitIntValue(0, 2); - OS.AddComment("Argument list type index"); - 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()); - (void)NextIdx; - 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); - } + TypeTable.ForEachRecord( + [&](TypeIndex Index, const MemoryTypeTableBuilder::Record *R) { + // Each record should be 4 byte aligned. We achieve that by emitting + // LF_PAD padding bytes. The on-disk record size includes the padding + // bytes so that consumers don't have to skip past them. + uint64_t RecordSize = R->size() + 2; + uint64_t AlignedSize = alignTo(RecordSize, 4); + uint64_t AlignedRecordSize = AlignedSize - 2; + assert(AlignedRecordSize < (1 << 16) && "type record size overflow"); + OS.AddComment("Type record length"); + OS.EmitIntValue(AlignedRecordSize, 2); + OS.AddComment("Type record data"); + OS.EmitBytes(StringRef(R->data(), R->size())); + // Pad the record with LF_PAD bytes. + for (unsigned I = AlignedSize - RecordSize; I > 0; --I) + OS.EmitIntValue(LF_PAD0 + I, 1); + }); } void CodeViewDebug::emitInlineeFuncIdsAndLines() { @@ -330,8 +316,10 @@ void CodeViewDebug::emitInlineeFuncIdsAndLines() { OS.AddComment("Inlinee lines signature"); OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4); - unsigned InlineeIndex = FuncIdTypeIndexStart; for (const DISubprogram *SP : InlinedSubprograms) { + assert(TypeIndices.count(SP)); + TypeIndex InlineeIdx = TypeIndices[SP]; + OS.AddBlankLine(); unsigned FileId = maybeRecordFile(SP->getFile()); OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " + @@ -341,14 +329,11 @@ void CodeViewDebug::emitInlineeFuncIdsAndLines() { // 1. unsigned FileOffset = (FileId - 1) * 8; OS.AddComment("Type index of inlined function"); - OS.EmitIntValue(InlineeIndex, 4); + OS.EmitIntValue(InlineeIdx.getIndex(), 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); @@ -371,8 +356,8 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(), *InlineEnd = MMI->getContext().createTempSymbol(); - assert(SubprogramIndices.count(Site.Inlinee)); - unsigned InlineeIdx = FuncIdTypeIndexStart + SubprogramIndices[Site.Inlinee]; + assert(TypeIndices.count(Site.Inlinee)); + TypeIndex InlineeIdx = TypeIndices[Site.Inlinee]; // SymbolRecord OS.AddComment("Record length"); @@ -386,7 +371,7 @@ void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, OS.AddComment("PtrEnd"); OS.EmitIntValue(0, 4); OS.AddComment("Inlinee type index"); - OS.EmitIntValue(InlineeIdx, 4); + OS.EmitIntValue(InlineeIdx.getIndex(), 4); unsigned FileId = maybeRecordFile(Site.Inlinee->getFile()); unsigned StartLineNum = Site.Inlinee->getLine(); |

