Skip to content

Commit ef0dcb5

Browse files
committed
[DWARF] Create subprogram's DIE in DISubprogram's unit
This is a fix for PR48790. Over in D70350, subprogram DIEs were permitted to be shared between CUs. However, the creation of a subprogram DIE can be triggered early, from other CUs. The subprogram definition is then created in one CU, and when the function is actually emitted children are attached to the subprogram that expect to be in another CU. This breaks internal CU references in the children. Fix this by redirecting the creation of subprogram DIEs in getOrCreateContextDIE to the CU specified by it's DISubprogram definition. This ensures that the subprogram DIE is always created in the correct CU. Differential Revision: https://reviews.llvm.org/D94976
1 parent d7cc3a0 commit ef0dcb5

File tree

3 files changed

+103
-5
lines changed

3 files changed

+103
-5
lines changed

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,9 +465,6 @@ class DwarfDebug : public DebugHandlerBase {
465465
/// Construct a DIE for this abstract scope.
466466
void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope);
467467

468-
/// Construct a DIE for the subprogram definition \p SP and return it.
469-
DIE &constructSubprogramDefinitionDIE(const DISubprogram *SP);
470-
471468
/// Construct DIEs for call site entries describing the calls in \p MF.
472469
void constructCallSiteEntryDIEs(const DISubprogram &SP, DwarfCompileUnit &CU,
473470
DIE &ScopeDIE, const MachineFunction &MF);
@@ -759,6 +756,9 @@ class DwarfDebug : public DebugHandlerBase {
759756
/// * DW_FORM_data4 for 32-bit DWARFv3 and DWARFv2.
760757
dwarf::Form getDwarfSectionOffsetForm() const;
761758

759+
/// Construct a DIE for the subprogram definition \p SP and return it.
760+
DIE &constructSubprogramDefinitionDIE(const DISubprogram *SP);
761+
762762
/// Returns the previous CU that was being updated
763763
const DwarfCompileUnit *getPrevCU() const { return PrevCU; }
764764
void setPrevCU(const DwarfCompileUnit *PrevCU) { this->PrevCU = PrevCU; }

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -521,8 +521,13 @@ DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {
521521
return getOrCreateTypeDIE(T);
522522
if (auto *NS = dyn_cast<DINamespace>(Context))
523523
return getOrCreateNameSpace(NS);
524-
if (auto *SP = dyn_cast<DISubprogram>(Context))
525-
return getOrCreateSubprogramDIE(SP);
524+
if (auto *SP = dyn_cast<DISubprogram>(Context)) {
525+
// Subprogram definitions should be created in the Unit that they specify,
526+
// which might not be "this" unit when type definitions move around under
527+
// LTO.
528+
assert(SP->isDefinition());
529+
return &DD->constructSubprogramDefinitionDIE(SP);
530+
}
526531
if (auto *M = dyn_cast<DIModule>(Context))
527532
return getOrCreateModule(M);
528533
return getDIE(Context);
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
; RUN: llc %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o %t
2+
; RUN: llvm-dwarfdump -verify %t
3+
; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s
4+
; RUN: rm %t
5+
;
6+
;$ cat -n 1.cpp
7+
; 1 struct HHH;
8+
; 2 HHH *zzz;
9+
;
10+
;$ cat -n 2.cpp
11+
; 1 void __attribute__((optnone)) __attribute__((nodebug)) f1() { }
12+
; 2
13+
; 3 struct HHH {
14+
; 4 template <typename bbb>
15+
; 5 static int __attribute__((always_inline)) ccc() {
16+
; 6 f1();
17+
; 7 }
18+
; 8 };
19+
; 9
20+
; 10 int main() {
21+
; 11 struct local { };
22+
; 12 HHH::ccc<local>();
23+
; 13 }
24+
;
25+
; $ clang -flto -O2 -g 1.cpp 2.cpp -o a.out
26+
;
27+
; Given this input, LLVM attempts to create a DIE for subprogram "main" in the
28+
; wrong context. The definition of struct "HHH" is placed in the CU for 1.cpp.
29+
; While creating the template instance in "HHH", function "ccc" is referenced
30+
; via the struct local type, and "main" is created in the CU for 1.cpp, which
31+
; is incorrect.
32+
;
33+
; See PR48790 for more discussion and original compile commands.
34+
;
35+
; Check that there are no verifier failures, and that the SP for "main" appears
36+
; in the correct CU.
37+
; CHECK-LABEL: DW_TAG_compile_unit
38+
; CHECK: DW_AT_name ("1.cpp")
39+
; CHECK-NOT: DW_AT_name ("main")
40+
; CHECK-LABEL: DW_TAG_compile_unit
41+
; CHECK: DW_AT_name ("2.cpp")
42+
; CHECK: DW_TAG_subprogram
43+
; CHECK: DW_AT_name ("main")
44+
45+
source_filename = "ld-temp.o"
46+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
47+
target triple = "x86_64-unknown-linux-gnu"
48+
49+
; Function Attrs: noinline norecurse nounwind optnone uwtable mustprogress
50+
define internal fastcc void @_Z2f1v() unnamed_addr {
51+
entry:
52+
ret void
53+
}
54+
55+
; Function Attrs: norecurse noreturn nounwind uwtable mustprogress
56+
define dso_local i32 @main() local_unnamed_addr !dbg !17 {
57+
entry:
58+
tail call fastcc void @_Z2f1v(), !dbg !21
59+
unreachable, !dbg !21
60+
}
61+
62+
!llvm.dbg.cu = !{!0, !9}
63+
!llvm.ident = !{!10, !10}
64+
!llvm.module.flags = !{!11, !12, !13, !14, !15, !16}
65+
66+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 12.0.0 ([email protected]:llvm/llvm-project bc9ab9a5cd6bafc5e1293f3d5d51638f8f5cd26c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !3, splitDebugInlining: false, nameTableKind: None)
67+
!1 = !DIFile(filename: "1.cpp", directory: "/tmp/bees")
68+
!2 = !{}
69+
!3 = !{!4}
70+
!4 = !DIGlobalVariableExpression(var: !5, expr: !DIExpression())
71+
!5 = distinct !DIGlobalVariable(name: "zzz", scope: !0, file: !1, line: 2, type: !6, isLocal: false, isDefinition: true)
72+
!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64)
73+
!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "HHH", file: !8, line: 3, size: 8, flags: DIFlagTypePassByValue, elements: !2, identifier: "_ZTS3HHH")
74+
!8 = !DIFile(filename: "2.cpp", directory: "/tmp/bees")
75+
!9 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !8, producer: "clang version 12.0.0 ([email protected]:llvm/llvm-project bc9ab9a5cd6bafc5e1293f3d5d51638f8f5cd26c)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
76+
!10 = !{!"clang version 12.0.0 ([email protected]:llvm/llvm-project bc9ab9a5cd6bafc5e1293f3d5d51638f8f5cd26c)"}
77+
!11 = !{i32 7, !"Dwarf Version", i32 4}
78+
!12 = !{i32 2, !"Debug Info Version", i32 3}
79+
!13 = !{i32 1, !"wchar_size", i32 4}
80+
!14 = !{i32 1, !"ThinLTO", i32 0}
81+
!15 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
82+
!16 = !{i32 1, !"LTOPostLink", i32 1}
83+
!17 = distinct !DISubprogram(name: "main", scope: !8, file: !8, line: 10, type: !18, scopeLine: 10, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !9, retainedNodes: !2)
84+
!18 = !DISubroutineType(types: !19)
85+
!19 = !{!20}
86+
!20 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
87+
!21 = !DILocation(line: 6, column: 5, scope: !22, inlinedAt: !27)
88+
!22 = distinct !DISubprogram(name: "ccc<local>", linkageName: "_ZN3HHH3cccIZ4mainE5localEEiv", scope: !7, file: !8, line: 5, type: !18, scopeLine: 5, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: !9, templateParams: !24, declaration: !23, retainedNodes: !2)
89+
!23 = !DISubprogram(name: "ccc<local>", linkageName: "_ZN3HHH3cccIZ4mainE5localEEiv", scope: !7, file: !8, line: 5, type: !18, scopeLine: 5, flags: DIFlagPrototyped | DIFlagStaticMember, spFlags: DISPFlagOptimized, templateParams: !24)
90+
!24 = !{!25}
91+
!25 = !DITemplateTypeParameter(name: "bbb", type: !26)
92+
!26 = !DICompositeType(tag: DW_TAG_structure_type, name: "local", scope: !17, file: !8, line: 11, size: 8, flags: DIFlagFwdDecl)
93+
!27 = distinct !DILocation(line: 12, column: 3, scope: !17)

0 commit comments

Comments
 (0)