[llvm] r209675 - DebugInfo: Lazily construct subprogram definition DIEs.

David Blaikie dblaikie at gmail.com
Tue May 27 11:37:49 PDT 2014


Author: dblaikie
Date: Tue May 27 13:37:48 2014
New Revision: 209675

URL: http://llvm.org/viewvc/llvm-project?rev=209675&view=rev
Log:
DebugInfo: Lazily construct subprogram definition DIEs.

A further step to correctly emitting concrete out of line definitions
preceeding inlined instances of the same program.

To do this, emission of subprograms must be delayed until required since
we don't know which (abstract only (if there's no out of line
definition), concrete only (if there are no inlined instances), or both)
DIEs are required at the start of the module.

To reduce the test churn in the following commit that actually fixes the
bug, this commit introduces the lazy DIE construction and cleans up test
cases that are impacted by the changes in the resulting DIE ordering.

Modified:
    llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll
    llvm/trunk/test/DebugInfo/X86/debug-info-blocks.ll
    llvm/trunk/test/DebugInfo/X86/inline-member-function.ll
    llvm/trunk/test/DebugInfo/X86/inline-seldag-test.ll
    llvm/trunk/test/DebugInfo/X86/sret.ll
    llvm/trunk/test/DebugInfo/debug-info-qualifiers.ll
    llvm/trunk/test/DebugInfo/namespace.ll
    llvm/trunk/test/DebugInfo/varargs.ll
    llvm/trunk/test/Linker/type-unique-odr-a.ll

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue May 27 13:37:48 2014
@@ -314,7 +314,7 @@ bool DwarfDebug::isSubprogramContext(con
 // scope then create and insert DIEs for these variables.
 DIE &DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit &SPCU,
                                           DISubprogram SP) {
-  DIE *SPDie = SPCU.getDIE(SP);
+  DIE *SPDie = SPCU.getOrCreateSubprogramDIE(SP);
 
   assert(SPDie && "Unable to find subprogram DIE!");
 
@@ -525,15 +525,18 @@ void DwarfDebug::constructAbstractSubpro
 
   DISubprogram SP(Scope->getScopeNode());
 
-  if (!ProcessedSPNodes.insert(SP))
+  DIE *&AbsDef = AbstractSPDies[SP];
+  if (AbsDef)
     return;
 
   // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
   // was inlined from another compile unit.
   DwarfCompileUnit &SPCU = *SPMap[SP];
-  DIE *AbsDef = SPCU.getDIE(SP);
-  assert(AbsDef);
-  AbstractSPDies.insert(std::make_pair(SP, AbsDef));
+  AbsDef = SPCU.getOrCreateSubprogramDIE(SP);
+
+  if (!ProcessedSPNodes.insert(SP))
+    return;
+
   SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
   createAndAddScopeChildren(SPCU, Scope, *AbsDef);
 }
@@ -781,7 +784,7 @@ void DwarfDebug::beginModule() {
       CU.createGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i)));
     DIArray SPs = CUNode.getSubprograms();
     for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
-      constructSubprogramDIE(CU, SPs.getElement(i));
+      SPMap.insert(std::make_pair(SPs.getElement(i), &CU));
     DIArray EnumTypes = CUNode.getEnumTypes();
     for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i)
       CU.getOrCreateTypeDIE(EnumTypes.getElement(i));
@@ -818,8 +821,17 @@ void DwarfDebug::finishSubprogramDefinit
     DIArray Subprograms = TheCU.getSubprograms();
     for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) {
       DISubprogram SP(Subprograms.getElement(i));
-      if (DIE *D = SPCU->getDIE(SP))
-        SPCU->applySubprogramAttributes(SP, *D);
+      // Perhaps the subprogram is in another CU (such as due to comdat
+      // folding, etc), in which case ignore it here.
+      if (SPMap[SP] != SPCU)
+        continue;
+      DIE *D = SPCU->getDIE(SP);
+      if (!D)
+        // Lazily construct the subprogram if we didn't see either concrete or
+        // inlined versions during codegen.
+        D = SPCU->getOrCreateSubprogramDIE(SP);
+      SPCU->applySubprogramAttributes(SP, *D);
+      SPCU->addGlobalName(SP.getName(), *D, resolve(SP.getContext()));
     }
   }
 }
@@ -863,11 +875,11 @@ void DwarfDebug::collectDeadVariables()
 }
 
 void DwarfDebug::finalizeModuleInfo() {
+  finishSubprogramDefinitions();
+
   // Collect info for variables that were optimized out.
   collectDeadVariables();
 
-  finishSubprogramDefinitions();
-
   // Handle anything that needs to be done on a per-unit basis after
   // all other generation.
   for (const auto &TheU : getUnits()) {

Modified: llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll (original)
+++ llvm/trunk/test/DebugInfo/X86/concrete_out_of_line.ll Tue May 27 13:37:48 2014
@@ -14,6 +14,19 @@
 ; CHECK: [[RELEASE_DECL:0x........]]:  DW_TAG_subprogram
 ; CHECK: [[DTOR_DECL:0x........]]:  DW_TAG_subprogram
 
+; CHECK: [[D2_ABS:.*]]: DW_TAG_subprogram
+; CHECK-NEXT:     DW_AT_inline
+; CHECK-NEXT:     DW_AT_{{.*}}linkage_name {{.*}}D2
+; CHECK-NEXT:     DW_AT_specification {{.*}} {[[DTOR_DECL]]}
+; CHECK-NOT:      DW_AT
+; CHECK: DW_TAG
+; CHECK: [[D1_ABS:.*]]: DW_TAG_subprogram
+; CHECK-NEXT:     DW_AT_inline
+; CHECK-NEXT:     DW_AT_{{.*}}linkage_name {{.*}}D1
+; CHECK-NEXT:     DW_AT_specification {{.*}} {[[DTOR_DECL]]}
+; CHECK-NOT:     DW_AT
+; CHECK: [[D1_THIS_ABS:.*]]: DW_TAG_formal_parameter
+
 ; CHECK: [[RELEASE:0x........]]: DW_TAG_subprogram
 ; CHECK:     DW_AT_specification {{.*}} {[[RELEASE_DECL]]}
 ; CHECK: DW_TAG_formal_parameter
@@ -27,29 +40,15 @@
 ; CHECK-NOT: NULL
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_TAG_inlined_subroutine
-; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_ABS:0x........]]}
+; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_ABS]]}
 ; CHECK-NOT: NULL
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_TAG_inlined_subroutine
-; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D2_ABS:0x........]]}
-
-; CHECK: [[D1_ABS]]: DW_TAG_subprogram
-; CHECK-NEXT:     DW_AT_inline
-; CHECK-NEXT:     DW_AT_{{.*}}linkage_name
-; CHECK-NEXT:     DW_AT_specification {{.*}} {[[DTOR_DECL]]}
-; CHECK-NOT:     DW_AT
-; CHECK: [[D1_THIS_ABS:0x........]]: DW_TAG_formal_parameter
-; CHECK: [[D2_ABS]]: DW_TAG_subprogram
-; CHECK-NEXT:     DW_AT_inline
-; CHECK-NEXT:     DW_AT_{{.*}}linkage_name
-; CHECK-NEXT:     DW_AT_specification {{.*}} {[[DTOR_DECL]]}
-; CHECK-NOT:     DW_AT
-; CHECK: DW_TAG
+; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D2_ABS]]}
 
 ; and then that a TAG_subprogram refers to it with AT_abstract_origin.
 
 ; CHECK: DW_TAG_subprogram
-; CHECK: DW_TAG_subprogram
 ; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_ABS]]}
 ; CHECK: DW_TAG_formal_parameter
 ; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_THIS_ABS]]}

Modified: llvm/trunk/test/DebugInfo/X86/debug-info-blocks.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/debug-info-blocks.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/debug-info-blocks.ll (original)
+++ llvm/trunk/test/DebugInfo/X86/debug-info-blocks.ll Tue May 27 13:37:48 2014
@@ -5,6 +5,11 @@
 ; rdar://problem/9279956
 ; test that the DW_AT_location of self is at ( fbreg +{{[0-9]+}}, deref, +{{[0-9]+}} )
 
+; CHECK: [[A:.*]]:   DW_TAG_structure_type
+; CHECK-NEXT: DW_AT_APPLE_objc_complete_type
+; CHECK-NEXT: DW_AT_name{{.*}}"A"
+
+; CHECK: DW_TAG_subprogram
 ; CHECK: DW_TAG_subprogram
 ; CHECK: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
@@ -32,9 +37,6 @@
 ; 0x91 = DW_OP_fbreg
 ; CHECK: DW_AT_location{{.*}}91 {{[0-9]+}} 06 23 {{[0-9]+}} )
 
-; CHECK: [[A:.*]]:   DW_TAG_structure_type
-; CHECK-NEXT: DW_AT_APPLE_objc_complete_type
-; CHECK-NEXT: DW_AT_name{{.*}}"A"
 ; CHECK: [[APTR]]:   DW_TAG_pointer_type
 ; CHECK-NEXT: {[[A]]}
 

Modified: llvm/trunk/test/DebugInfo/X86/inline-member-function.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/inline-member-function.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/inline-member-function.ll (original)
+++ llvm/trunk/test/DebugInfo/X86/inline-member-function.ll Tue May 27 13:37:48 2014
@@ -13,21 +13,24 @@
 ;   return foo().func(i);
 ; }
 
+; CHECK: DW_TAG_structure_type
+; CHECK:   DW_TAG_subprogram
+
+; But make sure we emit DW_AT_object_pointer on the abstract definition.
+; CHECK: [[ABSTRACT_ORIGIN:.*]]: DW_TAG_subprogram
+; CHECK-NOT: NULL
+; CHECK-NOT: TAG
+; CHECK: DW_AT_object_pointer
+
 ; Ensure we omit DW_AT_object_pointer on inlined subroutines.
 ; CHECK: DW_TAG_inlined_subroutine
-; CHECK-NEXT: DW_AT_abstract_origin {{.*}}{[[ABSTRACT_ORIGIN:0x[0-9a-e]*]]}
+; CHECK-NEXT: DW_AT_abstract_origin {{.*}}{[[ABSTRACT_ORIGIN]]}
 ; CHECK-NOT: NULL
 ; CHECK-NOT: DW_AT_object_pointer
 ; CHECK: DW_TAG_formal_parameter
 ; CHECK-NOT: DW_AT_artificial
 ; CHECK: DW_TAG
 
-; But make sure we emit DW_AT_object_pointer on the abstract definition.
-; CHECK: [[ABSTRACT_ORIGIN]]: DW_TAG_subprogram
-; CHECK-NOT: NULL
-; CHECK-NOT: TAG
-; CHECK: DW_AT_object_pointer
-
 %struct.foo = type { i8 }
 
 @i = global i32 0, align 4

Modified: llvm/trunk/test/DebugInfo/X86/inline-seldag-test.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/inline-seldag-test.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/inline-seldag-test.ll (original)
+++ llvm/trunk/test/DebugInfo/X86/inline-seldag-test.ll Tue May 27 13:37:48 2014
@@ -11,12 +11,13 @@
 ;   x = f(x);
 ; }
 
-; CHECK: DW_TAG_inlined_subroutine
-; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[F:0x.*]]}
-; CHECK: [[F]]: DW_TAG_subprogram
+; CHECK: [[F:.*]]: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_name {{.*}} "f"
 
+; CHECK: DW_TAG_inlined_subroutine
+; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[F]]}
+
 
 ; Make sure the condition test is attributed to the inline function, not the
 ; location of the test's operands within the caller.

Modified: llvm/trunk/test/DebugInfo/X86/sret.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/sret.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/X86/sret.ll (original)
+++ llvm/trunk/test/DebugInfo/X86/sret.ll Tue May 27 13:37:48 2014
@@ -3,8 +3,8 @@
 
 ; Based on the debuginfo-tests/sret.cpp code.
 
-; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0xc68148e4333befda)
-; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0xc68148e4333befda)
+; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x72aabf538392d298)
+; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x72aabf538392d298)
 
 %class.A = type { i32 (...)**, i32 }
 %class.B = type { i8 }

Modified: llvm/trunk/test/DebugInfo/debug-info-qualifiers.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/debug-info-qualifiers.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/debug-info-qualifiers.ll (original)
+++ llvm/trunk/test/DebugInfo/debug-info-qualifiers.ll Tue May 27 13:37:48 2014
@@ -21,8 +21,6 @@
 ; CHECK-NEXT: DW_AT_rvalue_reference DW_FORM_flag_present
 ;
 ; CHECK: DW_TAG_subprogram
-;
-; CHECK: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG_subprogram
 ; CHECK:   DW_AT_name {{.*}}"l"
 ; CHECK-NOT: DW_TAG_subprogram

Modified: llvm/trunk/test/DebugInfo/namespace.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/namespace.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/namespace.ll (original)
+++ llvm/trunk/test/DebugInfo/namespace.ll Tue May 27 13:37:48 2014
@@ -16,27 +16,24 @@
 ; CHECK: [[I:0x[0-9a-f]*]]:{{ *}}DW_TAG_variable
 ; CHECK-NEXT: DW_AT_name{{.*}}= "i"
 ; CHECK-NOT: NULL
-; CHECK: DW_TAG_subprogram
+; CHECK: [[FOO:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
+; CHECK-NEXT: DW_AT_name{{.*}}= "foo"
+; CHECK-NEXT: DW_AT_declaration
+; CHECK-NOT: NULL
+; CHECK: [[BAR:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
+; CHECK-NEXT: DW_AT_name{{.*}}= "bar"
+; CHECK: NULL
+; CHECK: [[FUNC1:.*]]: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_MIPS_linkage_name
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_name{{.*}}= "f1"
-; CHECK: [[FUNC1:0x[0-9a-f]*]]:{{ *}}DW_TAG_subprogram
+; CHECK: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_MIPS_linkage_name
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_name{{.*}}= "f1"
 ; CHECK: NULL
-; CHECK-NOT: NULL
-; CHECK: [[FOO:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
-; CHECK-NEXT: DW_AT_name{{.*}}= "foo"
-; CHECK-NEXT: DW_AT_declaration
-; CHECK-NOT: NULL
-; CHECK: [[BAR:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
-; CHECK-NEXT: DW_AT_name{{.*}}= "bar"
-; CHECK: NULL
-; CHECK: NULL
-; CHECK: NULL
 
 ; CHECK-NOT: NULL
 ; CHECK: DW_TAG_imported_module
@@ -48,6 +45,13 @@
 ; CHECK: NULL
 ; CHECK-NOT: NULL
 
+; CHECK: DW_TAG_imported_module
+; Same bug as above, this should be F2, not F1
+; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F1]])
+; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x0b)
+; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]})
+; CHECK-NOT: NULL
+
 ; CHECK: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_MIPS_linkage_name
@@ -99,13 +103,7 @@
 ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS2]]})
 ; CHECK: NULL
 ; CHECK: NULL
-; CHECK-NOT: NULL
-
-; CHECK: DW_TAG_imported_module
-; Same bug as above, this should be F2, not F1
-; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F1]])
-; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x0b)
-; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]})
+; CHECK: NULL
 
 ; CHECK: file_names[  [[F1]]]{{.*}}debug-info-namespace.cpp
 ; CHECK: file_names[  [[F2]]]{{.*}}foo.cpp

Modified: llvm/trunk/test/DebugInfo/varargs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/varargs.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/varargs.ll (original)
+++ llvm/trunk/test/DebugInfo/varargs.ll Tue May 27 13:37:48 2014
@@ -13,25 +13,25 @@
 ;
 ; CHECK: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
-; CHECK: DW_AT_name {{.*}} "b"
+; CHECK: DW_AT_name {{.*}} "a"
+; CHECK-NOT: DW_TAG
+; CHECK: DW_TAG_formal_parameter
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_TAG_formal_parameter
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_TAG_unspecified_parameters
 ;
-; Variadic C++ member function.
-; struct A { void a(int c, ...); }
-;
 ; CHECK: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
-; CHECK: DW_AT_name {{.*}} "a"
-; CHECK-NOT: DW_TAG
-; CHECK: DW_TAG_formal_parameter
+; CHECK: DW_AT_name {{.*}} "b"
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_TAG_formal_parameter
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_TAG_unspecified_parameters
 ;
+; Variadic C++ member function.
+; struct A { void a(int c, ...); }
+;
 ; Variadic function pointer.
 ; void (*fptr)(int, ...);
 ;

Modified: llvm/trunk/test/Linker/type-unique-odr-a.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/type-unique-odr-a.ll?rev=209675&r1=209674&r2=209675&view=diff
==============================================================================
--- llvm/trunk/test/Linker/type-unique-odr-a.ll (original)
+++ llvm/trunk/test/Linker/type-unique-odr-a.ll Tue May 27 13:37:48 2014
@@ -22,12 +22,6 @@
 ;     return A().getFoo();
 ; }
 ;
-; CHECK:      DW_TAG_subprogram
-; CHECK-NOT: DW_TAG
-; CHECK:   DW_AT_MIPS_linkage_name {{.*}} "_Z3bazv"
-; CHECK:      DW_TAG_subprogram
-; CHECK-NOT: DW_TAG
-; CHECK:   DW_AT_MIPS_linkage_name {{.*}} "_ZL3barv"
 ; CHECK:      DW_TAG_class_type
 ; CHECK-NEXT:   DW_AT_name {{.*}} "A"
 ; CHECK-NOT:  DW_TAG
@@ -39,6 +33,12 @@
 ; CHECK:   DW_AT_MIPS_linkage_name {{.*}} "_ZN1A6getFooEv"
 ; CHECK-NOT: DW_TAG
 ; CHECK:   DW_AT_name {{.*}} "getFoo"
+; CHECK:      DW_TAG_subprogram
+; CHECK-NOT: DW_TAG
+; CHECK:   DW_AT_MIPS_linkage_name {{.*}} "_Z3bazv"
+; CHECK:      DW_TAG_subprogram
+; CHECK-NOT: DW_TAG
+; CHECK:   DW_AT_MIPS_linkage_name {{.*}} "_ZL3barv"
 
 ; getFoo and A may only appear once.
 ; CHECK-NOT:  {{(getFoo)|("A")}}





More information about the llvm-commits mailing list