]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/commitdiff
DebugInfo: Lazily attach definition attributes to definitions.
authorDavid Blaikie <dblaikie@gmail.com>
Tue, 27 May 2014 18:37:43 +0000 (18:37 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Tue, 27 May 2014 18:37:43 +0000 (18:37 +0000)
This is a precursor to fixing inlined debug info where the concrete,
out-of-line definition may preceed any inlined usage. To cope with this,
the attributes that may appear on the concrete definition or the
abstract definition are delayed until the end of the module. Then, if an
abstract definition was created, it is referenced (and no other
attributes are added to the out-of-line definition), otherwise the
attributes are added directly to the out-of-line definition.

In a couple of cases this causes not just reordering of attributes, but
reordering of types. When the creation of the attribute is delayed, if
that creation would create a type (such as for a DW_AT_type attribute)
then other top level DIEs may've been constructed during the delay,
causing the referenced type to be created and added after those
intervening DIEs. In the extreme case, in cross-cu-inlining.ll, this
actually causes the DW_TAG_basic_type for "int" to move from one CU to
another.

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

lib/CodeGen/AsmPrinter/DwarfDebug.cpp
lib/CodeGen/AsmPrinter/DwarfDebug.h
lib/CodeGen/AsmPrinter/DwarfUnit.cpp
test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll
test/DebugInfo/X86/concrete_out_of_line.ll
test/DebugInfo/X86/dbg-value-inlined-parameter.ll
test/DebugInfo/X86/debug-info-blocks.ll
test/DebugInfo/X86/empty-and-one-elem-array.ll
test/DebugInfo/cross-cu-inlining.ll
test/DebugInfo/namespace_function_definition.ll

index 5c802f7a2ceb14304ce1ddbbd210d7ec050a2079..6234f12dd2bea914656d51e077bdd647f2e17363 100644 (file)
@@ -806,6 +806,25 @@ void DwarfDebug::beginModule() {
   SectionMap[Asm->getObjFileLowering().getTextSection()];
 }
 
+void DwarfDebug::finishSubprogramDefinitions() {
+  const Module *M = MMI->getModule();
+
+  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
+  for (MDNode *N : CU_Nodes->operands()) {
+    DICompileUnit TheCU(N);
+    // Construct subprogram DIE and add variables DIEs.
+    DwarfCompileUnit *SPCU =
+        static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
+    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);
+    }
+  }
+}
+
+
 // Collect info for variables that were optimized out.
 void DwarfDebug::collectDeadVariables() {
   const Module *M = MMI->getModule();
@@ -847,6 +866,8 @@ void DwarfDebug::finalizeModuleInfo() {
   // 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()) {
index 1b0b1ebafd88fa23e2aa191bd32493df867f15e5..4a4d01246c23be151527bfbe010b60d4318de1a6 100644 (file)
@@ -389,6 +389,8 @@ class DwarfDebug : public AsmPrinterHandler {
   /// \brief Collect info for variables that were optimized out.
   void collectDeadVariables();
 
+  void finishSubprogramDefinitions();
+
   /// \brief Finish off debug information after all functions have been
   /// processed.
   void finalizeModuleInfo();
index c6e47ec072039ab0ca76b57946a19c5e16f2bd9f..2707f8b73d84b2c82837111264edc196194e1b70 100644 (file)
@@ -1389,6 +1389,11 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
   // DW_TAG_inlined_subroutine may refer to this DIE.
   DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
 
+  // Abort here and fill this in later, depending on whether or not this
+  // subprogram turns out to have inlined instances or not.
+  if (SP.isDefinition())
+    return &SPDie;
+
   applySubprogramAttributes(SP, SPDie);
   return &SPDie;
 }
@@ -1397,7 +1402,8 @@ void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie) {
   DIE *DeclDie = nullptr;
   StringRef DeclLinkageName;
   if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
-    DeclDie = getOrCreateSubprogramDIE(SPDecl);
+    DeclDie = getDIE(SPDecl);
+    assert(DeclDie);
     DeclLinkageName = SPDecl.getLinkageName();
   }
 
index e81667f6793cbafbe4103e95f89a6f391f787826..5f7cb696d73855d3198cf23e628a2bbe5b2923a3 100644 (file)
 ; Check that the subprogram inside the class definition has low_pc, only
 ; attached to the definition.
 ; CHECK: [[FOO_INL:0x........]]: DW_TAG_subprogram
-; CHECK-NEXT: DW_AT_MIPS_linkage_name {{.*}} "_ZZN1B2fnEvEN1A3fooEv"
-; CHECK-NOT: NULL
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_low_pc
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZZN1B2fnEvEN1A3fooEv"
 ; And just double check that there's no out of line definition that references
 ; this subprogram.
 ; CHECK-NOT: DW_AT_specification {{.*}} {[[FOO_INL]]}
index a8bf7ca5f9eef1f6fd1b53be4ab734e4e879a9bf..5d4d5802bd1ac2e1824ae987cbb7e72f7c15cbc8 100644 (file)
 ; 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-NEXT:     DW_AT_inline
-; CHECK-NOT:     DW_AT_inline
-; CHECK-NOT: DW_TAG
+; 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-NEXT:     DW_AT_inline
-; CHECK-NOT:     DW_AT_inline
+; CHECK-NOT:     DW_AT
 ; CHECK: DW_TAG
 
 ; and then that a TAG_subprogram refers to it with AT_abstract_origin.
index b901711c2dcf7b0157bdeb04f0550c5a09adaad8..74b2f8bc338c300f469e999324c953c5af4bcf39 100644 (file)
@@ -9,9 +9,9 @@
 ; incorrect. They should be separate
 ; CHECK: [[ABS:.*]]: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
-; CHECK:   DW_AT_name {{.*}} "foo"
-; CHECK-NOT: DW_TAG
 ; CHECK:   DW_AT_high_pc
+; CHECK-NOT: DW_TAG
+; CHECK:   DW_AT_name {{.*}} "foo"
 ; CHECK: [[ABS_SP:.*]]:   DW_TAG_formal_parameter
 ; CHECK-NEXT:     DW_AT_name {{.*}} "sp"
 ; CHECK: [[ABS_NUMS:.*]]:  DW_TAG_formal_parameter
index b2531f64708363a027b29783add50cb145294107..5feab24772395561085e799edd6f00829d330861 100644 (file)
@@ -6,16 +6,20 @@
 ; test that the DW_AT_location of self is at ( fbreg +{{[0-9]+}}, deref, +{{[0-9]+}} )
 
 ; CHECK: DW_TAG_subprogram
-; CHECK: DW_AT_name{{.*}}_block_invoke
+; CHECK: DW_TAG_subprogram
+; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_object_pointer
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_name{{.*}}_block_invoke
 
-; CHECK-NOT: DW_TAG_subprogram
+; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK: DW_TAG_formal_parameter
-; CHECK-NEXT: DW_AT_name{{.*}}.block_descriptor
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_name{{.*}}.block_descriptor
 ; CHECK-NOT: DW_TAG
 ; CHECK: DW_AT_location
 
-; CHECK-NOT: DW_TAG_subprogram
+; CHECK-NOT: {{DW_TAG|NULL}}
 ; CHECK: DW_TAG_variable
 ; CHECK-NEXT: DW_AT_name{{.*}}"self"
 ; CHECK-NOT: DW_TAG
@@ -31,7 +35,7 @@
 ; 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 [5]
+; CHECK: [[APTR]]:   DW_TAG_pointer_type
 ; CHECK-NEXT: {[[A]]}
 
 
index f5c37df1e5e8feeccb3674a0204fd786ff26452f..974bd73479510c2996dff2dbf4e786fe29a2a2d0 100644 (file)
@@ -28,11 +28,6 @@ declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
 ; An empty array should not have an AT_upper_bound attribute. But an array of 1
 ; should.
 
-; CHECK:      DW_TAG_base_type
-; CHECK-NEXT: DW_AT_name [DW_FORM_strp]  ( .debug_str[{{.*}}] = "int")
-; CHECK-NEXT: DW_AT_encoding [DW_FORM_data1]   (0x05)
-; CHECK-NEXT: DW_AT_byte_size [DW_FORM_data1]  (0x04)
-
 ; int foo::b[1]:
 ; CHECK: DW_TAG_structure_type
 ; CHECK: DW_AT_name{{.*}}"foo"
@@ -41,6 +36,11 @@ declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
 ; CHECK-NEXT: DW_AT_name [DW_FORM_strp]  ( .debug_str[{{.*}}] = "b")
 ; CHECK-NEXT: DW_AT_type [DW_FORM_ref4]
 
+; CHECK:      DW_TAG_base_type
+; CHECK-NEXT: DW_AT_name [DW_FORM_strp]  ( .debug_str[{{.*}}] = "int")
+; CHECK-NEXT: DW_AT_encoding [DW_FORM_data1]   (0x05)
+; CHECK-NEXT: DW_AT_byte_size [DW_FORM_data1]  (0x04)
+
 ; int[1]:
 ; CHECK:      DW_TAG_array_type [{{.*}}] *
 ; CHECK-NEXT: DW_AT_type [DW_FORM_ref4]
index 44a1a5850693daee36707014a2fc5f6305439e2f..6e0378d57f0b66505aea8063108091310776a6f6 100644 (file)
 ; CHECK: DW_TAG_compile_unit
 ; CHECK:   DW_AT_name {{.*}} "a.cpp"
 ; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_type [DW_FORM_ref_addr] (0x00000000[[INT:.*]])
 ; CHECK:     DW_TAG_inlined_subroutine
 ; CHECK-NEXT:       DW_AT_abstract_origin {{.*}}[[ABS_FUNC:........]])
 ; CHECK:       DW_TAG_formal_parameter
 ; CHECK-NEXT:         DW_AT_abstract_origin {{.*}}[[ABS_VAR:........]])
-; CHECK: 0x[[INT:.*]]: DW_TAG_base_type
-; CHECK-NOT: DW_TAG
-; CHECK:   DW_AT_name {{.*}} "int"
 
 ; Check the abstract definition is in the 'b.cpp' CU and doesn't contain any
 ; concrete information (address range or variable location)
 ; CHECK: 0x[[ABS_VAR]]: DW_TAG_formal_parameter
 ; CHECK-NOT: DW_TAG
 ; CHECK-NOT: DW_AT_location
-; CHECK: DW_AT_type [DW_FORM_ref_addr] (0x00000000[[INT]])
+; CHECK: DW_AT_type [DW_FORM_ref4] {{.*}} {0x[[INT]]}
 ; CHECK-NOT: DW_AT_location
 
+; CHECK: 0x[[INT]]: DW_TAG_base_type
+; CHECK-NOT: DW_TAG
+; CHECK:   DW_AT_name {{.*}} "int"
+
 ; Check the concrete out of line definition references the abstract and
 ; provides the address range and variable location
 ; CHECK: DW_TAG_subprogram
index 15f39fd6d9d8a9cbd0901ce99ae04917a713c3ba..590f2b301ffe95885153529ea5e0b05f18aaf023 100644 (file)
@@ -12,9 +12,9 @@
 ; CHECK-NEXT: DW_AT_name {{.*}} "ns"
 ; CHECK: DW_TAG_subprogram
 ; CHECK-NOT: DW_TAG
-; CHECK:   DW_AT_MIPS_linkage_name {{.*}} "_ZN2ns4funcEv"
-; CHECK-NOT: DW_TAG
 ; CHECK:   DW_AT_low_pc
+; CHECK-NOT: DW_TAG
+; CHECK:   DW_AT_MIPS_linkage_name {{.*}} "_ZN2ns4funcEv"
 ; CHECK: NULL
 ; CHECK: NULL