-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[DebugInfo][DWARF] Emit DW_AT_abstract_origin for concrete/inlined DW_TAG_lexical_blocks #136205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DebugInfo][DWARF] Emit DW_AT_abstract_origin for concrete/inlined DW_TAG_lexical_blocks #136205
Conversation
@llvm/pr-subscribers-debuginfo Author: Vladislav Dzhidzhoev (dzhidzhoev) ChangesDuring the discussion under #119001, it was noticed that concrete DW_TAG_lexical_blocks should refer to corresponding abstract DW_TAG_lexical_blocks by having DW_AT_abstract_origin, to avoid ambiguity. This behavior is implemented in GCC (https://godbolt.org/z/Khrzdq1Wx), but not in LLVM. Fixes #49297. Full diff: https://github.com/llvm/llvm-project/pull/136205.diff 7 Files Affected:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 3939dae81841f..c57722216ea8d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -782,6 +782,8 @@ DIE *DwarfCompileUnit::constructLexicalScopeDIE(LexicalScope *Scope) {
assert(!LexicalBlockDIEs.count(DS) &&
"Concrete out-of-line DIE for this scope exists!");
LexicalBlockDIEs[DS] = ScopeDIE;
+ } else {
+ InlinedLocalScopeDIEs[DS].push_back(ScopeDIE);
}
attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
@@ -1491,6 +1493,20 @@ void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
getDwarfDebug().addAccelName(*this, CUNode->getNameTableKind(), Name, *Die);
}
+void DwarfCompileUnit::attachLexicalScopesAbstractOrigins(
+ LexicalScopes &LScopes) {
+ auto AttachAO = [&](const DILocalScope *LS, DIE *ScopeDIE) {
+ if (auto *AbsLSDie = getAbstractScopeDIEs().lookup(LS))
+ addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *AbsLSDie);
+ };
+
+ for (auto [LScope, ScopeDIE] : LexicalBlockDIEs)
+ AttachAO(LScope, ScopeDIE);
+ for (auto &[LScope, ScopeDIEs] : InlinedLocalScopeDIEs)
+ for (auto *ScopeDIE : ScopeDIEs)
+ AttachAO(LScope, ScopeDIE);
+}
+
DbgEntity *DwarfCompileUnit::getExistingAbstractEntity(const DINode *Node) {
auto &AbstractEntities = getAbstractEntities();
auto I = AbstractEntities.find(Node);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index 104039db03c7c..8a9493d9294cd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -82,6 +82,10 @@ class DwarfCompileUnit final : public DwarfUnit {
// List of abstract local scopes (either DISubprogram or DILexicalBlock).
DenseMap<const DILocalScope *, DIE *> AbstractLocalScopeDIEs;
+ // List of inlined lexical block scopes that belong to subprograms within this
+ // CU.
+ DenseMap<const DILocalScope *, SmallVector<DIE *, 2>> InlinedLocalScopeDIEs;
+
DenseMap<const DINode *, std::unique_ptr<DbgEntity>> AbstractEntities;
/// DWO ID for correlating skeleton and split units.
@@ -299,6 +303,7 @@ class DwarfCompileUnit final : public DwarfUnit {
void finishSubprogramDefinition(const DISubprogram *SP);
void finishEntityDefinition(const DbgEntity *Entity);
+ void attachLexicalScopesAbstractOrigins(LexicalScopes &LScopes);
/// Find abstract variable associated with Var.
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 39f1299a24e81..93f9184c71c7f 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1262,6 +1262,7 @@ void DwarfDebug::finalizeModuleInfo() {
auto &TheCU = *P.second;
if (TheCU.getCUNode()->isDebugDirectivesOnly())
continue;
+ TheCU.attachLexicalScopesAbstractOrigins(LScopes);
// Emit DW_AT_containing_type attribute to connect types with their
// vtable holding type.
TheCU.constructContainingTypeDIEs();
diff --git a/llvm/test/DebugInfo/Generic/inline-scopes.ll b/llvm/test/DebugInfo/Generic/inline-scopes.ll
index 8e7543eb16e69..45ecdd0594f64 100644
--- a/llvm/test/DebugInfo/Generic/inline-scopes.ll
+++ b/llvm/test/DebugInfo/Generic/inline-scopes.ll
@@ -20,16 +20,29 @@
; }
; Ensure that lexical_blocks within inlined_subroutines are preserved/emitted.
+; CHECK: DW_TAG_subprogram
+; CHECK-NEXT: DW_AT_linkage_name ("_Z2f1v")
+; CHECK: [[ADDR1:0x[0-9a-f]+]]: DW_TAG_lexical_block
+; CHECK: DW_TAG_subprogram
+; CHECK-NEXT: DW_AT_linkage_name ("_Z2f2v")
+; CHECK: [[ADDR2:0x[0-9a-f]+]]: DW_TAG_lexical_block
; CHECK: DW_TAG_inlined_subroutine
; CHECK-NOT: DW_TAG
; CHECK-NOT: NULL
-; CHECK: DW_TAG_lexical_block
+; CHECK: DW_TAG_lexical_block
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_AT_abstract_origin ([[ADDR1]]
; CHECK-NOT: DW_TAG
; CHECK-NOT: NULL
; CHECK: DW_TAG_variable
; Ensure that file changes don't interfere with creating inlined subroutines.
; (see the line directive inside 'f2' in thesource)
; CHECK: DW_TAG_inlined_subroutine
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_TAG_lexical_block
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_AT_abstract_origin ([[ADDR2]]
+; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_variable
; CHECK-NOT: DW_TAG
; CHECK: DW_AT_abstract_origin
diff --git a/llvm/test/DebugInfo/Generic/lexical-block-abstract-origin.ll b/llvm/test/DebugInfo/Generic/lexical-block-abstract-origin.ll
new file mode 100644
index 0000000000000..cbe2b818fba38
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/lexical-block-abstract-origin.ll
@@ -0,0 +1,56 @@
+; RUN: %llc_dwarf -filetype=obj -O0 %s -o - | llvm-dwarfdump -debug-info - | FileCheck %s
+
+; Check that DW_AT_abstract_origin is generated for concrete lexical block.
+
+; Generated from:
+; inline __attribute__((always_inline)) int foo(int x) {
+; {
+; int y = x + 5;
+; return y - 10;
+; }
+; }
+;
+; int bar(int x) {
+; int y = foo(7);
+; return y + 8;
+; }
+
+; CHECK: DW_TAG_subprogram
+; CHECK-NEXT: DW_AT_name ("foo")
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: [[LB:.*]]: DW_TAG_lexical_block
+
+; CHECK: DW_TAG_inlined_subroutine
+; CHECK-NEXT: DW_AT_abstract_origin {{.*}} "foo"
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_TAG_lexical_block
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_AT_abstract_origin {{.*}}[[LB]]
+
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "arm64-apple-macosx15.0.0"
+
+define i32 @bar() !dbg !9 {
+entry:
+ %y.i = alloca i32, align 4
+ #dbg_declare(ptr %y.i, !22, !DIExpression(), !24)
+ store i32 0, ptr %y.i, align 4, !dbg !24
+ %1 = load i32, ptr %y.i, align 4
+ ret i32 %1
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, emissionKind: FullDebug)
+!1 = !DIFile(filename: "test.c", directory: "")
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!9 = distinct !DISubprogram(name: "bar", scope: !1, file: !1, line: 8, type: !10, spFlags: DISPFlagDefinition, unit: !0)
+!10 = !DISubroutineType(types: !13)
+!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!13 = !{}
+!19 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !0)
+!21 = distinct !DILocation(line: 9, column: 11, scope: !9)
+!22 = !DILocalVariable(name: "y", scope: !23, file: !1, line: 3, type: !12)
+!23 = distinct !DILexicalBlock(scope: !19, file: !1, line: 2, column: 3)
+!24 = !DILocation(line: 3, column: 9, scope: !23, inlinedAt: !21)
diff --git a/llvm/test/DebugInfo/X86/lexical-block-file-inline.ll b/llvm/test/DebugInfo/X86/lexical-block-file-inline.ll
index 15d0785bde93d..43c5e7ccef8c6 100644
--- a/llvm/test/DebugInfo/X86/lexical-block-file-inline.ll
+++ b/llvm/test/DebugInfo/X86/lexical-block-file-inline.ll
@@ -28,9 +28,11 @@
; CHECK: DW_TAG_subprogram
; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_AT_abstract_origin {{.*}} {[[Offset_bar:0x[0-9abcdef]+]]}
-; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_lexical_block
-; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_AT_abstract_origin {{.*}}[[Offset_lb:0x[0-9a-f]+]]
+; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_variable
;; Abstract "bar" function
@@ -40,7 +42,7 @@
; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_AT_inline
; CHECK-NOT: {{DW_TAG|NULL}}
-; CHECK: DW_TAG_lexical_block
+; CHECK: [[Offset_lb]]: DW_TAG_lexical_block
; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_variable
; CHECK-NOT: {{DW_TAG|NULL}}
@@ -56,8 +58,10 @@
; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[Offset_bar]]}
; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_lexical_block
-; CHECK-NOT: {{DW_TAG|NULL}}
-; CHECK: DW_TAG_variable
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_AT_abstract_origin {{.*}}[[Offset_lb]]
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_TAG_variable
; Function Attrs: alwaysinline nounwind
define i32 @_Z3barv() #0 !dbg !4 {
diff --git a/llvm/test/DebugInfo/X86/missing-abstract-variable.ll b/llvm/test/DebugInfo/X86/missing-abstract-variable.ll
index 572dca2c2cb6c..21363805aff2f 100644
--- a/llvm/test/DebugInfo/X86/missing-abstract-variable.ll
+++ b/llvm/test/DebugInfo/X86/missing-abstract-variable.ll
@@ -37,7 +37,7 @@
; CHECK-NOT: DW_TAG
; CHECK: DW_AT_name ("b")
; CHECK-NOT: {{DW_TAG|NULL}}
-; CHECK: DW_TAG_lexical_block
+; CHECK: [[LB_DECL:.*]]: DW_TAG_lexical_block
; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_variable
; CHECK-NOT: DW_TAG
@@ -82,7 +82,9 @@
; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_lexical_block
-; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK-NOT: {{DW_TAG|NULL}}
+; CHECK: DW_AT_abstract_origin {{.*}}[[LB_DECL]]
+; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_variable
; CHECK-NOT: DW_TAG
; CHECK: DW_AT_abstract_origin {{.*}} "s"
|
…_TAG_lexical_blocks During the discussion under llvm#119001, it was noticed, that concrete DW_TAG_lexical_blocks should refer to corresponding abstract DW_TAG_lexical_blocks to avoid ambiguity. This behavior is implemented in GCC (https://godbolt.org/z/Khrzdq1Wx), but not in LLVM so far. Fixes llvm#49297.
cb3f994
to
34da121
Compare
I think this is the right direction, and I'm not sure what we'll do about it if we have to do anything, but... could you measure the size impact of this change? (use Bloaty's comparison mode to compare, say, a Release built clang built with a compiler with/without this change) |
Sure!
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks!
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/23533 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/9117 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/46/builds/15718 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/133/builds/15049 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/140/builds/21898 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/154/builds/15279 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/139/builds/14030 Here is the relevant piece of the build log for the reference
|
…lined DW_TAG_lexical_blocks" (#137237) Reverts #136205 Breaks buildbots, probably something about needing to restrict the test to running on a specific target or the like - I haven't looked closely. Co-authored-by: Vladislav Dzhidzhoev <[email protected]>
Oops, I have (apparently) fixed these failures in 92dc18b. |
…concrete/inlined DW_TAG_lexical_blocks" (#137237) Reverts llvm/llvm-project#136205 Breaks buildbots, probably something about needing to restrict the test to running on a specific target or the like - I haven't looked closely. Co-authored-by: Vladislav Dzhidzhoev <[email protected]>
…_TAG_lexical_blocks (llvm#136205) During the discussion under llvm#119001, it was noticed that concrete DW_TAG_lexical_blocks should refer to corresponding abstract DW_TAG_lexical_blocks by having DW_AT_abstract_origin, to avoid ambiguity. This behavior is implemented in GCC (https://godbolt.org/z/Khrzdq1Wx), but not in LLVM. Fixes llvm#49297.
…lined DW_TAG_lexical_blocks" (llvm#137237) Reverts llvm#136205 Breaks buildbots, probably something about needing to restrict the test to running on a specific target or the like - I haven't looked closely. Co-authored-by: Vladislav Dzhidzhoev <[email protected]>
…_TAG_lexical_blocks (llvm#136205) During the discussion under llvm#119001, it was noticed that concrete DW_TAG_lexical_blocks should refer to corresponding abstract DW_TAG_lexical_blocks by having DW_AT_abstract_origin, to avoid ambiguity. This behavior is implemented in GCC (https://godbolt.org/z/Khrzdq1Wx), but not in LLVM. Fixes llvm#49297.
…lined DW_TAG_lexical_blocks" (llvm#137237) Reverts llvm#136205 Breaks buildbots, probably something about needing to restrict the test to running on a specific target or the like - I haven't looked closely. Co-authored-by: Vladislav Dzhidzhoev <[email protected]>
…_TAG_lexical_blocks (llvm#136205) During the discussion under llvm#119001, it was noticed that concrete DW_TAG_lexical_blocks should refer to corresponding abstract DW_TAG_lexical_blocks by having DW_AT_abstract_origin, to avoid ambiguity. This behavior is implemented in GCC (https://godbolt.org/z/Khrzdq1Wx), but not in LLVM. Fixes llvm#49297.
…lined DW_TAG_lexical_blocks" (llvm#137237) Reverts llvm#136205 Breaks buildbots, probably something about needing to restrict the test to running on a specific target or the like - I haven't looked closely. Co-authored-by: Vladislav Dzhidzhoev <[email protected]>
…_TAG_lexical_blocks (llvm#136205) During the discussion under llvm#119001, it was noticed that concrete DW_TAG_lexical_blocks should refer to corresponding abstract DW_TAG_lexical_blocks by having DW_AT_abstract_origin, to avoid ambiguity. This behavior is implemented in GCC (https://godbolt.org/z/Khrzdq1Wx), but not in LLVM. Fixes llvm#49297.
…lined DW_TAG_lexical_blocks" (llvm#137237) Reverts llvm#136205 Breaks buildbots, probably something about needing to restrict the test to running on a specific target or the like - I haven't looked closely. Co-authored-by: Vladislav Dzhidzhoev <[email protected]>
During the discussion under #119001, it was noticed that concrete DW_TAG_lexical_blocks should refer to corresponding abstract DW_TAG_lexical_blocks by having DW_AT_abstract_origin, to avoid ambiguity. This behavior is implemented in GCC (https://godbolt.org/z/Khrzdq1Wx), but not in LLVM.
Fixes #49297.