[llvm-dwp] Deduplicate type units
authorDavid Blaikie <dblaikie@gmail.com>
Mon, 14 Dec 2015 07:42:00 +0000 (07:42 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Mon, 14 Dec 2015 07:42:00 +0000 (07:42 +0000)
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

test/tools/llvm-dwp/Inputs/type_dedup/a.dwo [new file with mode: 0644]
test/tools/llvm-dwp/Inputs/type_dedup/b.dwo [new file with mode: 0644]
test/tools/llvm-dwp/X86/type_dedup.test [new file with mode: 0644]
tools/llvm-dwp/llvm-dwp.cpp

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 (file)
index 0000000..cfd54c5
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 (file)
index 0000000..278369f
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 (file)
index 0000000..3005705
--- /dev/null
@@ -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
index 5d95a751f71523588d0f59dc776b44e608b5c339..5fb1c52330f24a46ef8bf1e05915f0b36a03eabe 100644 (file)
@@ -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);
   }
 }