]> granicus.if.org Git - clang/commitdiff
DebugInfo: Make DICompositeTypes distinct most of the time
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sun, 17 Apr 2016 07:45:08 +0000 (07:45 +0000)
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>
Sun, 17 Apr 2016 07:45:08 +0000 (07:45 +0000)
Since elements of most kinds of DICompositeType have back references,
most are involved in uniquing cycles.  Except via the ODR 'identifier:'
field, which doesn't care about the storage type (see r266549),
they have no hope of being uniqued.

Distinct nodes are far more efficient, so use them for most kinds of
DICompositeType definitions (i.e., when DIType::isForwardDecl is false).
The exceptions:

  - DW_TAG_array_type, since their elements never have back-references
    and they never have ODR 'identifier:' fields;

  - DW_TAG_enumeration_type when there is no ODR 'identifier:' field,
    since their elements usually don't have back-references.

This breaks the last major uniquing cycle I'm aware of in the debug info
graph.  The impact won't be enormous for C++ because references to
ODR-uniqued nodes still use string-based DITypeRefs; but this should
prevent a regression in C++ when we drop the string-based references.

This wouldn't have been reasonable until r266549, when composite types
stopped relying on being uniqued by structural equivalence to prevent
blow-ups at LTO time.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@266556 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
lib/CodeGen/CGDebugInfo.cpp
test/CodeGenCXX/debug-info-anon-union-vars.cpp
test/CodeGenCXX/debug-info-artificial-arg.cpp
test/CodeGenCXX/debug-info-class.cpp
test/CodeGenCXX/debug-info-template-limit.cpp
test/CodeGenCXX/debug-info-template-member.cpp
test/CodeGenCXX/debug-info-template-quals.cpp
test/CodeGenCXX/debug-info-template.cpp
test/CodeGenCXX/debug-lambda-expressions.cpp
test/Modules/ExtDebugInfo.cpp
test/Modules/ExtDebugInfo.m
test/Modules/ModuleDebugInfo.m

index 6fd0032f84c24e4a1e7e9467877568335449b1ff..ae95dd8ed66fdf72ad88d6db1c8fb878329aee9e 100644 (file)
@@ -2374,6 +2374,30 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
       getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align, 0,
       FullName);
 
+  // Elements of composite types usually have back to the type, creating
+  // uniquing cycles.  Distinct nodes are more efficient.
+  switch (RealDecl->getTag()) {
+  default:
+    llvm_unreachable("invalid composite type tag");
+
+  case llvm::dwarf::DW_TAG_array_type:
+  case llvm::dwarf::DW_TAG_enumeration_type:
+    // Array elements and most enumeration elements don't have back references,
+    // so they don't tend to be involved in uniquing cycles and there is some
+    // chance of merging them when linking together two modules.  Only make
+    // them distinct if they are ODR-uniqued.
+    if (FullName.empty())
+      break;
+
+  case llvm::dwarf::DW_TAG_structure_type:
+  case llvm::dwarf::DW_TAG_union_type:
+  case llvm::dwarf::DW_TAG_class_type:
+    // Immediatley resolve to a distinct node.
+    RealDecl =
+        llvm::MDNode::replaceWithDistinct(llvm::TempDICompositeType(RealDecl));
+    break;
+  }
+
   RegionMap[Ty->getDecl()].reset(RealDecl);
   TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
 
index 80742250d84138de473187cf279257a34a443bfe..b844d429447b724700b7a3dd57f8a257f62bb9ce 100644 (file)
@@ -56,7 +56,7 @@ void instantiate(int x) {
 // CHECK: !DILocalVariable(
 // CHECK-NOT: name:
 // CHECK: type: ![[UNION:[0-9]+]]
-// CHECK: ![[UNION]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
 // CHECK-NOT: name:
 // CHECK: elements
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]],
index c840df672aa025bf4606b39a47e5c0205260695f..e927dc5d734348f77ff65417594ffa487a54cffa 100644 (file)
@@ -22,7 +22,7 @@ int main(int argc, char **argv) {
   A reallyA (500);
 }
 
-// CHECK: ![[CLASSTYPE:.*]] = !DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK: ![[CLASSTYPE:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "A",
 // CHECK-SAME:                                 identifier: "_ZTS1A"
 // CHECK: ![[ARTARG:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1A",
 // CHECK-SAME:                            DIFlagArtificial
index ed52fd05238e93d4bdec07f03375f23f3cb9baad..ece5c945449667abe57fa011a7672a672ab258aa 100644 (file)
@@ -101,7 +101,7 @@ int main(int argc, char **argv) {
 
 // CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
 
-// CHECK: [[C:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "C",
+// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "C",
 // CHECK-NOT:                              DIFlagFwdDecl
 // CHECK-SAME:                             elements: [[C_MEM:![0-9]*]]
 // CHECK-SAME:                             vtableHolder: !"_ZTS1C"
index 5c4ac0cc3e153268201daad72da2a8f10e242145..7e3a4a6959c255ca418fef91e0d43b2eae0edac8 100644 (file)
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited -triple %itanium_abi_triple %s -o - | FileCheck %s
 
 // Check that this pointer type is TC<int>
-// CHECK: ![[LINE:[0-9]+]] = !DICompositeType(tag: DW_TAG_class_type, name: "TC<int>"{{.*}}, identifier: "_ZTS2TCIiE")
+// CHECK: ![[LINE:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "TC<int>"{{.*}}, identifier: "_ZTS2TCIiE")
 // CHECK: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS2TCIiE"
 
 template<typename T>
index a6ba82aa94323bc9a2011e24805a6c582f17328d..dcc464629fd519e5c60f1ea98b1b429f462ea39b 100644 (file)
@@ -24,7 +24,7 @@ inline int add3(int x) {
 // CHECK-SAME:                         type: [[FOO_FUNC_TYPE:![0-9]*]]
 // CHECK: [[FOO_FUNC_TYPE]] = !DISubroutineType(types: [[FOO_FUNC_PARAMS:![0-9]*]])
 // CHECK: [[FOO_FUNC_PARAMS]] = !{null, !{{[0-9]*}}, !"[[OUTER_FOO_INNER_ID:.*]]"}
-// CHECK: !{{[0-9]*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier: "[[OUTER_FOO_INNER_ID]]")
+// CHECK: !{{[0-9]*}} = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier: "[[OUTER_FOO_INNER_ID]]")
 
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "virt<elem>"
 // CHECK-SAME:             elements: [[VIRT_MEM:![0-9]*]]
@@ -34,7 +34,7 @@ inline int add3(int x) {
 // CHECK: [[VIRT_TEMP_PARAM]] = !{[[VIRT_T:![0-9]*]]}
 // CHECK: [[VIRT_T]] = !DITemplateTypeParameter(name: "T", type: !"_ZTS4elem")
 
-// CHECK: [[C:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"
+// CHECK: [[C:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass"
 // CHECK-SAME:                             elements: [[C_MEM:![0-9]*]]
 // CHECK-SAME:                             vtableHolder: !"_ZTS7MyClass"
 // CHECK-SAME:                             identifier: "_ZTS7MyClass")
@@ -43,7 +43,7 @@ inline int add3(int x) {
 
 // CHECK: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 7,
 
-// CHECK: [[ELEM:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "elem"
+// CHECK: [[ELEM:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "elem"
 // CHECK-SAME:                                elements: [[ELEM_MEM:![0-9]*]]
 // CHECK-SAME:                                identifier: "_ZTS4elem"
 // CHECK: [[ELEM_MEM]] = !{[[ELEM_X:![0-9]*]]}
index 1e8bdb1ad714563edf7d12c58bbea9a14389d546..881bb0e20052edb566bad4766fccd1ec1935301e 100644 (file)
@@ -15,7 +15,7 @@ void foo (const char *c) {
   str.assign(c, str);
 }
 
-// CHECK: [[BS:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "basic_string<char>"
+// CHECK: [[BS:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "basic_string<char>"
 // CHECK-SAME:                         line: 4
 // CHECK-SAME:                         size: 8, align: 8
 // CHECK: [[TYPE:![0-9]*]] = !DISubroutineType(types: [[ARGS:.*]])
index 74adef9a5f7aa1f49e00cdff8410bcc7b6ee002e..569357c06199c0c02fd64e4cf5ebefa8318a070b 100644 (file)
@@ -6,7 +6,7 @@
 // CHECK: [[RETAIN]] = !{!{{[0-9]]*}}, [[FOO:![0-9]*]],
 
 
-// CHECK: [[TC:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>"
+// CHECK: [[TC:![0-9]*]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>"
 // CHECK-SAME:                              templateParams: [[TCARGS:![0-9]*]]
 // CHECK: [[TCARGS]] = !{[[TCARG1:![0-9]*]], [[TCARG2:![0-9]*]], [[TCARG3:![0-9]*]], [[TCARG4:![0-9]*]], [[TCARG5:![0-9]*]], [[TCARG6:![0-9]*]], [[TCARG7:![0-9]*]]}
 //
@@ -48,7 +48,7 @@
 // We could just emit a declaration of 'foo' here, rather than the entire
 // definition (same goes for any time we emit a member (function or data)
 // pointer type)
-// CHECK: [[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}identifier: "_ZTS3foo")
+// CHECK: [[FOO]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}identifier: "_ZTS3foo")
 // CHECK: !DISubprogram(name: "f", linkageName: "_ZN3foo1fEv", {{.*}}type: [[FTYPE:![0-9]*]]
 //
 
index 3efdee54c98d9fed3960b2faf26df9000ff95ea9..985234f481f9b1dae7820e5bd390546dcf9babb7 100644 (file)
@@ -23,7 +23,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
 // CHECK: !DIGlobalVariable(name: "cvar"
 // CHECK-SAME:              line: [[CVAR_LINE:[0-9]+]]
 // CHECK-SAME:              type: ![[CVAR_T:[0-9]+]]
-// CHECK: ![[CVAR_T]] = !DICompositeType(tag: DW_TAG_class_type
+// CHECK: ![[CVAR_T]] = distinct !DICompositeType(tag: DW_TAG_class_type
 // CHECK-SAME:                           line: [[CVAR_LINE]],
 // CHECK-SAME:                           elements: ![[CVAR_ARGS:[0-9]+]]
 // CHECK: ![[CVAR_ARGS]] = !{!{{[0-9]+}}}
@@ -32,7 +32,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
 // CHECK: !DIGlobalVariable(name: "var"
 // CHECK-SAME:              line: [[VAR_LINE:[0-9]+]]
 // CHECK-SAME:              type: ![[VAR_T:[0-9]+]]
-// CHECK: ![[VAR_T]] = !DICompositeType(tag: DW_TAG_class_type
+// CHECK: ![[VAR_T]] = distinct !DICompositeType(tag: DW_TAG_class_type
 // CHECK-SAME:                          line: [[VAR_LINE]],
 // CHECK-SAME:                          elements: ![[VAR_ARGS:[0-9]+]]
 // CHECK: ![[VAR_ARGS]] = !{!{{[0-9]+}}}
@@ -41,7 +41,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
 // CHECK: ![[A_FUNC:.*]] = distinct !DISubprogram(name: "a"{{.*}}, line: [[A_LINE:[0-9]+]]{{.*}}, isDefinition: true
 
 // Back to A. -- 78
-// CHECK: ![[LAM_A:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[A_FUNC]]{{.*}}, line: [[A_LINE]],
+// CHECK: ![[LAM_A:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[A_FUNC]]{{.*}}, line: [[A_LINE]],
 // CHECK-SAME:                             elements: ![[LAM_A_ARGS:[0-9]+]]
 // CHECK: ![[LAM_A_ARGS]] = !{![[CON_LAM_A:[0-9]+]]}
 // CHECK: ![[CON_LAM_A]] = !DISubprogram(name: "operator()"
@@ -53,7 +53,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
 // CHECK: ![[B_FUNC:.*]] = distinct !DISubprogram(name: "b"{{.*}}, line: [[B_LINE:[0-9]+]]{{.*}}, isDefinition: true
 
 // Back to B. -- 67
-// CHECK: ![[LAM_B:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[B_FUNC]]{{.*}}, line: [[B_LINE]],
+// CHECK: ![[LAM_B:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[B_FUNC]]{{.*}}, line: [[B_LINE]],
 // CHECK-SAME:                             elements: ![[LAM_B_ARGS:[0-9]+]]
 // CHECK: ![[LAM_B_ARGS]] = !{![[CAP_B:[0-9]+]], ![[CON_LAM_B:[0-9]+]]}
 // CHECK: ![[CAP_B]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
@@ -69,7 +69,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
 // CHECK: ![[C_FUNC:.*]] = distinct !DISubprogram(name: "c"{{.*}}, line: [[C_LINE:[0-9]+]]{{.*}}, isDefinition: true
 
 // Back to C. -- 55
-// CHECK: ![[LAM_C:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[C_FUNC]]{{.*}}, line: [[C_LINE]],
+// CHECK: ![[LAM_C:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[C_FUNC]]{{.*}}, line: [[C_LINE]],
 // CHECK-SAME:                             elements: ![[LAM_C_ARGS:[0-9]+]]
 // CHECK: ![[LAM_C_ARGS]] = !{![[CAP_C:[0-9]+]], ![[CON_LAM_C:[0-9]+]]}
 // CHECK: ![[CAP_C]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
@@ -86,7 +86,7 @@ int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); }
 // CHECK: ![[D_FUNC:.*]] = distinct !DISubprogram(name: "d"{{.*}}, line: [[D_LINE:[0-9]+]]{{.*}}, isDefinition: true
 
 // Back to D. -- 24
-// CHECK: ![[LAM_D:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[D_FUNC]]{{.*}}, line: [[D_LINE]],
+// CHECK: ![[LAM_D:.*]] = distinct !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[D_FUNC]]{{.*}}, line: [[D_LINE]],
 // CHECK-SAME:                             elements: ![[LAM_D_ARGS:[0-9]+]]
 // CHECK: ![[LAM_D_ARGS]] = !{![[CAP_D_X:[0-9]+]], ![[CAP_D_Y:[0-9]+]], ![[CON_LAM_D:[0-9]+]]}
 // CHECK: ![[CAP_D_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x"
index 3b4547a87e04151609852ab3b04f87b8d28c47fd..6c38e7f464a6b7f0fc760ce430e8568615073976 100644 (file)
@@ -91,11 +91,11 @@ void foo() {
 
 // CHECK: !DIGlobalVariable(name: "GlobalUnion",
 // CHECK-SAME:              type: ![[GLOBAL_UNION:[0-9]+]]
-// CHECK: ![[GLOBAL_UNION]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[GLOBAL_UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
 // CHECK-SAME:                elements: !{{[0-9]+}})
 // CHECK: !DIGlobalVariable(name: "GlobalStruct",
 // CHECK-SAME:              type: ![[GLOBAL_STRUCT:[0-9]+]]
-// CHECK: ![[GLOBAL_STRUCT]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK: ![[GLOBAL_STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
 // CHECK-SAME:                elements: !{{[0-9]+}})
 
 // CHECK: !DIGlobalVariable(name: "anon",
index d758bfda8314d2b3e63dc9033a16d6ab076ef7d3..3b907ac729ad947d808066420a3afedf668d9f77 100644 (file)
@@ -32,12 +32,12 @@ int foo(ObjCClass *c) {
 // CHECK: !DIGlobalVariable(name: "GlobalUnion",
 // CHECK-SAME:              type: ![[GLOBAL_UNION:[0-9]+]]
 // CHECK: ![[MOD:.*]] = !DIModule(scope: null, name: "DebugObjC
-// CHECK: ![[GLOBAL_UNION]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[GLOBAL_UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
 // CHECK-SAME:                elements: !{{[0-9]+}})
 
 // CHECK: !DIGlobalVariable(name: "GlobalStruct",
 // CHECK-SAME:              type: ![[GLOBAL_STRUCT:[0-9]+]]
-// CHECK: ![[GLOBAL_STRUCT]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK: ![[GLOBAL_STRUCT]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
 // CHECK-SAME:                elements: !{{[0-9]+}})
 
 // CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefUnion",
index 02ae93feb7969ede6a37fc843a69168d0d400397..360db919ab9cb36b8bda55f888d46989415960d5 100644 (file)
@@ -50,7 +50,7 @@
 // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "FwdDeclared"
 // CHECK-SAME:             elements:
 
-// CHECK: ![[TD_UNION:.*]] = !DICompositeType(tag: DW_TAG_union_type,
+// CHECK: ![[TD_UNION:.*]] = distinct !DICompositeType(tag: DW_TAG_union_type,
 // CHECK-NOT:              name:
 // CHECK-SAME:             elements:
 // CHECK-SAME:             )
@@ -61,7 +61,7 @@
 // CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefEnum",
 // CHECK-SAME:           baseType: ![[TD_ENUM:.*]])
 
-// CHECK: ![[TD_STRUCT:.*]] = !DICompositeType(tag: DW_TAG_structure_type,
+// CHECK: ![[TD_STRUCT:.*]] = distinct !DICompositeType(tag: DW_TAG_structure_type,
 // CHECK-NOT:              name:
 // CHECK-SAME:             elements:
 // CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "TypedefStruct",