From 999cf05d6afa85c235f5c325ff420d5f768d48d8 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 26 Nov 2013 00:22:37 +0000 Subject: [PATCH] DebugInfo: Avoid emitting pubtype entries for type DIEs that just indirect to a type unit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195698 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 80 +++++++++++---------- lib/DebugInfo/DWARFContext.cpp | 40 ++++++----- test/DebugInfo/X86/generate-odr-hash.ll | 12 +++- 3 files changed, 74 insertions(+), 58 deletions(-) diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index abb550e0d1d..2316301b402 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -929,6 +929,40 @@ DIE *CompileUnit::createTypeDIE(DICompositeType Ty) { return TyDIE; } +/// Return true if the type is appropriately scoped to be contained inside +/// its own type unit. +static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) { + DIScope Parent = DD->resolve(Ty.getContext()); + while (Parent) { + // Don't generate a hash for anything scoped inside a function. + if (Parent.isSubprogram()) + return false; + Parent = DD->resolve(Parent.getContext()); + } + return true; +} + +/// Return true if the type should be split out into a type unit. +static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) { + if (!GenerateTypeUnits) + return false; + + uint16_t Tag = CTy.getTag(); + + switch (Tag) { + case dwarf::DW_TAG_structure_type: + case dwarf::DW_TAG_union_type: + case dwarf::DW_TAG_enumeration_type: + case dwarf::DW_TAG_class_type: + // If this is a class, structure, union, or enumeration type + // that is a definition (not a declaration), and not scoped + // inside a function then separate this out as a type unit. + return !CTy.isForwardDecl() && isTypeUnitScoped(CTy, DD); + default: + return false; + } +} + /// getOrCreateTypeDIE - Find existing DIE or create new DIE for the /// given DIType. DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { @@ -953,9 +987,15 @@ DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) { if (Ty.isBasicType()) constructTypeDIE(*TyDIE, DIBasicType(Ty)); - else if (Ty.isCompositeType()) - constructTypeDIE(*TyDIE, DICompositeType(Ty)); - else { + else if (Ty.isCompositeType()) { + DICompositeType CTy(Ty); + if (shouldCreateTypeUnit(CTy, DD)) { + DD->addTypeUnitType(TyDIE, CTy); + // Skip updating the accellerator tables since this is not the full type + return TyDIE; + } + constructTypeDIEImpl(*TyDIE, CTy); + } else { assert(Ty.isDerivedType() && "Unknown kind of DIType"); constructTypeDIE(*TyDIE, DIDerivedType(Ty)); } @@ -1127,40 +1167,6 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) { addSourceLine(&Buffer, DTy); } -/// Return true if the type is appropriately scoped to be contained inside -/// its own type unit. -static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) { - DIScope Parent = DD->resolve(Ty.getContext()); - while (Parent) { - // Don't generate a hash for anything scoped inside a function. - if (Parent.isSubprogram()) - return false; - Parent = DD->resolve(Parent.getContext()); - } - return true; -} - -/// Return true if the type should be split out into a type unit. -static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) { - if (!GenerateTypeUnits) - return false; - - uint16_t Tag = CTy.getTag(); - - switch (Tag) { - case dwarf::DW_TAG_structure_type: - case dwarf::DW_TAG_union_type: - case dwarf::DW_TAG_enumeration_type: - case dwarf::DW_TAG_class_type: - // If this is a class, structure, union, or enumeration type - // that is a definition (not a declaration), and not scoped - // inside a function then separate this out as a type unit. - return !CTy.isForwardDecl() && isTypeUnitScoped(CTy, DD); - default: - return false; - } -} - /// constructTypeDIE - Construct type DIE from DICompositeType. void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { // If this is a type applicable to a type unit it then add it to the diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp index e47719025c8..eaeb2dcc1c3 100644 --- a/lib/DebugInfo/DWARFContext.cpp +++ b/lib/DebugInfo/DWARFContext.cpp @@ -34,27 +34,29 @@ static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data, OS << "\n." << Name << " contents:\n"; DataExtractor pubNames(Data, LittleEndian, 0); uint32_t offset = 0; - OS << "length = " << format("0x%08x", pubNames.getU32(&offset)); - OS << " version = " << format("0x%04x", pubNames.getU16(&offset)); - OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset)); - OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n'; - if (GnuStyle) - OS << "Offset Linkage Kind Name\n"; - else - OS << "Offset Name\n"; + while (pubNames.isValidOffset(offset)) { + OS << "length = " << format("0x%08x", pubNames.getU32(&offset)); + OS << " version = " << format("0x%04x", pubNames.getU16(&offset)); + OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset)); + OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n'; + if (GnuStyle) + OS << "Offset Linkage Kind Name\n"; + else + OS << "Offset Name\n"; - while (offset < Data.size()) { - uint32_t dieRef = pubNames.getU32(&offset); - if (dieRef == 0) - break; - OS << format("0x%8.8x ", dieRef); - if (GnuStyle) { - PubIndexEntryDescriptor desc(pubNames.getU8(&offset)); - OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage)) - << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind)) - << ' '; + while (offset < Data.size()) { + uint32_t dieRef = pubNames.getU32(&offset); + if (dieRef == 0) + break; + OS << format("0x%8.8x ", dieRef); + if (GnuStyle) { + PubIndexEntryDescriptor desc(pubNames.getU8(&offset)); + OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage)) + << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind)) + << ' '; + } + OS << '\"' << pubNames.getCStr(&offset) << "\"\n"; } - OS << '\"' << pubNames.getCStr(&offset) << "\"\n"; } } diff --git a/test/DebugInfo/X86/generate-odr-hash.ll b/test/DebugInfo/X86/generate-odr-hash.ll index f167c86180a..8ff367fa675 100644 --- a/test/DebugInfo/X86/generate-odr-hash.ll +++ b/test/DebugInfo/X86/generate-odr-hash.ll @@ -1,8 +1,8 @@ ; REQUIRES: object-emission ; RUN: llc %s -o %t -filetype=obj -O0 -generate-type-units -generate-odr-hash -mtriple=x86_64-unknown-linux-gnu -; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s -; +; RUN: llvm-dwarfdump %t | FileCheck %s + ; Generated from: ; struct bar {}; @@ -43,6 +43,8 @@ ; wombat wom; +; CHECK-LABEL: .debug_info contents: + ; Check that we generate a hash for bar and the value. ; CHECK-LABEL: DW_AT_GNU_odr_signature [DW_FORM_data8] (0x200520c0d5b90eff) ; CHECK: DW_TAG_structure_type @@ -89,6 +91,12 @@ ; CHECK: DW_TAG_structure_type ; CHECK-NEXT: debug_str{{.*}}"wombat" +; Don't emit pubtype entries for type DIEs in the compile unit that just indirect to a type unit. +; CHECK-LABEL: .debug_pubtypes contents: +; CHECK-NEXT: unit_offset = 0x00000000 +; CHECK-NEXT: Offset +; CHECK-NEXT: {{^$}} + %struct.bar = type { i8 } %"class.echidna::capybara::mongoose::fluffy" = type { i32, i32 } %"struct.::walrus" = type { i8 }