Make DW_AT_[MIPS_]linkage_name optional, and off by default for SCE.
authorPaul Robinson <paul_robinson@playstation.sony.com>
Tue, 11 Aug 2015 21:36:45 +0000 (21:36 +0000)
committerPaul Robinson <paul_robinson@playstation.sony.com>
Tue, 11 Aug 2015 21:36:45 +0000 (21:36 +0000)
Mangled "linkage" names can be huge, and if the debugger (or other
tools) have no use for them, the size savings can be very impressive
(on the order of 40%).

Add one test for controlling behavior, and modify a number of tests to
either stop using linkage names, or make llc emit them (so these tests
will still run when the default triple is for PS4).

Differential Revision: http://reviews.llvm.org/D11374

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

17 files changed:
lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/AsmPrinter/DwarfUnit.cpp
test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll
test/DebugInfo/PR20038.ll
test/DebugInfo/X86/dwarf-linkage-names.ll [new file with mode: 0644]
test/DebugInfo/X86/recursive_inlining.ll
test/DebugInfo/cross-cu-inlining.ll
test/DebugInfo/enum-types.ll
test/DebugInfo/incorrect-variable-debugloc.ll
test/DebugInfo/missing-abstract-variable.ll
test/DebugInfo/namespace.ll
test/DebugInfo/namespace_function_definition.ll
test/DebugInfo/namespace_inline_function_definition.ll
test/Linker/type-unique-odr-a.ll
test/Linker/type-unique-simple2-a.ll
test/Linker/type-unique-type-array-a.ll

index e09a90fbd0b7852d221342b292e02e448ce43baa..4a673d49cedf24524ad4e6dcff0ca0624e31915b 100644 (file)
@@ -116,6 +116,14 @@ DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden,
                             clEnumVal(Disable, "Disabled"), clEnumValEnd),
                  cl::init(Default));
 
+static cl::opt<DefaultOnOff>
+DwarfLinkageNames("dwarf-linkage-names", cl::Hidden,
+                  cl::desc("Emit DWARF linkage-name attributes."),
+                  cl::values(clEnumVal(Default, "Default for platform"),
+                             clEnumVal(Enable, "Enabled"),
+                             clEnumVal(Disable, "Disabled"), clEnumValEnd),
+                  cl::init(Default));
+
 static const char *const DWARFGroupName = "DWARF Emission";
 static const char *const DbgTimerName = "DWARF Debug Writer";
 
@@ -250,6 +258,12 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
   else
     HasDwarfPubSections = DwarfPubSections == Enable;
 
+  // SCE does not use linkage names.
+  if (DwarfLinkageNames == Default)
+    UseLinkageNames = !tuneForSCE();
+  else
+    UseLinkageNames = DwarfLinkageNames == Enable;
+
   unsigned DwarfVersionNumber = Asm->TM.Options.MCOptions.DwarfVersion;
   DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
                                     : MMI->getModule()->getDwarfVersion();
index d17589cba9ef95443ddd645626bb5595a37e3c06..977f340644160fc28574caea1c0d4b7605fc2e00 100644 (file)
@@ -333,6 +333,9 @@ class DwarfDebug : public AsmPrinterHandler {
   /// Whether to use the GNU TLS opcode (instead of the standard opcode).
   bool UseGNUTLSOpcode;
 
+  /// Whether to emit DW_AT_[MIPS_]linkage_name.
+  bool UseLinkageNames;
+
   /// Version of dwarf we're emitting.
   unsigned DwarfVersion;
 
@@ -588,6 +591,9 @@ public:
     SymSize[Sym] = Size;
   }
 
+  /// Returns whether to emit DW_AT_[MIPS_]linkage_name.
+  bool useLinkageNames() const { return UseLinkageNames; }
+
   /// Returns whether to use DW_OP_GNU_push_tls_address, instead of the
   /// standard DW_OP_form_tls_address opcode
   bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; }
index 72b9fe7fd8f926ccf68c8666c88b66dbede81f21..d5ed0cd094580b7b730ce006befda71f3b9d816a 100644 (file)
@@ -667,7 +667,7 @@ void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) {
 }
 
 void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) {
-  if (!LinkageName.empty())
+  if (!LinkageName.empty() && DD->useLinkageNames())
     addString(Die,
               DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name
                                          : dwarf::DW_AT_MIPS_linkage_name,
index b22a48f5516dcaa0513f762d951f99956a579ff4..9f78440fd91748e518cae8d9657408dadc7e88cf 100644 (file)
@@ -13,7 +13,7 @@
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_low_pc
 ; CHECK-NOT: DW_TAG
-; CHECK: DW_AT_linkage_name {{.*}} "_ZZN1B2fnEvEN1A3fooEv"
+; CHECK: DW_AT_name {{.*}} "foo"
 ; And just double check that there's no out of line definition that references
 ; this subprogram.
 ; CHECK-NOT: DW_AT_specification {{.*}} {[[FOO_INL]]}
index 7560130e6d018a09a1a5e239778846b507d148ce..884331d7ea621a0ebe9cc06c1b78af17b77c0caa 100644 (file)
@@ -3,7 +3,7 @@
 ; For some reason, the output when targetting sparc is not quite as expected.
 ; XFAIL: sparc
 
-; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
 
 ; IR generated from clang -O0 with:
 ; struct C {
diff --git a/test/DebugInfo/X86/dwarf-linkage-names.ll b/test/DebugInfo/X86/dwarf-linkage-names.ll
new file mode 100644 (file)
index 0000000..203ad21
--- /dev/null
@@ -0,0 +1,71 @@
+; DWARF linkage name attributes are optional; verify they are missing for
+; PS4 triple or when tuning for SCE.
+
+; RUN: llc -O0 -mtriple=x86_64-unknown-unknown < %s | FileCheck %s -check-prefix LINKAGE1
+; RUN: llc -O0 -mtriple=x86_64-unknown-unknown < %s | FileCheck %s -check-prefix LINKAGE2
+; RUN: llc -O0 -mtriple=x86_64-scei-ps4 < %s | FileCheck %s -check-prefix NOLINKAGE
+; RUN: llc -O0 -mtriple=x86_64-unknown-unknown -debugger-tune=sce < %s | FileCheck %s -check-prefix NOLINKAGE
+
+; $ clang++ -emit-llvm -S -g dwarf-linkage-names.cpp
+; namespace test {
+;  int global_var;
+;  int bar() { return global_var; }
+;};
+
+; With linkage names, we get an attribute for the declaration (first) entry
+; for the global variable, and one for the function.
+
+; This assumes the variable will appear before the function.
+; LINKAGE1: .section .debug_info
+; LINKAGE1: DW_TAG_variable
+; LINKAGE1-NOT: DW_TAG
+; LINKAGE1: {{DW_AT_(MIPS_)*linkage_name}}
+; LINKAGE1: DW_TAG_subprogram
+; LINKAGE1-NOT: DW_TAG
+; LINKAGE1: {{DW_AT_(MIPS_)*linkage_name}}
+; LINKAGE1: .section
+
+; Also verify we see the mangled names. We do this as a separate pass to
+; avoid depending on the order of .debug_info and .debug_str sections.
+
+; LINKAGE2-DAG: .asciz   "_ZN4test10global_varE"
+; LINKAGE2-DAG: .asciz   "_ZN4test3barEv"
+
+; Without linkage names, verify there aren't any linkage-name attributes,
+; and no mangled names.
+
+; NOLINKAGE-NOT: {{DW_AT_(MIPS_)*linkage_name}}
+; NOLINKAGE-NOT: .asciz   "_ZN4test10global_varE"
+; NOLINKAGE-NOT: .asciz   "_ZN4test3barEv"
+
+@_ZN4test10global_varE = global i32 0, align 4
+
+; Function Attrs: nounwind uwtable
+define i32 @_ZN4test3barEv() #0 {
+entry:
+  %0 = load i32, i32* @_ZN4test10global_varE, align 4, !dbg !14
+  ret i32 %0, !dbg !15
+}
+
+attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!11, !12}
+!llvm.ident = !{!13}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 3.8.0 (trunk 244662)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3, globals: !9)
+!1 = !DIFile(filename: "dwarf-linkage-names.cpp", directory: "/home/probinson/projects/scratch")
+!2 = !{}
+!3 = !{!4}
+!4 = !DISubprogram(name: "bar", linkageName: "_ZN4test3barEv", scope: !5, file: !1, line: 3, type: !6, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: false, function: i32 ()* @_ZN4test3barEv, variables: !2)
+!5 = !DINamespace(name: "test", scope: null, file: !1, line: 1)
+!6 = !DISubroutineType(types: !7)
+!7 = !{!8}
+!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!9 = !{!10}
+!10 = !DIGlobalVariable(name: "global_var", linkageName: "_ZN4test10global_varE", scope: !5, file: !1, line: 2, type: !8, isLocal: false, isDefinition: true, variable: i32* @_ZN4test10global_varE)
+!11 = !{i32 2, !"Dwarf Version", i32 4}
+!12 = !{i32 2, !"Debug Info Version", i32 3}
+!13 = !{!"clang version 3.8.0 (trunk 244662)"}
+!14 = !DILocation(line: 3, column: 21, scope: !4)
+!15 = !DILocation(line: 3, column: 14, scope: !4)
index 62c0405200824a0c6ced435eabd367ddcd9ec597..fff5471bb687f2cb5e10c0d1e68a178f88517f18 100644 (file)
 ; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK: DW_TAG_member
 ; CHECK-NOT: {{DW_TAG|NULL}}
-; CHECK: DW_TAG_subprogram
+; CHECK: [[M_FN2_DECL:.*]]: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
 ; CHECK:     DW_AT_name {{.*}} "m_fn2"
 ; CHECK-NOT: {{DW_TAG|NULL}}
-; CHECK: [[M_FN2_THIS_DECL:.*]]:     DW_TAG_formal_parameter
+; CHECK:     DW_TAG_formal_parameter
 
 ; The abstract definition of C::m_fn2
 ; CHECK: [[M_FN2_ABS_DEF:.*]]: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
-; CHECK:   DW_AT_specification {{.*}} "_ZN1C5m_fn2Ev"
+; CHECK:   DW_AT_specification {{.*}} {[[M_FN2_DECL]]}
 ; CHECK-NOT: DW_TAG
 ; CHECK:   DW_AT_inline
 ; CHECK-NOT: {{DW_TAG|NULL}}
@@ -63,7 +63,7 @@
 ; The concrete definition of C::m_fn2
 ; CHECK: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
-; CHECK:   DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]} "_ZN1C5m_fn2Ev"
+; CHECK:   DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]}
 ; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK:   DW_TAG_formal_parameter
 ; CHECK-NOT: DW_TAG
@@ -78,7 +78,7 @@
 ; Inlined C::m_fn2:
 ; CHECK:         DW_TAG_inlined_subroutine
 ; CHECK-NOT: DW_TAG
-; CHECK:           DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]} "_ZN1C5m_fn2Ev"
+; CHECK:           DW_AT_abstract_origin {{.*}} {[[M_FN2_ABS_DEF]]}
 ; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK:           DW_TAG_formal_parameter
 ; CHECK-NOT: DW_TAG
index 7929d5a39e5467b299c614ea36b3860ac3f356dc..3750eab836321cc020bcc0ee4572e1ed56c57477 100644 (file)
@@ -1,7 +1,7 @@
 ; REQUIRES: object-emission
 
-; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck -implicit-check-not=DW_TAG %s
-; RUN: %llc_dwarf -dwarf-accel-tables=Enable -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck --check-prefix=CHECK-ACCEL --check-prefix=CHECK %s
+; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck -implicit-check-not=DW_TAG %s
+; RUN: %llc_dwarf -dwarf-accel-tables=Enable -dwarf-linkage-names=Enable -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck --check-prefix=CHECK-ACCEL --check-prefix=CHECK %s
 
 ; Build from source:
 ; $ clang++ a.cpp b.cpp -g -c -emit-llvm
index 418d7f30cba271fecd90cd7155a37b0b79727f48..048475ef3bbd6b9cc8804fc246001052a481e84b 100644 (file)
@@ -1,6 +1,6 @@
 ; REQUIRES: object-emission
 ;
-; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+; RUN: %llc_dwarf -filetype=obj -O0 -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
 
 ; Make sure we can handle enums with the same identifier but in enum types of
 ; different compile units.
index 86f16ca877949f91e2e6dfe2f9e578b1a054555c..cff254ee3c6c89cf7d914afa08feb80d8780635e 100644 (file)
 
 ; CHECK: DW_TAG_structure_type
 ; CHECK-NEXT: DW_AT_name {{.*}} "C"
-; CHECK:   DW_TAG_subprogram
-; CHECK-NOT: DW_TAG
+; CHECK: [[M_FN3_DECL:.*]]:  DW_TAG_subprogram
+; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK: DW_AT_name {{.*}} "m_fn3"
 
-; CHECK: DW_AT_specification {{.*}} "_ZN1C5m_fn3Ev"
+; CHECK: DW_AT_specification {{.*}} {[[M_FN3_DECL]]}
 ; CHECK-NOT: DW_TAG
 ; CHECK:   DW_TAG_formal_parameter
 ; CHECK-NOT: DW_TAG
index 88b32aad6d5e342fa2a09c27556d14c356f55dca..6273e171483f450e213525478981e0e5d6487eb4 100644 (file)
@@ -37,7 +37,7 @@
 ;   x(u);
 ; }
 
-; CHECK: DW_TAG_subprogram
+; CHECK: [[X_DECL:.*]]: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
 ; CHECK:   DW_AT_name {{.*}} "x"
 ; CHECK-NOT: {{DW_TAG|NULL}}
@@ -57,7 +57,7 @@
 ; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK:   DW_TAG_inlined_subroutine
 ; CHECK-NOT: DW_TAG
-; CHECK:     DW_AT_abstract_origin {{.*}} "_Z1xb"
+; CHECK:     DW_AT_abstract_origin {{.*}} {[[X_DECL]]}
 ; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK:     DW_TAG_formal_parameter
 ; CHECK-NOT: DW_TAG
@@ -78,7 +78,7 @@
 ; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK:   DW_TAG_inlined_subroutine
 ; CHECK-NOT: DW_TAG
-; CHECK:     DW_AT_abstract_origin {{.*}} "_Z1xb"
+; CHECK:     DW_AT_abstract_origin {{.*}} {[[X_DECL]]}
 ; CHECK-NOT: {{DW_TAG|NULL}}
 ; FIXME: This formal parameter goes missing at least at -O2 (& on
 ; mips/powerpc), maybe before that. Perhaps SelectionDAG is to blame (and
index 792981b008783a04733d3a8979fed066f2c40ff1..c43de6b16fae5d6d88c25ba3eb37142ab6ba0c8c 100644 (file)
@@ -1,7 +1,6 @@
 ; REQUIRES: object-emission
 
-; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t
-; RUN: llvm-dwarfdump %t | FileCheck %s
+; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump - | FileCheck %s
 ; CHECK: debug_info contents
 ; CHECK: [[NS1:0x[0-9a-f]*]]:{{ *}}DW_TAG_namespace
 ; CHECK-NEXT: DW_AT_name{{.*}} = "A"
index 5f87cfc90c2bf2dcafb9260da78f071a05f10a5b..6983a687aba81b51db14c0b02dfe2a899e32edef 100644 (file)
@@ -1,6 +1,6 @@
 ; REQUIRES: object-emission
 
-; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
 
 ; Generated from clang with the following source:
 ; namespace ns {
index 99b09c9545ae08835d56762f5a60e0aa758c3bae..abbe9c34e96aceca8f76b919c8237259c2429f0c 100644 (file)
@@ -1,6 +1,6 @@
 ; REQUIRES: object-emission
 
-; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+; RUN: %llc_dwarf -O0 -filetype=obj -dwarf-linkage-names=Enable < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
 
 ; Generate from clang with the following source. Note that the definition of
 ; the inline function follows its use to workaround another bug that should be
index 2ce264b0f9cc9fcd449b25e6e3c189d82d394f52..6f3ee71fe7f6a6b534a92850982dc53ba42e805f 100644 (file)
@@ -1,6 +1,6 @@
 ; REQUIRES: object-emission, native
 ;
-; RUN: llvm-link %s %p/type-unique-odr-b.ll -S -o - | %llc_dwarf -filetype=obj -O0 | llvm-dwarfdump -debug-dump=info - | FileCheck %s
+; RUN: llvm-link %s %p/type-unique-odr-b.ll -S -o - | %llc_dwarf -dwarf-linkage-names=Enable -filetype=obj -O0 | llvm-dwarfdump -debug-dump=info - | FileCheck %s
 ;
 ; Test ODR-based type uniquing for C++ class members.
 ; rdar://problem/15851313.
index 0297717ba216843d2c762fc1d11078556c890538..56682c4babbee9e70e4d8d9ec79dc71d2ea9c928 100644 (file)
@@ -18,7 +18,8 @@
 ;     return A().getFoo();
 ; }
 ;
-; CHECK: _ZN1A6setFooEv
+; CHECK: DW_AT_name {{.*}} "setFoo"
+; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_accessibility [DW_FORM_data1]   (DW_ACCESS_public)
 ; CHECK-NOT: DW_AT_accessibility
 ; CHECK: DW_TAG
index d9387e54020b0afcceeba576e17bfc69ae672440..ca6c2524bb8477f363dd9a744bc06cab8b42efee 100644 (file)
@@ -23,7 +23,7 @@
 ; CHECK: DW_TAG_class_type
 ; CHECK-NEXT:   DW_AT_name {{.*}} "A"
 ; CHECK: DW_TAG_subprogram
-; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN1A5testAE2SA"
+; CHECK: DW_AT_name {{.*}} "testA"
 ; CHECK: DW_TAG_formal_parameter
 ; CHECK: DW_TAG_formal_parameter
 ; CHECK-NEXT: DW_AT_type [DW_FORM_ref4] (cu + 0x{{.*}} => {0x[[STRUCT:.*]]})
@@ -34,7 +34,7 @@
 ; CHECK: DW_TAG_class_type
 ; CHECK-NEXT:   DW_AT_name {{.*}} "B"
 ; CHECK: DW_TAG_subprogram
-; CHECK:   DW_AT_MIPS_linkage_name {{.*}} "_ZN1B5testBE2SA"
+; CHECK:   DW_AT_name {{.*}} "testB"
 ; CHECK: DW_TAG_formal_parameter
 ; CHECK: DW_TAG_formal_parameter
 ; CHECK-NEXT: DW_AT_type [DW_FORM_ref_addr] {{.*}}[[STRUCT]]