From: David Blaikie Date: Sat, 26 Apr 2014 17:27:38 +0000 (+0000) Subject: DWARF Type Units: Avoid emitting type units under fission if the type requires an... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=4f18a81abade0448785b26692a467c15c461794d;p=oota-llvm.git DWARF Type Units: Avoid emitting type units under fission if the type requires an address. Since there's no way to ensure the type unit in the .dwo and the type unit skeleton in the .o are correlated, this cannot work. This implementation is a bit inefficient for a few reasons, called out in comments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207323 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/AsmPrinter/AddressPool.cpp b/lib/CodeGen/AsmPrinter/AddressPool.cpp index 222717b81b1..8dab5e59d63 100644 --- a/lib/CodeGen/AsmPrinter/AddressPool.cpp +++ b/lib/CodeGen/AsmPrinter/AddressPool.cpp @@ -17,6 +17,7 @@ using namespace llvm; class MCExpr; unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) { + HasBeenUsed = true; auto IterBool = Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS))); return IterBool.first->second.Number; diff --git a/lib/CodeGen/AsmPrinter/AddressPool.h b/lib/CodeGen/AsmPrinter/AddressPool.h index d0c9b0d8577..3058fed33fd 100644 --- a/lib/CodeGen/AsmPrinter/AddressPool.h +++ b/lib/CodeGen/AsmPrinter/AddressPool.h @@ -26,8 +26,11 @@ class AddressPool { AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {} }; DenseMap Pool; + bool HasBeenUsed; public: + AddressPool() : HasBeenUsed(false) {} + /// \brief Returns the index into the address pool with the given /// label/symbol. unsigned getIndex(const MCSymbol *Sym, bool TLS = false); @@ -35,6 +38,10 @@ public: void emit(AsmPrinter &Asm, const MCSection *AddrSection); bool isEmpty() { return Pool.empty(); } + + bool hasBeenUsed() const { return HasBeenUsed; } + + void resetUsedFlag() { HasBeenUsed = false; } }; } #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index cbd2eb6ca44..0465b8929a7 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -2500,19 +2500,28 @@ static uint64_t makeTypeSignature(StringRef Identifier) { void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, DIE &RefDie, DICompositeType CTy) { + // Fast path if we're building some type units and one has already used the + // address pool we know we're going to throw away all this work anyway, so + // don't bother building dependent types. + if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed()) + return; + const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy]; if (TU) { CU.addDIETypeSignature(RefDie, *TU); return; } + bool TopLevelType = TypeUnitsUnderConstruction.empty(); + AddrPool.resetUsedFlag(); + DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit); auto OwnedUnit = make_unique(InfoHolder.getUnits().size(), UnitDie, CU, Asm, this, &InfoHolder, getDwoLineTable(CU)); DwarfTypeUnit &NewTU = *OwnedUnit; TU = &NewTU; - InfoHolder.addUnit(std::move(OwnedUnit)); + TypeUnitsUnderConstruction.push_back(std::make_pair(std::move(OwnedUnit), CTy)); NewTU.addUInt(*UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2, CU.getLanguage()); @@ -2520,9 +2529,7 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, uint64_t Signature = makeTypeSignature(Identifier); NewTU.setTypeSignature(Signature); - if (useSplitDwarf()) - NewTU.setSkeleton(constructSkeletonTU(NewTU)); - else + if (!useSplitDwarf()) CU.applyStmtList(*UnitDie); NewTU.initSection( @@ -2532,6 +2539,36 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU, NewTU.setType(NewTU.createTypeDIE(CTy)); + if (TopLevelType) { + auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction); + TypeUnitsUnderConstruction.clear(); + + // Types referencing entries in the address table cannot be placed in type + // units. + if (AddrPool.hasBeenUsed()) { + + // Remove all the types built while building this type. + // This is pessimistic as some of these types might not be dependent on + // the type that used an address. + for (const auto &TU : TypeUnitsToAdd) + DwarfTypeUnits.erase(TU.second); + + // Construct this type in the CU directly. + // This is inefficient because all the dependent types will be rebuilt + // from scratch, including building them in type units, discovering that + // they depend on addresses, throwing them out and rebuilding them. + CU.constructTypeDIE(RefDie, CTy); + return; + } + + // If the type wasn't dependent on fission addresses, finish adding the type + // and all its dependent types. + for (auto &TU : TypeUnitsToAdd) { + if (useSplitDwarf()) + TU.first->setSkeleton(constructSkeletonTU(*TU.first)); + InfoHolder.addUnit(std::move(TU.first)); + } + } CU.addDIETypeSignature(RefDie, NewTU); } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 9038c648af3..a5bbb251229 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -284,6 +284,8 @@ class DwarfDebug : public AsmPrinterHandler { // them. DenseMap DwarfTypeUnits; + SmallVector, DICompositeType>, 1> TypeUnitsUnderConstruction; + // Whether to emit the pubnames/pubtypes sections. bool HasDwarfPubSections; diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h index 1e64f58fe0d..69774f551be 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -445,6 +445,9 @@ public: virtual DwarfCompileUnit &getCU() = 0; + /// constructTypeDIE - Construct type DIE from DICompositeType. + void constructTypeDIE(DIE &Buffer, DICompositeType CTy); + protected: /// getOrCreateStaticMemberDIE - Create new static data member DIE. DIE *getOrCreateStaticMemberDIE(DIDerivedType DT); @@ -465,9 +468,6 @@ private: /// constructTypeDIE - Construct derived type die from DIDerivedType. void constructTypeDIE(DIE &Buffer, DIDerivedType DTy); - /// constructTypeDIE - Construct type DIE from DICompositeType. - void constructTypeDIE(DIE &Buffer, DICompositeType CTy); - /// constructSubrangeDIE - Construct subrange DIE from DISubrange. void constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy); diff --git a/test/DebugInfo/X86/type_units_with_addresses.ll b/test/DebugInfo/X86/type_units_with_addresses.ll new file mode 100644 index 00000000000..71a84ba36a6 --- /dev/null +++ b/test/DebugInfo/X86/type_units_with_addresses.ll @@ -0,0 +1,109 @@ +; REQUIRES: object-emission + +; RUN: llc -split-dwarf=Enable -filetype=obj -O0 -generate-type-units -mtriple=x86_64-unknown-linux-gnu < %s \ +; RUN: | llvm-dwarfdump - | FileCheck %s + +; RUN: llc -split-dwarf=Disable -filetype=obj -O0 -generate-type-units -mtriple=x86_64-unknown-linux-gnu < %s \ +; RUN: | llvm-dwarfdump - | FileCheck --check-prefix=SINGLE %s + +; CHECK: .debug_info.dwo contents: + +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}}"S1<&i>" + +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}}"S2" +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}}"S2_1<&i>" + +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}}"S3" +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}}"S3_1<&i>" +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_declaration +; CHECK-NEXT: DW_AT_signature + +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}}"S4" +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_declaration +; CHECK-NEXT: DW_AT_signature +; CHECK: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_name {{.*}}"S4_2<&i>" + +; SINGLE: .debug_info contents: + +; SINGLE: DW_TAG_structure_type +; SINGLE-NEXT: DW_AT_declaration +; SINGLE-NEXT: DW_AT_signature + +; SINGLE: DW_TAG_structure_type +; SINGLE-NEXT: DW_AT_declaration +; SINGLE-NEXT: DW_AT_signature + +; SINGLE: DW_TAG_structure_type +; SINGLE-NEXT: DW_AT_declaration +; SINGLE-NEXT: DW_AT_signature + +; SINGLE: DW_TAG_structure_type +; SINGLE-NEXT: DW_AT_declaration +; SINGLE-NEXT: DW_AT_signature + +%struct.S1 = type { i8 } +%struct.S2 = type { %struct.S2_1 } +%struct.S2_1 = type { i8 } +%struct.S3 = type { %struct.S3_1, %struct.S3_2 } +%struct.S3_1 = type { i8 } +%struct.S3_2 = type { i8 } +%struct.S4 = type { %struct.S4_1, %struct.S4_2 } +%struct.S4_1 = type { i8 } +%struct.S4_2 = type { i8 } + +@i = global i32 0, align 4 +@a = global %struct.S1 zeroinitializer, align 1 +@s2 = global %struct.S2 zeroinitializer, align 1 +@s3 = global %struct.S3 zeroinitializer, align 1 +@s4 = global %struct.S4 zeroinitializer, align 1 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!34, !35} +!llvm.ident = !{!36} + +!0 = metadata !{i32 786449, metadata !1, i32 4, metadata !"clang version 3.5.0 ", i1 false, metadata !"", i32 0, metadata !2, metadata !3, metadata !2, metadata !27, metadata !2, metadata !"tu.dwo", i32 1} ; [ DW_TAG_compile_unit ] [/tmp/dbginfo/tu.cpp] [DW_LANG_C_plus_plus] +!1 = metadata !{metadata !"tu.cpp", metadata !"/tmp/dbginfo"} +!2 = metadata !{} +!3 = metadata !{metadata !4, metadata !9, metadata !12, metadata !13, metadata !17, metadata !18, metadata !19, metadata !23, metadata !24} +!4 = metadata !{i32 786451, metadata !1, null, metadata !"S1<&i>", i32 4, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, metadata !5, metadata !"_ZTS2S1IXadL_Z1iEEE"} ; [ DW_TAG_structure_type ] [S1<&i>] [line 4, size 8, align 8, offset 0] [def] [from ] +!5 = metadata !{metadata !6} +!6 = metadata !{i32 786480, null, metadata !"I", metadata !7, i32* @i, null, i32 0, i32 0} ; [ DW_TAG_template_value_parameter ] +!7 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 0, metadata !8} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int] +!8 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] +!9 = metadata !{i32 786451, metadata !1, null, metadata !"S2", i32 11, i64 8, i64 8, i32 0, i32 0, null, metadata !10, i32 0, null, null, metadata !"_ZTS2S2"} ; [ DW_TAG_structure_type ] [S2] [line 11, size 8, align 8, offset 0] [def] [from ] +!10 = metadata !{metadata !11} +!11 = metadata !{i32 786445, metadata !1, metadata !"_ZTS2S2", metadata !"s2_1", i32 12, i64 8, i64 8, i64 0, i32 0, metadata !"_ZTS4S2_1IXadL_Z1iEEE"} ; [ DW_TAG_member ] [s2_1] [line 12, size 8, align 8, offset 0] [from _ZTS4S2_1IXadL_Z1iEEE] +!12 = metadata !{i32 786451, metadata !1, null, metadata !"S2_1<&i>", i32 9, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, metadata !5, metadata !"_ZTS4S2_1IXadL_Z1iEEE"} ; [ DW_TAG_structure_type ] [S2_1<&i>] [line 9, size 8, align 8, offset 0] [def] [from ] +!13 = metadata !{i32 786451, metadata !1, null, metadata !"S3", i32 22, i64 16, i64 8, i32 0, i32 0, null, metadata !14, i32 0, null, null, metadata !"_ZTS2S3"} ; [ DW_TAG_structure_type ] [S3] [line 22, size 16, align 8, offset 0] [def] [from ] +!14 = metadata !{metadata !15, metadata !16} +!15 = metadata !{i32 786445, metadata !1, metadata !"_ZTS2S3", metadata !"s3_1", i32 23, i64 8, i64 8, i64 0, i32 0, metadata !"_ZTS4S3_1IXadL_Z1iEEE"} ; [ DW_TAG_member ] [s3_1] [line 23, size 8, align 8, offset 0] [from _ZTS4S3_1IXadL_Z1iEEE] +!16 = metadata !{i32 786445, metadata !1, metadata !"_ZTS2S3", metadata !"s3_2", i32 24, i64 8, i64 8, i64 8, i32 0, metadata !"_ZTS4S3_2"} ; [ DW_TAG_member ] [s3_2] [line 24, size 8, align 8, offset 8] [from _ZTS4S3_2] +!17 = metadata !{i32 786451, metadata !1, null, metadata !"S3_1<&i>", i32 18, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, metadata !5, metadata !"_ZTS4S3_1IXadL_Z1iEEE"} ; [ DW_TAG_structure_type ] [S3_1<&i>] [line 18, size 8, align 8, offset 0] [def] [from ] +!18 = metadata !{i32 786451, metadata !1, null, metadata !"S3_2", i32 20, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, null, metadata !"_ZTS4S3_2"} ; [ DW_TAG_structure_type ] [S3_2] [line 20, size 8, align 8, offset 0] [def] [from ] +!19 = metadata !{i32 786451, metadata !1, null, metadata !"S4", i32 34, i64 16, i64 8, i32 0, i32 0, null, metadata !20, i32 0, null, null, metadata !"_ZTS2S4"} ; [ DW_TAG_structure_type ] [S4] [line 34, size 16, align 8, offset 0] [def] [from ] +!20 = metadata !{metadata !21, metadata !22} +!21 = metadata !{i32 786445, metadata !1, metadata !"_ZTS2S4", metadata !"s4_1", i32 35, i64 8, i64 8, i64 0, i32 0, metadata !"_ZTS4S4_1"} ; [ DW_TAG_member ] [s4_1] [line 35, size 8, align 8, offset 0] [from _ZTS4S4_1] +!22 = metadata !{i32 786445, metadata !1, metadata !"_ZTS2S4", metadata !"s4_2", i32 36, i64 8, i64 8, i64 8, i32 0, metadata !"_ZTS4S4_2IXadL_Z1iEEE"} ; [ DW_TAG_member ] [s4_2] [line 36, size 8, align 8, offset 8] [from _ZTS4S4_2IXadL_Z1iEEE] +!23 = metadata !{i32 786451, metadata !1, null, metadata !"S4_1", i32 29, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, null, metadata !"_ZTS4S4_1"} ; [ DW_TAG_structure_type ] [S4_1] [line 29, size 8, align 8, offset 0] [def] [from ] +!24 = metadata !{i32 786451, metadata !1, null, metadata !"S4_2<&i>", i32 32, i64 8, i64 8, i32 0, i32 0, null, metadata !2, i32 0, null, metadata !25, metadata !"_ZTS4S4_2IXadL_Z1iEEE"} ; [ DW_TAG_structure_type ] [S4_2<&i>] [line 32, size 8, align 8, offset 0] [def] [from ] +!25 = metadata !{metadata !26} +!26 = metadata !{i32 786480, null, metadata !"T", metadata !7, i32* @i, null, i32 0, i32 0} ; [ DW_TAG_template_value_parameter ] +!27 = metadata !{metadata !28, metadata !30, metadata !31, metadata !32, metadata !33} +!28 = metadata !{i32 786484, i32 0, null, metadata !"i", metadata !"i", metadata !"", metadata !29, i32 1, metadata !8, i32 0, i32 1, i32* @i, null} ; [ DW_TAG_variable ] [i] [line 1] [def] +!29 = metadata !{i32 786473, metadata !1} ; [ DW_TAG_file_type ] [/tmp/dbginfo/tu.cpp] +!30 = metadata !{i32 786484, i32 0, null, metadata !"a", metadata !"a", metadata !"", metadata !29, i32 6, metadata !"_ZTS2S1IXadL_Z1iEEE", i32 0, i32 1, %struct.S1* @a, null} ; [ DW_TAG_variable ] [a] [line 6] [def] +!31 = metadata !{i32 786484, i32 0, null, metadata !"s2", metadata !"s2", metadata !"", metadata !29, i32 15, metadata !"_ZTS2S2", i32 0, i32 1, %struct.S2* @s2, null} ; [ DW_TAG_variable ] [s2] [line 15] [def] +!32 = metadata !{i32 786484, i32 0, null, metadata !"s3", metadata !"s3", metadata !"", metadata !29, i32 27, metadata !"_ZTS2S3", i32 0, i32 1, %struct.S3* @s3, null} ; [ DW_TAG_variable ] [s3] [line 27] [def] +!33 = metadata !{i32 786484, i32 0, null, metadata !"s4", metadata !"s4", metadata !"", metadata !29, i32 39, metadata !"_ZTS2S4", i32 0, i32 1, %struct.S4* @s4, null} ; [ DW_TAG_variable ] [s4] [line 39] [def] +!34 = metadata !{i32 2, metadata !"Dwarf Version", i32 4} +!35 = metadata !{i32 1, metadata !"Debug Info Version", i32 1} +!36 = metadata !{metadata !"clang version 3.5.0 "}