DebugInfo: Avoid emitting pubtype entries for type DIEs that just indirect to a type...
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 26 Nov 2013 00:22:37 +0000 (00:22 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 26 Nov 2013 00:22:37 +0000 (00:22 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195698 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
lib/DebugInfo/DWARFContext.cpp
test/DebugInfo/X86/generate-odr-hash.ll

index abb550e0d1d3d0556eec9bf04f93d0d2f8f18858..2316301b4026e8cd7f0d3a4a8c8ece1078592289 100644 (file)
@@ -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
index e47719025c8074fc5d08855add24147519171cc4..eaeb2dcc1c3f421286e422a1f408f1c04d0558a2 100644 (file)
@@ -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 (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 (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))
+           << ' ';
+      }
+      OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
     }
-    OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
   }
 }
 
index f167c86180a9860432fd21a48a49d6c4f501c95a..8ff367fa675dd5c299018b6cbaf720607f8bc477 100644 (file)
@@ -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
 ; 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.<anonymous namespace>::walrus" = type { i8 }