| commit 1b112c80a68697687189ddf5bb01b2edacb618af |
| Author: David Blaikie <dblaikie@gmail.com> |
| Date: Sun Jun 27 14:34:18 2021 -0700 |
| |
| PR37255: DebugInfo: LTO with -g inlined into -gmlt combined with Split DWARF without CU cross-references |
| |
| A combination of features ^ that lead to a mismatch of expectations |
| about how a subprogram definition DIE would be produced with/without a |
| declaration when taking full -g debug info and inlining it into a -gmlt |
| CU - specifically when using Split DWARF that doesn't support cross-CU |
| references, so we have to put the -g debug info into the -gmlt CU, which |
| gets confusing about which mode is respected. |
| |
| This patch comes down on respecting the CU the debug info is emitted |
| into, rather than preserving the full debug info when it's emitted into |
| the gmlt CU. |
| --- |
| llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 50 +++++++------- |
| llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h | 2 +- |
| .../DebugInfo/X86/split-dwarf-cross-cu-gmlt-g.ll | 80 ++++++++++++++++++++++ |
| 3 files changed, 107 insertions(+), 25 deletions(-) |
| |
| diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp |
| index 82dbb8a74375..5c6dd43b8163 100644 |
| --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp |
| +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp |
| @@ -1130,32 +1130,34 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) { |
| } |
| |
| bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP, |
| - DIE &SPDie) { |
| + DIE &SPDie, bool Minimal) { |
| DIE *DeclDie = nullptr; |
| StringRef DeclLinkageName; |
| if (auto *SPDecl = SP->getDeclaration()) { |
| - DITypeRefArray DeclArgs, DefinitionArgs; |
| - DeclArgs = SPDecl->getType()->getTypeArray(); |
| - DefinitionArgs = SP->getType()->getTypeArray(); |
| - |
| - if (DeclArgs.size() && DefinitionArgs.size()) |
| - if (DefinitionArgs[0] != NULL && DeclArgs[0] != DefinitionArgs[0]) |
| - addType(SPDie, DefinitionArgs[0]); |
| - |
| - DeclDie = getDIE(SPDecl); |
| - assert(DeclDie && "This DIE should've already been constructed when the " |
| - "definition DIE was created in " |
| - "getOrCreateSubprogramDIE"); |
| - // Look at the Decl's linkage name only if we emitted it. |
| - if (DD->useAllLinkageNames()) |
| - DeclLinkageName = SPDecl->getLinkageName(); |
| - unsigned DeclID = getOrCreateSourceID(SPDecl->getFile()); |
| - unsigned DefID = getOrCreateSourceID(SP->getFile()); |
| - if (DeclID != DefID) |
| - addUInt(SPDie, dwarf::DW_AT_decl_file, None, DefID); |
| - |
| - if (SP->getLine() != SPDecl->getLine()) |
| - addUInt(SPDie, dwarf::DW_AT_decl_line, None, SP->getLine()); |
| + if (!Minimal) { |
| + DITypeRefArray DeclArgs, DefinitionArgs; |
| + DeclArgs = SPDecl->getType()->getTypeArray(); |
| + DefinitionArgs = SP->getType()->getTypeArray(); |
| + |
| + if (DeclArgs.size() && DefinitionArgs.size()) |
| + if (DefinitionArgs[0] != NULL && DeclArgs[0] != DefinitionArgs[0]) |
| + addType(SPDie, DefinitionArgs[0]); |
| + |
| + DeclDie = getDIE(SPDecl); |
| + assert(DeclDie && "This DIE should've already been constructed when the " |
| + "definition DIE was created in " |
| + "getOrCreateSubprogramDIE"); |
| + // Look at the Decl's linkage name only if we emitted it. |
| + if (DD->useAllLinkageNames()) |
| + DeclLinkageName = SPDecl->getLinkageName(); |
| + unsigned DeclID = getOrCreateSourceID(SPDecl->getFile()); |
| + unsigned DefID = getOrCreateSourceID(SP->getFile()); |
| + if (DeclID != DefID) |
| + addUInt(SPDie, dwarf::DW_AT_decl_file, None, DefID); |
| + |
| + if (SP->getLine() != SPDecl->getLine()) |
| + addUInt(SPDie, dwarf::DW_AT_decl_line, None, SP->getLine()); |
| + } |
| } |
| |
| // Add function template parameters. |
| @@ -1187,7 +1189,7 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie, |
| bool SkipSPSourceLocation = SkipSPAttributes && |
| !CUNode->getDebugInfoForProfiling(); |
| if (!SkipSPSourceLocation) |
| - if (applySubprogramDefinitionAttributes(SP, SPDie)) |
| + if (applySubprogramDefinitionAttributes(SP, SPDie, SkipSPAttributes)) |
| return; |
| |
| // Constructors and operators for anonymous aggregates do not have names. |
| diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h |
| index df1ead03dc05..4d31dd0daf59 100644 |
| --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h |
| +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h |
| @@ -73,7 +73,7 @@ protected: |
| DwarfUnit(dwarf::Tag, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, |
| DwarfFile *DWU); |
| |
| - bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie); |
| + bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie, bool Minimal); |
| |
| bool isShareableAcrossCUs(const DINode *D) const; |
| |
| diff --git a/llvm/test/DebugInfo/X86/split-dwarf-cross-cu-gmlt-g.ll b/llvm/test/DebugInfo/X86/split-dwarf-cross-cu-gmlt-g.ll |
| new file mode 100644 |
| index 000000000000..ac5a10652ba9 |
| --- /dev/null |
| +++ b/llvm/test/DebugInfo/X86/split-dwarf-cross-cu-gmlt-g.ll |
| @@ -0,0 +1,80 @@ |
| +; RUN: llc -mtriple=x86_64-linux -split-dwarf-file=foo.dwo -filetype=obj -o %t < %s |
| +; RUN: llvm-dwarfdump -debug-info %t | FileCheck %s |
| + |
| +; CHECK: DW_AT_name ("b.cpp") |
| +; CHECK: DW_TAG_subprogram |
| +; CHECK-NEXT: DW_AT_linkage_name ("_ZN5outer2f2Ev") |
| +; CHECK-NEXT: DW_AT_name ("f2") |
| +; CHECK-NEXT: DW_AT_decl_file (0x02) |
| +; CHECK-NEXT: DW_AT_decl_line (4) |
| + |
| +; Function Attrs: noinline nounwind optnone uwtable mustprogress |
| +define dso_local void @_Z2f1v() local_unnamed_addr #0 !dbg !12 { |
| +entry: |
| + ret void, !dbg !15 |
| +} |
| + |
| +; Function Attrs: nounwind uwtable mustprogress |
| +define dso_local void @_ZN5outer2f2Ev() local_unnamed_addr #1 align 2 !dbg !16 { |
| +entry: |
| + tail call void @_Z2f1v(), !dbg !21 |
| + ret void, !dbg !22 |
| +} |
| + |
| +; Function Attrs: nounwind uwtable mustprogress |
| +define dso_local void @_Z2f2v() local_unnamed_addr #1 !dbg !23 { |
| +entry: |
| + tail call void @_Z2f1v(), !dbg !24 |
| + ret void, !dbg !25 |
| +} |
| + |
| +; Function Attrs: norecurse nounwind uwtable mustprogress |
| +define dso_local i32 @main() local_unnamed_addr #2 !dbg !26 { |
| +entry: |
| + tail call void @_Z2f1v() #3, !dbg !28 |
| + tail call void @_Z2f1v() #3, !dbg !30 |
| + ret i32 0, !dbg !32 |
| +} |
| + |
| +attributes #0 = { noinline nounwind optnone uwtable mustprogress "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } |
| +attributes #1 = { nounwind uwtable mustprogress "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } |
| +attributes #2 = { norecurse nounwind uwtable mustprogress "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } |
| +attributes #3 = { nounwind } |
| + |
| +!llvm.dbg.cu = !{!0, !3} |
| +!llvm.ident = !{!5, !5} |
| +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11} |
| + |
| +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 9aa951e80e72decd95c7d972e1e0dde24260d336)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, debugInfoForProfiling: true, nameTableKind: None) |
| +!1 = !DIFile(filename: "a.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch") |
| +!2 = !{} |
| +!3 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !4, producer: "clang version 13.0.0 (git@github.com:llvm/llvm-project.git 9aa951e80e72decd95c7d972e1e0dde24260d336)", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2, splitDebugInlining: false, debugInfoForProfiling: true, nameTableKind: None) |
| +!4 = !DIFile(filename: "b.cpp", directory: "/usr/local/google/home/blaikie/dev/scratch") |
| +!5 = !{!"clang version 13.0.0 (git@github.com:llvm/llvm-project.git 9aa951e80e72decd95c7d972e1e0dde24260d336)"} |
| +!6 = !{i32 7, !"Dwarf Version", i32 4} |
| +!7 = !{i32 2, !"Debug Info Version", i32 3} |
| +!8 = !{i32 1, !"wchar_size", i32 4} |
| +!9 = !{i32 7, !"uwtable", i32 1} |
| +!10 = !{i32 1, !"ThinLTO", i32 0} |
| +!11 = !{i32 1, !"EnableSplitLTOUnit", i32 1} |
| +!12 = distinct !DISubprogram(name: "f1", linkageName: "_Z2f1v", scope: !1, file: !1, line: 2, type: !13, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) |
| +!13 = !DISubroutineType(types: !14) |
| +!14 = !{null} |
| +!15 = !DILocation(line: 3, column: 1, scope: !12) |
| +!16 = distinct !DISubprogram(name: "f2", linkageName: "_ZN5outer2f2Ev", scope: !17, file: !1, line: 4, type: !13, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, declaration: !20, retainedNodes: !2) |
| +!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "outer", file: !18, line: 1, size: 8, flags: DIFlagTypePassByValue, elements: !19, identifier: "_ZTS5outer") |
| +!18 = !DIFile(filename: "./a.h", directory: "/usr/local/google/home/blaikie/dev/scratch") |
| +!19 = !{!20} |
| +!20 = !DISubprogram(name: "f2", linkageName: "_ZN5outer2f2Ev", scope: !17, file: !18, line: 2, type: !13, scopeLine: 2, flags: DIFlagPrototyped | DIFlagStaticMember, spFlags: DISPFlagOptimized) |
| +!21 = !DILocation(line: 5, column: 3, scope: !16) |
| +!22 = !DILocation(line: 6, column: 1, scope: !16) |
| +!23 = distinct !DISubprogram(name: "f2", linkageName: "_Z2f2v", scope: !1, file: !1, line: 7, type: !13, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2) |
| +!24 = !DILocation(line: 8, column: 3, scope: !23) |
| +!25 = !DILocation(line: 9, column: 1, scope: !23) |
| +!26 = distinct !DISubprogram(name: "main", scope: !4, file: !4, line: 2, type: !27, scopeLine: 2, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !3, retainedNodes: !2) |
| +!27 = !DISubroutineType(types: !2) |
| +!28 = !DILocation(line: 5, column: 3, scope: !16, inlinedAt: !29) |
| +!29 = distinct !DILocation(line: 3, column: 3, scope: !26) |
| +!30 = !DILocation(line: 8, column: 3, scope: !23, inlinedAt: !31) |
| +!31 = distinct !DILocation(line: 4, column: 3, scope: !26) |
| +!32 = !DILocation(line: 5, column: 1, scope: !26) |