diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1274,9 +1274,13 @@ void DwarfDebug::finishSubprogramDefinitions() { for (const DISubprogram *SP : ProcessedSPNodes) { assert(SP->getUnit()->getEmissionKind() != DICompileUnit::NoDebug); - forBothCUs( - getOrCreateDwarfCompileUnit(SP->getUnit()), - [&](DwarfCompileUnit &CU) { CU.finishSubprogramDefinition(SP); }); + DwarfCompileUnit *ContextCU = CUMap.lookup(SP->getUnit()); + DIE *ContextDIE = ContextCU->getOrCreateContextDIE(SP->getScope()); + ContextCU = static_cast(ContextDIE->getUnit()); + DwarfCompileUnit &TheCU = *ContextCU; + forBothCUs(TheCU, [&](DwarfCompileUnit &CU) { + CU.finishSubprogramDefinition(SP); + }); } } @@ -2232,7 +2236,12 @@ LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); assert(!FnScope || SP == FnScope->getScopeNode()); - DwarfCompileUnit &TheCU = *CUMap.lookup(SP->getUnit()); + + DwarfCompileUnit *ContextCU = CUMap.lookup(SP->getUnit()); + DIE *ContextDIE = ContextCU->getOrCreateContextDIE(SP->getScope()); + ContextCU = static_cast(ContextDIE->getUnit()); + DwarfCompileUnit &TheCU = *ContextCU; + if (TheCU.getCUNode()->isDebugDirectivesOnly()) { PrevLabel = nullptr; CurFn = nullptr; diff --git a/llvm/test/DebugInfo/Generic/cross-cu-inlining-2.ll b/llvm/test/DebugInfo/Generic/cross-cu-inlining-2.ll --- a/llvm/test/DebugInfo/Generic/cross-cu-inlining-2.ll +++ b/llvm/test/DebugInfo/Generic/cross-cu-inlining-2.ll @@ -41,19 +41,19 @@ ; CHECK: DW_TAG_compile_unit ; CHECK: DW_TAG_module ; CHECK: DW_TAG_structure_type -; CHECK: [[INIT:0x.*]]: DW_TAG_subprogram -; CHECK; DW_AT_name [DW_FORM_strp] ({{.*}} = "init") ; CHECK: DW_TAG_subprogram -; CHECK; DW_AT_name [DW_FORM_strp] ({{.*}} = "bar") +; CHECK; DW_AT_name [DW_FORM_strp] ({{.*}} = "foo") ; CHECK: DW_TAG_inlined_subroutine -; CHECK: DW_AT_abstract_origin [DW_FORM_ref_addr] (0x00000000[[GOO:.*]] "goo") +; CHECK: DW_AT_abstract_origin [DW_FORM_ref4] ({{.*}} => {[[INIT:0x.*]]} "init") ; CHECK: NULL ; CHECK: NULL ; CHECK: DW_TAG_structure_type +; CHECK:[[INIT]]: DW_TAG_subprogram +; CHECK; DW_AT_name [DW_FORM_strp] ({{.*}} = "init") ; CHECK: DW_TAG_subprogram -; CHECK; DW_AT_name [DW_FORM_strp] ({{.*}} = "foo") +; CHECK; DW_AT_name [DW_FORM_strp] ({{.*}} = "bar") ; CHECK: DW_TAG_inlined_subroutine -; CHECK: DW_AT_abstract_origin [DW_FORM_ref4] ({{.*}} => {[[INIT]]} "init") +; CHECK: DW_AT_abstract_origin [DW_FORM_ref_addr] (0x00000000[[GOO:.*]] "goo") ; CHECK: NULL ; CHECK: NULL ; CHECK: NULL diff --git a/llvm/test/DebugInfo/Generic/cross-cu.ll b/llvm/test/DebugInfo/Generic/cross-cu.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/Generic/cross-cu.ll @@ -0,0 +1,75 @@ +; RUN: %llc_dwarf %s -O0 -filetype=obj -o %t.o +; RUN: llvm-dwarfdump %t.o --debug-info --verify + +declare void @llvm.dbg.declare(metadata, metadata, metadata) + +define { ptr, i64 } @test(i1 %0, ptr %1) !dbg !23 { + %3 = alloca i64, i32 0, align 8 + call void @llvm.dbg.declare(metadata ptr %3, metadata !26, metadata !DIExpression()), !dbg !29 + %4 = icmp eq i64 0, 0 + br i1 %4, label %5, label %6 + +5: ; preds = %2 + store ptr null, ptr null, align 8, !dbg !30 + store i64 0, ptr %1, align 8 + ret { ptr, i64 } zeroinitializer + +6: ; preds = %2 + br i1 %0, label %9, label %7, !dbg !31 + +7: ; preds = %6 + %8 = load i64, ptr null, align 8, !dbg !32 + store i64 %8, ptr %1, align 8 + ret { ptr, i64 } zeroinitializer + +9: ; preds = %6 + store i64 0, ptr null, align 8 + ret { ptr, i64 } zeroinitializer +} + +define void @test2() cold !dbg !33 { + unreachable +} + +!llvm.module.flags = !{!0} +!llvm.dbg.cu = !{!1, !4} + +!0 = !{i32 2, !"Debug Info Version", i32 3} +!1 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !2, producer: "clang LLVM (rustc version 1.70.0-nightly (ec2f40c6b 2023-03-30))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, splitDebugInlining: false) +!2 = !DIFile(filename: "src/lib.rs/@/3jkrl8oz9knrf4o4", directory: "/home/npopov/repos/test") +!3 = !{} +!4 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !5, producer: "clang LLVM (rustc version 1.70.0-nightly (ec2f40c6b 2023-03-30))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !6, splitDebugInlining: false) +!5 = !DIFile(filename: "src/lib.rs/@/4r9uiw0o66d13q4b", directory: "/home/npopov/repos/test") +!6 = !{!7} +!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression()) +!8 = distinct !DIGlobalVariable(name: "<&alloc::vec::Vec as core::fmt::Debug>::{vtable}", scope: null, file: !9, type: !10, isLocal: true, isDefinition: true) +!9 = !DIFile(filename: "", directory: "") +!10 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "<&alloc::vec::Vec as core::fmt::Debug>::{vtable_type}", file: !9, size: 256, align: 64, flags: DIFlagArtificial, elements: !3, vtableHolder: !11, templateParams: !3, identifier: "8b5b18a5b595fd2726a060be925b88b2") +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&alloc::vec::Vec", baseType: !12, size: 64, align: 64, dwarfAddressSpace: 0) +!12 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Vec", scope: !13, file: !9, size: 192, align: 64, elements: !15, templateParams: !3, identifier: "528a0d32ae6e19b7d83105274ce701fc") +!13 = !DINamespace(name: "vec", scope: !14) +!14 = !DINamespace(name: "alloc", scope: null) +!15 = !{!16} +!16 = !DIDerivedType(tag: DW_TAG_member, name: "buf", scope: !12, file: !9, baseType: !17, size: 128, align: 64) +!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "RawVec", scope: !18, file: !9, size: 128, align: 64, elements: !3, templateParams: !19, identifier: "67d483d3bf48782733e92e6e5b9d5f14") +!18 = !DINamespace(name: "raw_vec", scope: !14) +!19 = !{!20} +!20 = !DITemplateTypeParameter(name: "A", type: !21) +!21 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Global", scope: !22, file: !9, align: 8, elements: !3, identifier: "8b09da5419eb6d204173b283709c5949") +!22 = !DINamespace(name: "alloc", scope: !14) +!23 = distinct !DISubprogram(name: "alloc_impl", linkageName: "_ZN5alloc5alloc6Global10alloc_impl17h238d0844851c71a5E", scope: !21, file: !24, line: 170, type: !25, scopeLine: 170, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !1, templateParams: !3, retainedNodes: !3) +!24 = !DIFile(filename: "/rustc/ec2f40c6b04f0e9850dd1f454e8639d319f4ed9b/library/alloc/src/alloc.rs", directory: "", checksumkind: CSK_MD5, checksum: "4972b0b4c31877237f60deae5d06e8ce") +!25 = distinct !DISubroutineType(types: !3) +!26 = !DILocalVariable(name: "size", scope: !27, file: !24, line: 174, type: !28, align: 8) +!27 = distinct !DILexicalBlock(scope: !23, file: !24, line: 174, column: 13) +!28 = !DIBasicType(name: "usize", size: 64, encoding: DW_ATE_unsigned) +!29 = !DILocation(line: 174, column: 13, scope: !27) +!30 = !DILocation(line: 172, column: 51, scope: !23) +!31 = !DILocation(line: 175, column: 34, scope: !27) +!32 = !DILocation(line: 175, column: 79, scope: !27) +!33 = distinct !DISubprogram(name: "assert_failed, alloc::vec::Vec>", linkageName: "_ZN4core9panicking13assert_failed17h49f83a394aded8c4E", scope: !35, file: !34, line: 204, type: !37, scopeLine: 204, flags: DIFlagPrototyped | DIFlagNoReturn, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4, templateParams: !3, retainedNodes: !3) +!34 = !DIFile(filename: "/rustc/ec2f40c6b04f0e9850dd1f454e8639d319f4ed9b/library/core/src/panicking.rs", directory: "", checksumkind: CSK_MD5, checksum: "83265ee8d3fb756102ca03de7bd05933") +!35 = !DINamespace(name: "panicking", scope: !36) +!36 = !DINamespace(name: "core", scope: null) +!37 = distinct !DISubroutineType(types: !38) +!38 = !{null}