From: David Blaikie Date: Mon, 14 Dec 2015 07:42:00 +0000 (+0000) Subject: [llvm-dwp] Deduplicate type units X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=cd49eb3fa17f9f19cfffa9437eb4db10dc11d43c;p=oota-llvm.git [llvm-dwp] Deduplicate type units It's O(N^2) because it does a simple walk through the existing types to find duplicates, but that will be fixed in a follow-up commit to use a mapping data structure of some kind. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255482 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-dwp/Inputs/type_dedup/a.dwo b/test/tools/llvm-dwp/Inputs/type_dedup/a.dwo new file mode 100644 index 00000000000..cfd54c5fbc1 Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/type_dedup/a.dwo differ diff --git a/test/tools/llvm-dwp/Inputs/type_dedup/b.dwo b/test/tools/llvm-dwp/Inputs/type_dedup/b.dwo new file mode 100644 index 00000000000..278369f80d6 Binary files /dev/null and b/test/tools/llvm-dwp/Inputs/type_dedup/b.dwo differ diff --git a/test/tools/llvm-dwp/X86/type_dedup.test b/test/tools/llvm-dwp/X86/type_dedup.test new file mode 100644 index 00000000000..3005705fcaa --- /dev/null +++ b/test/tools/llvm-dwp/X86/type_dedup.test @@ -0,0 +1,35 @@ +RUN: llvm-dwp %p/../Inputs/type_dedup/a.dwo %p/../Inputs/type_dedup/b.dwo -o %t +RUN: llvm-dwarfdump %t | FileCheck %s + +a.cpp: + struct common { }; + common a1; + struct adistinct { }; + adistinct a2; + +b.cpp: + struct common { }; + common b1; + struct bdistinct { }; + bdistinct b2; + +CHECK-LABEL: .debug_types.dwo contents: +CHECK: [[COMMONUOFF:0x[0-9a-f]*]]: +CHECK-LABEL: Type Unit: length = 0x00000020 version = 0x0004 abbr_offset = +CHECK: 0x0000 addr_size = 0x08 type_signature = [[COMMONSIG:0x[0-9a-f]*]] type_offset = 0x[[COMMONOFF:.*]] (next unit at [[AUOFF:.*]]) +CHECK: DW_TAG_type_unit +CHECK: [[COMMONOFF]]: DW_TAG_structure_type +CHECK: DW_AT_name {{.*}} "common" +CHECK: [[AUOFF]]: +CHECK-LABEL: Type Unit: length = 0x00000020 version = 0x0004 abbr_offset = +CHECK: 0x0000 addr_size = 0x08 type_signature = [[ASIG:0x[0-9a-f]*]] type_offset = 0x[[AOFF:.*]] (next unit at [[BUOFF:.*]]) +CHECK: DW_TAG_type_unit +CHECK: 0x00000042: DW_TAG_structure_type +CHECK: DW_AT_name {{.*}} "adistinct" +CHECK: [[BUOFF]]: +CHECK-LABEL: Type Unit: length = 0x00000020 version = 0x0004 abbr_offset = +CHECK: 0x{{.*}} addr_size = 0x08 type_signature = [[BSIG:0x[0-9a-f]*]] type_offset = 0x[[BOFF:.*]] (next unit at [[XUOFF:.*]]) +CHECK: DW_TAG_type_unit +CHECK: 0x00000066: DW_TAG_structure_type +CHECK: DW_AT_name {{.*}} "bdistinct" +CHECK-NOT: Type Unit diff --git a/tools/llvm-dwp/llvm-dwp.cpp b/tools/llvm-dwp/llvm-dwp.cpp index 5d95a751f71..5fb1c52330f 100644 --- a/tools/llvm-dwp/llvm-dwp.cpp +++ b/tools/llvm-dwp/llvm-dwp.cpp @@ -148,24 +148,30 @@ static void addAllTypes(MCStreamer &Out, uint32_t Offset = 0; DataExtractor Data(Types, true, 0); while (Data.isValidOffset(Offset)) { - TypeIndexEntries.push_back(CUEntry); - auto &Entry = TypeIndexEntries.back(); + UnitIndexEntry Entry = CUEntry; // Zero out the debug_info contribution Entry.Contributions[0] = {}; auto &C = Entry.Contributions[DW_SECT_TYPES - DW_SECT_INFO]; - C.Offset = TypesOffset + Offset; + C.Offset = TypesOffset; auto PrevOffset = Offset; // Length of the unit, including the 4 byte length field. C.Length = Data.getU32(&Offset) + 4; - Out.EmitBytes(Types.substr(Offset - 4, C.Length)); - TypesOffset += C.Length; - Data.getU16(&Offset); // Version Data.getU32(&Offset); // Abbrev offset Data.getU8(&Offset); // Address size Entry.Signature = Data.getU64(&Offset); Offset = PrevOffset + C.Length; + + if (any_of(TypeIndexEntries, [&](const UnitIndexEntry &E) { + return E.Signature == Entry.Signature; + })) + continue; + + Out.EmitBytes(Types.substr(PrevOffset, C.Length)); + TypesOffset += C.Length; + + TypeIndexEntries.push_back(Entry); } }