[llvm] f19471a - [DebugInfo] Only create concrete DIEs of concrete functions

Kyungwoo Lee via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 9 10:52:53 PST 2021


Author: Ellis Hoag
Date: 2021-11-09T10:52:34-08:00
New Revision: f19471a24985a0cbc32b6548c8fce1d2514e8243

URL: https://github.com/llvm/llvm-project/commit/f19471a24985a0cbc32b6548c8fce1d2514e8243
DIFF: https://github.com/llvm/llvm-project/commit/f19471a24985a0cbc32b6548c8fce1d2514e8243.diff

LOG: [DebugInfo] Only create concrete DIEs of concrete functions

At the begining of the module we can iterate through the functions to
see which SPs should have concrete DIEs. Then when we need to reference
a DIE for a SP we can decide if it's ok to create a concrete DIE or not.

Fixes
 * https://bugs.llvm.org/show_bug.cgi?id=52159
 * https://bugs.llvm.org/show_bug.cgi?id=30637

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D112337

Added: 
    llvm/test/DebugInfo/Generic/import-inlined-declaration.ll
    llvm/test/DebugInfo/Generic/inlined-local-type.ll
    llvm/test/DebugInfo/Generic/inlined-static-var.ll

Modified: 
    llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
    llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
    llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index f51fb041f559..07aa02952e3e 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -1118,9 +1118,14 @@ void DwarfCompileUnit::constructAbstractSubprogramScopeDIE(
     ContextCU = DD->lookupCU(ContextDIE->getUnitDie());
   }
 
-  // Passing null as the associated node because the abstract definition
-  // shouldn't be found by lookup.
-  AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, nullptr);
+  // The abstract definition can only be looked up from the associated node if
+  // the subprogram does not have a concrete function.
+  if (!ContextCU->DD->IsConcrete(SP))
+    AbsDef = ContextCU->getDIE(SP);
+  if (!AbsDef)
+    AbsDef = &ContextCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE,
+                                         nullptr);
+
   ContextCU->applySubprogramAttributesToDefinition(SP, *AbsDef);
   ContextCU->addSInt(*AbsDef, dwarf::DW_AT_inline,
                      DD->getDwarfVersion() <= 4 ? Optional<dwarf::Form>()
@@ -1302,7 +1307,7 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
 void DwarfCompileUnit::finishSubprogramDefinition(const DISubprogram *SP) {
   DIE *D = getDIE(SP);
   if (DIE *AbsSPDIE = getAbstractSPDies().lookup(SP)) {
-    if (D)
+    if (D && D != AbsSPDIE)
       // If this subprogram has an abstract definition, reference that
       addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
   } else {

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 9388cd6fce69..344ac873c934 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1156,6 +1156,12 @@ void DwarfDebug::beginModule(Module *M) {
   assert(MMI->hasDebugInfo() &&
          "DebugInfoAvailabilty unexpectedly not initialized");
   SingleCU = NumDebugCUs == 1;
+
+  for (const auto &F : M->functions())
+    if (!F.isDeclaration())
+      if (const auto *SP = F.getSubprogram())
+        ConcreteSPs.insert(SP);
+
   DenseMap<DIGlobalVariable *, SmallVector<DwarfCompileUnit::GlobalExpr, 1>>
       GVMap;
   for (const GlobalVariable &Global : M->globals()) {

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 6de095617477..23eb80fb6aec 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -315,11 +315,18 @@ class DwarfDebug : public DebugHandlerBase {
   /// can refer to them in spite of insertions into this list.
   DebugLocStream DebugLocs;
 
+  using SubprogramSetVector =
+      SetVector<const DISubprogram *, SmallVector<const DISubprogram *, 16>,
+                SmallPtrSet<const DISubprogram *, 16>>;
+
   /// This is a collection of subprogram MDNodes that are processed to
   /// create DIEs.
-  SetVector<const DISubprogram *, SmallVector<const DISubprogram *, 16>,
-            SmallPtrSet<const DISubprogram *, 16>>
-      ProcessedSPNodes;
+  SubprogramSetVector ProcessedSPNodes;
+
+  /// The set of subprograms that have concrete functions.
+  /// This does not include subprograms of machine outlined functions because
+  /// they are created after this set is computed.
+  SubprogramSetVector ConcreteSPs;
 
   /// If nonnull, stores the current machine function we're processing.
   const MachineFunction *CurFn = nullptr;
@@ -851,6 +858,14 @@ class DwarfDebug : public DebugHandlerBase {
   /// If the \p File has an MD5 checksum, return it as an MD5Result
   /// allocated in the MCContext.
   Optional<MD5::MD5Result> getMD5AsBytes(const DIFile *File) const;
+
+  /// Returns true if the subprogram has a function that will be emitted.
+  /// Returns false for subprograms of machine outlined functions even when
+  /// they do have concrete instances, but they should never have abstract
+  /// subprograms anyway.
+  bool IsConcrete(const DISubprogram *SP) const {
+    return ConcreteSPs.count(SP);
+  }
 };
 
 } // end namespace llvm

diff  --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 976e35905144..63cbfdef8430 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1146,6 +1146,11 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) {
     }
   }
 
+  // Try to reference the abstract origin if the subprogram is not concrete.
+  if (!DD->IsConcrete(SP))
+    if (auto *SPDie = DU->getAbstractSPDies().lookup(SP))
+      return SPDie;
+
   // DW_TAG_inlined_subroutine may refer to this DIE.
   DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
 

diff  --git a/llvm/test/DebugInfo/Generic/import-inlined-declaration.ll b/llvm/test/DebugInfo/Generic/import-inlined-declaration.ll
new file mode 100644
index 000000000000..47833a3e829e
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/import-inlined-declaration.ll
@@ -0,0 +1,72 @@
+; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump - | FileCheck --implicit-check-not "{{DW_TAG|NULL}}" %s
+
+; namespace ns {
+; inline __attribute__((always_inline))
+; void foo() { int a = 4; }
+; }
+;
+; void goo() {
+;   using ns::foo;
+;   foo();
+; }
+
+; Ensure that imported declarations reference the correct subprograms even if
+; those subprograms are inlined.
+
+; CHECK: DW_TAG_compile_unit
+; CHECK:   DW_TAG_namespace
+; CHECK:     DW_AT_name     ("ns")
+; CHECK: [[FOO:0x.*]]:     DW_TAG_subprogram
+; CHECK:       DW_AT_name   ("foo")
+; CHECK:       DW_TAG_variable
+; CHECK:       NULL
+; CHECK:     NULL
+; CHECK:   DW_TAG_base_type
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_name     ("goo")
+; CHECK:     DW_TAG_imported_declaration
+; CHECK:       DW_AT_import ([[FOO]])
+; CHECK:     DW_TAG_inlined_subroutine
+; CHECK:       DW_AT_abstract_origin ([[FOO]]
+; CHECK:       DW_TAG_variable
+; CHECK:       NULL
+; CHECK:     NULL
+; CHECK:   NULL
+
+; Function Attrs: mustprogress noinline optnone uwtable
+define dso_local void @_Z3goov() !dbg !4 {
+entry:
+  %a.i = alloca i32, align 4
+  call void @llvm.dbg.declare(metadata i32* %a.i, metadata !16, metadata !DIExpression()), !dbg !18
+  store i32 4, i32* %a.i, align 4, !dbg !18
+  ret void, !dbg !20
+}
+
+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!10, !11, !12, !13, !14}
+!llvm.ident = !{!15}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, imports: !2, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "imported-inlined-declaration.cpp", directory: "")
+!2 = !{!3}
+!3 = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !4, entity: !8, file: !1, line: 7)
+!4 = distinct !DISubprogram(name: "goo", linkageName: "_Z3goov", scope: !1, file: !1, line: 6, type: !5, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !7)
+!5 = !DISubroutineType(types: !6)
+!6 = !{null}
+!7 = !{}
+!8 = distinct !DISubprogram(name: "foo", linkageName: "_ZN2ns3fooEv", scope: !9, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !7)
+!9 = !DINamespace(name: "ns", scope: null)
+!10 = !{i32 7, !"Dwarf Version", i32 4}
+!11 = !{i32 2, !"Debug Info Version", i32 3}
+!12 = !{i32 1, !"wchar_size", i32 4}
+!13 = !{i32 7, !"uwtable", i32 1}
+!14 = !{i32 7, !"frame-pointer", i32 2}
+!15 = !{!"clang version 14.0.0"}
+!16 = !DILocalVariable(name: "a", scope: !8, file: !1, line: 3, type: !17)
+!17 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!18 = !DILocation(line: 3, column: 18, scope: !8, inlinedAt: !19)
+!19 = distinct !DILocation(line: 8, column: 2, scope: !4)
+!20 = !DILocation(line: 9, column: 1, scope: !4)

diff  --git a/llvm/test/DebugInfo/Generic/inlined-local-type.ll b/llvm/test/DebugInfo/Generic/inlined-local-type.ll
new file mode 100644
index 000000000000..5589cf3e4130
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/inlined-local-type.ll
@@ -0,0 +1,125 @@
+; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --implicit-check-not "{{DW_TAG|NULL}}" %s
+
+; inline __attribute__((always_inline))
+; int removed() { struct A {int i;}; struct A a; return a.i++; }
+;
+; __attribute__((always_inline))
+; int not_removed() { struct B {int i;}; struct B b; return b.i++; }
+;
+; int foo() { return removed() + not_removed(); }}
+
+; Ensure that function-local types have the correct subprogram parent even if
+; those subprograms are inlined.
+
+; CHECK: DW_TAG_compile_unit
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_abstract_origin	({{0x.*}} "not_removed")
+; CHECK:     DW_TAG_variable
+; CHECK: [[B:0x.*]]: DW_TAG_structure_type
+; CHECK:       DW_AT_name	("B")
+; CHECK:       DW_TAG_member
+; CHECK:       NULL
+; CHECK:     NULL
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_name	("removed")
+; CHECK: [[A:0x.*]]: DW_TAG_structure_type
+; CHECK:       DW_AT_name	("A")
+; CHECK:       DW_TAG_member
+; CHECK:       NULL
+; CHECK:     DW_TAG_variable
+; CHECK:       DW_AT_type	([[A]] "A")
+; CHECK:     NULL
+; CHECK:   DW_TAG_base_type
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_name	("not_removed")
+; CHECK:     DW_TAG_variable
+; CHECK:       DW_AT_type	([[B]] "B")
+; CHECK:     NULL
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_TAG_inlined_subroutine
+; CHECK:       DW_TAG_variable
+; CHECK:       NULL
+; CHECK:     DW_TAG_inlined_subroutine
+; CHECK:       DW_TAG_variable
+; CHECK:       NULL
+; CHECK:     NULL
+; CHECK:   NULL
+
+%struct.B = type { i32 }
+%struct.A = type { i32 }
+
+define dso_local i32 @not_removed() !dbg !12 {
+  %1 = alloca %struct.B, align 4
+  call void @llvm.dbg.declare(metadata %struct.B* %1, metadata !18, metadata !DIExpression()), !dbg !22
+  %2 = getelementptr inbounds %struct.B, %struct.B* %1, i32 0, i32 0, !dbg !23
+  %3 = load i32, i32* %2, align 4, !dbg !24
+  %4 = add nsw i32 %3, 1, !dbg !24
+  store i32 %4, i32* %2, align 4, !dbg !24
+  ret i32 %3, !dbg !25
+}
+
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+define dso_local i32 @foo() !dbg !26 {
+  %1 = alloca %struct.A, align 4
+  %2 = alloca %struct.B, align 4
+  call void @llvm.dbg.declare(metadata %struct.A* %1, metadata !27, metadata !DIExpression()), !dbg !32
+  %3 = getelementptr inbounds %struct.A, %struct.A* %1, i32 0, i32 0, !dbg !34
+  %4 = load i32, i32* %3, align 4, !dbg !35
+  %5 = add nsw i32 %4, 1, !dbg !35
+  store i32 %5, i32* %3, align 4, !dbg !35
+  call void @llvm.dbg.declare(metadata %struct.B* %2, metadata !18, metadata !DIExpression()), !dbg !36
+  %6 = getelementptr inbounds %struct.B, %struct.B* %2, i32 0, i32 0, !dbg !38
+  %7 = load i32, i32* %6, align 4, !dbg !39
+  %8 = add nsw i32 %7, 1, !dbg !39
+  store i32 %8, i32* %6, align 4, !dbg !39
+  %9 = add nsw i32 %4, %7, !dbg !40
+  ret i32 %9, !dbg !41
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8, !9, !10}
+!llvm.ident = !{!11}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "inlined-local-type.cpp", directory: "")
+!2 = !{i32 7, !"Dwarf Version", i32 4}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 1, !"branch-target-enforcement", i32 0}
+!6 = !{i32 1, !"sign-return-address", i32 0}
+!7 = !{i32 1, !"sign-return-address-all", i32 0}
+!8 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!9 = !{i32 7, !"uwtable", i32 1}
+!10 = !{i32 7, !"frame-pointer", i32 1}
+!11 = !{!"clang version 14.0.0"}
+!12 = distinct !DISubprogram(name: "not_removed", scope: !13, file: !13, line: 5, type: !14, scopeLine: 5, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17)
+!13 = !DIFile(filename: "inlined-local-type.cpp", directory: "")
+!14 = !DISubroutineType(types: !15)
+!15 = !{!16}
+!16 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!17 = !{}
+!18 = !DILocalVariable(name: "b", scope: !12, file: !13, line: 5, type: !19)
+!19 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "B", scope: !12, file: !13, line: 5, size: 32, elements: !20)
+!20 = !{!21}
+!21 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !19, file: !13, line: 5, baseType: !16, size: 32)
+!22 = !DILocation(line: 5, column: 49, scope: !12)
+!23 = !DILocation(line: 5, column: 61, scope: !12)
+!24 = !DILocation(line: 5, column: 62, scope: !12)
+!25 = !DILocation(line: 5, column: 52, scope: !12)
+!26 = distinct !DISubprogram(name: "foo", scope: !13, file: !13, line: 7, type: !14, scopeLine: 7, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17)
+!27 = !DILocalVariable(name: "a", scope: !28, file: !13, line: 2, type: !29)
+!28 = distinct !DISubprogram(name: "removed", scope: !13, file: !13, line: 2, type: !14, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !17)
+!29 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "A", scope: !28, file: !13, line: 2, size: 32, elements: !30)
+!30 = !{!31}
+!31 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !29, file: !13, line: 2, baseType: !16, size: 32)
+!32 = !DILocation(line: 2, column: 45, scope: !28, inlinedAt: !33)
+!33 = distinct !DILocation(line: 7, column: 20, scope: !26)
+!34 = !DILocation(line: 2, column: 57, scope: !28, inlinedAt: !33)
+!35 = !DILocation(line: 2, column: 58, scope: !28, inlinedAt: !33)
+!36 = !DILocation(line: 5, column: 49, scope: !12, inlinedAt: !37)
+!37 = distinct !DILocation(line: 7, column: 32, scope: !26)
+!38 = !DILocation(line: 5, column: 61, scope: !12, inlinedAt: !37)
+!39 = !DILocation(line: 5, column: 62, scope: !12, inlinedAt: !37)
+!40 = !DILocation(line: 7, column: 30, scope: !26)
+!41 = !DILocation(line: 7, column: 13, scope: !26)

diff  --git a/llvm/test/DebugInfo/Generic/inlined-static-var.ll b/llvm/test/DebugInfo/Generic/inlined-static-var.ll
new file mode 100644
index 000000000000..720d4cab4829
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/inlined-static-var.ll
@@ -0,0 +1,94 @@
+; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-info - | FileCheck --implicit-check-not "{{DW_TAG|NULL}}" %s
+
+; inline __attribute__((always_inline))
+; int removed() { static int A; return A++; }
+;
+; __attribute__((always_inline))
+; int not_removed() { static int B; return B++; }
+;
+; int foo() { return removed() + not_removed(); }
+
+; Ensure that global variables belong to the correct subprograms even if those
+; subprograms are inlined.
+
+; CHECK: DW_TAG_compile_unit
+; CHECK:   DW_TAG_subprogram
+; TODO: Place the variable in the abstract DIE rather than this concrete DIE.
+; CHECK:     DW_TAG_variable
+; CHECK:       DW_AT_name     ("B")
+; CHECK:     NULL
+; CHECK:   DW_TAG_base_type
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_name       ("removed")
+; CHECK:     DW_TAG_variable
+; CHECK:       DW_AT_name     ("A")
+; CHECK:     NULL
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_name       ("not_removed")
+; CHECK:   DW_TAG_subprogram
+; CHECK:     DW_AT_name       ("foo")
+; CHECK:     DW_TAG_inlined_subroutine
+; CHECK:     DW_TAG_inlined_subroutine
+; CHECK:     NULL
+; CHECK:   NULL
+
+$_ZZ7removedvE1A = comdat any
+
+ at _ZZ11not_removedvE1A = internal global i32 0, align 4, !dbg !0
+ at _ZZ7removedvE1A = linkonce_odr dso_local global i32 0, comdat, align 4, !dbg !10
+
+define dso_local i32 @_Z11not_removedv() !dbg !2 {
+  %1 = load i32, i32* @_ZZ11not_removedvE1A, align 4, !dbg !24
+  %2 = add nsw i32 %1, 1, !dbg !24
+  store i32 %2, i32* @_ZZ11not_removedvE1A, align 4, !dbg !24
+  ret i32 %1, !dbg !25
+}
+
+define dso_local i32 @_Z3foov() !dbg !26 {
+  %1 = load i32, i32* @_ZZ7removedvE1A, align 4, !dbg !27
+  %2 = add nsw i32 %1, 1, !dbg !27
+  store i32 %2, i32* @_ZZ7removedvE1A, align 4, !dbg !27
+  %3 = load i32, i32* @_ZZ11not_removedvE1A, align 4, !dbg !29
+  %4 = add nsw i32 %3, 1, !dbg !29
+  store i32 %4, i32* @_ZZ11not_removedvE1A, align 4, !dbg !29
+  %5 = add nsw i32 %1, %3, !dbg !31
+  ret i32 %5, !dbg !32
+}
+
+!llvm.dbg.cu = !{!7}
+!llvm.module.flags = !{!14, !15, !16, !17, !18, !19, !20, !21, !22}
+!llvm.ident = !{!23}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "B", scope: !2, file: !3, line: 5, type: !6, isLocal: true, isDefinition: true)
+!2 = distinct !DISubprogram(name: "not_removed", linkageName: "_Z11not_removedv", scope: !3, file: !3, line: 5, type: !4, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !13)
+!3 = !DIFile(filename: "example.cpp", directory: "")
+!4 = !DISubroutineType(types: !5)
+!5 = !{!6}
+!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !8, producer: "clang version 14.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !9, splitDebugInlining: false, nameTableKind: None)
+!8 = !DIFile(filename: "example.cpp", directory: "")
+!9 = !{!0, !10}
+!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression())
+!11 = distinct !DIGlobalVariable(name: "A", scope: !12, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true)
+!12 = distinct !DISubprogram(name: "removed", linkageName: "_Z7removedv", scope: !3, file: !3, line: 2, type: !4, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !13)
+!13 = !{}
+!14 = !{i32 7, !"Dwarf Version", i32 4}
+!15 = !{i32 2, !"Debug Info Version", i32 3}
+!16 = !{i32 1, !"wchar_size", i32 4}
+!17 = !{i32 1, !"branch-target-enforcement", i32 0}
+!18 = !{i32 1, !"sign-return-address", i32 0}
+!19 = !{i32 1, !"sign-return-address-all", i32 0}
+!20 = !{i32 1, !"sign-return-address-with-bkey", i32 0}
+!21 = !{i32 7, !"uwtable", i32 1}
+!22 = !{i32 7, !"frame-pointer", i32 1}
+!23 = !{!"clang version 14.0.0"}
+!24 = !DILocation(line: 5, column: 43, scope: !2)
+!25 = !DILocation(line: 5, column: 35, scope: !2)
+!26 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", scope: !3, file: !3, line: 7, type: !4, scopeLine: 7, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !13)
+!27 = !DILocation(line: 2, column: 39, scope: !12, inlinedAt: !28)
+!28 = distinct !DILocation(line: 7, column: 20, scope: !26)
+!29 = !DILocation(line: 5, column: 43, scope: !2, inlinedAt: !30)
+!30 = distinct !DILocation(line: 7, column: 32, scope: !26)
+!31 = !DILocation(line: 7, column: 30, scope: !26)
+!32 = !DILocation(line: 7, column: 13, scope: !26)


        


More information about the llvm-commits mailing list