Skip to content

[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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -1491,6 +1493,19 @@ void DwarfCompileUnit::finishEntityDefinition(const DbgEntity *Entity) {
getDwarfDebug().addAccelName(*this, CUNode->getNameTableKind(), Name, *Die);
}

void DwarfCompileUnit::attachLexicalScopesAbstractOrigins() {
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);
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -299,6 +303,7 @@ class DwarfCompileUnit final : public DwarfUnit {

void finishSubprogramDefinition(const DISubprogram *SP);
void finishEntityDefinition(const DbgEntity *Entity);
void attachLexicalScopesAbstractOrigins();

/// Find abstract variable associated with Var.
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,7 @@ void DwarfDebug::finalizeModuleInfo() {
auto &TheCU = *P.second;
if (TheCU.getCUNode()->isDebugDirectivesOnly())
continue;
TheCU.attachLexicalScopesAbstractOrigins();
// Emit DW_AT_containing_type attribute to connect types with their
// vtable holding type.
TheCU.constructContainingTypeDIEs();
Expand Down
15 changes: 14 additions & 1 deletion llvm/test/DebugInfo/Generic/inline-scopes.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
56 changes: 56 additions & 0 deletions llvm/test/DebugInfo/Generic/lexical-block-abstract-origin.ll
Original file line number Diff line number Diff line change
@@ -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)
14 changes: 9 additions & 5 deletions llvm/test/DebugInfo/X86/lexical-block-file-inline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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}}
Expand All @@ -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 {
Expand Down
6 changes: 4 additions & 2 deletions llvm/test/DebugInfo/X86/missing-abstract-variable.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down
Loading