diff --git a/llvm/include/llvm/CodeGen/DebugHandlerBase.h b/llvm/include/llvm/CodeGen/DebugHandlerBase.h --- a/llvm/include/llvm/CodeGen/DebugHandlerBase.h +++ b/llvm/include/llvm/CodeGen/DebugHandlerBase.h @@ -72,6 +72,9 @@ /// function body. DebugLoc PrologEndLoc; + /// This block includes epilogue instructions. + const MachineBasicBlock *EpilogBeginBlock; + /// If nonnull, stores the current machine instruction we're processing. const MachineInstr *CurMI = nullptr; diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -417,6 +417,7 @@ } void DebugHandlerBase::beginBasicBlockSection(const MachineBasicBlock &MBB) { + EpilogBeginBlock = nullptr; if (!MBB.isEntryBlock()) PrevLabel = MBB.getSymbol(); } 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 @@ -2004,6 +2004,17 @@ if (MI->isMetaInstruction() || MI->getFlag(MachineInstr::FrameSetup)) return; const DebugLoc &DL = MI->getDebugLoc(); + unsigned Flags = 0; + + if (MI->getFlag(MachineInstr::FrameDestroy) && DL) { + const MachineBasicBlock *MBB = MI->getParent(); + if (MBB && (MBB != EpilogBeginBlock)) { + // First time FrameDestroy has been seen in this basic block + EpilogBeginBlock = MBB; + Flags |= DWARF2_FLAG_EPILOGUE_BEGIN; + } + } + // When we emit a line-0 record, we don't update PrevInstLoc; so look at // the last line number actually emitted, to see if it was line 0. unsigned LastAsmLine = @@ -2015,10 +2026,10 @@ return; // We have an explicit location, same as the previous location. // But we might be coming back to it after a line 0 record. - if (LastAsmLine == 0 && DL.getLine() != 0) { + if ((LastAsmLine == 0 && DL.getLine() != 0) || Flags) { // Reinstate the source location but not marked as a statement. const MDNode *Scope = DL.getScope(); - recordSourceLine(DL.getLine(), DL.getCol(), Scope, /*Flags=*/0); + recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags); } return; } @@ -2059,7 +2070,6 @@ // (The new location might be an explicit line 0, which we do emit.) if (DL.getLine() == 0 && LastAsmLine == 0) return; - unsigned Flags = 0; if (DL == PrologEndLoc) { Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT; PrologEndLoc = DebugLoc(); diff --git a/llvm/test/CodeGen/AMDGPU/no-source-locations-in-prologue.ll b/llvm/test/CodeGen/AMDGPU/no-source-locations-in-prologue.ll --- a/llvm/test/CodeGen/AMDGPU/no-source-locations-in-prologue.ll +++ b/llvm/test/CodeGen/AMDGPU/no-source-locations-in-prologue.ll @@ -37,6 +37,7 @@ ; CHECK-NEXT: .loc 0 32 1 ; lane-info.cpp:32:1 ; CHECK-NEXT: v_readlane_b32 s31, v40, 1 ; CHECK-NEXT: v_readlane_b32 s30, v40, 0 +; CHECK-NEXT: .loc 0 32 1 epilogue_begin is_stmt 0 ; lane-info.cpp:32:1 ; CHECK-NEXT: s_add_i32 s32, s32, 0xfffffc00 ; CHECK-NEXT: v_readlane_b32 s33, v40, 2 ; CHECK-NEXT: s_or_saveexec_b64 s[4:5], -1 diff --git a/llvm/test/CodeGen/X86/dbg-line-0-no-discriminator.ll b/llvm/test/CodeGen/X86/dbg-line-0-no-discriminator.ll --- a/llvm/test/CodeGen/X86/dbg-line-0-no-discriminator.ll +++ b/llvm/test/CodeGen/X86/dbg-line-0-no-discriminator.ll @@ -29,7 +29,7 @@ ; Look at the lengths. We can't verify the line-number-program size ; directly, but the difference in the two lengths should not change ; unexpectedly. -; CHECK: total_length: 0x00000044 +; CHECK: total_length: 0x00000045 ; CHECK: prologue_length: 0x0000001f ; ; Verify that we see a line entry with a discriminator, and the next entry diff --git a/llvm/test/DebugInfo/AArch64/line-header.ll b/llvm/test/DebugInfo/AArch64/line-header.ll --- a/llvm/test/DebugInfo/AArch64/line-header.ll +++ b/llvm/test/DebugInfo/AArch64/line-header.ll @@ -3,4 +3,4 @@ ; check line table length is correctly calculated for both big and little endian CHECK-LABEL: .debug_line contents: -CHECK: total_length: 0x00000040 +CHECK: total_length: 0x00000043 diff --git a/llvm/test/DebugInfo/Generic/extended-loc-directive.ll b/llvm/test/DebugInfo/Generic/extended-loc-directive.ll --- a/llvm/test/DebugInfo/Generic/extended-loc-directive.ll +++ b/llvm/test/DebugInfo/Generic/extended-loc-directive.ll @@ -31,7 +31,7 @@ ; CHECK-NOT: .loc ; CHECK: .loc 1 4 15{{$}} ; CHECK-NOT: .loc -; ENABLED: .loc 1 5 1 is_stmt 1{{$}} +; ENABLED: .loc 1 5 1 {{(epilogue_begin )?is_stmt}} 1{{$}} ; DISABLED: .loc 1 5 1{{$}} ; Function Attrs: nounwind uwtable diff --git a/llvm/test/DebugInfo/Generic/multiline.ll b/llvm/test/DebugInfo/Generic/multiline.ll --- a/llvm/test/DebugInfo/Generic/multiline.ll +++ b/llvm/test/DebugInfo/Generic/multiline.ll @@ -27,7 +27,7 @@ ; CHECK-NOT: .loc ; CHECK: .loc 1 4 15{{$}} ; CHECK-NOT: .loc -; CHECK: .loc 1 5 1 is_stmt 1{{$}} +; CHECK: .loc 1 5 1 {{(epilogue_begin )?}}is_stmt 1{{$}} ; INT: {{^}}Address ; INT: ----- @@ -38,7 +38,7 @@ ; INT-NEXT: 4 3 1 0 0 is_stmt{{$}} ; INT-NEXT: 4 9 1 0 0 {{$}} ; INT-NEXT: 4 15 1 0 0 {{$}} -; INT-NEXT: 5 1 1 0 0 is_stmt{{$}} +; INT-NEXT: 5 1 1 0 0 is_stmt{{( epilogue_begin)?}}{{$}} ; Function Attrs: nounwind uwtable diff --git a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll --- a/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll +++ b/llvm/test/DebugInfo/RISCV/dwarf-riscv-relocs.ll @@ -36,7 +36,7 @@ ; DWARF-DUMP: .debug_line contents: ; DWARF-DUMP-NEXT: debug_line[0x00000000] ; DWARF-DUMP-NEXT: Line table prologue: -; DWARF-DUMP-NEXT: total_length: 0x0000005f +; DWARF-DUMP-NEXT: total_length: 0x00000067 ; DWARF-DUMP-NEXT: format: DWARF32 ; DWARF-DUMP-NEXT: version: 5 ; DWARF-DUMP-NEXT: address_size: 4 @@ -71,7 +71,8 @@ ; DWARF-DUMP-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- ; DWARF-DUMP-NEXT: 0x0000000000000000 2 0 0 0 0 is_stmt ; DWARF-DUMP-NEXT: 0x0000000000000014 3 5 0 0 0 is_stmt prologue_end -; DWARF-DUMP-NEXT: 0x0000000000000028 3 5 0 0 0 is_stmt end_sequence +; DWARF-DUMP-NEXT: 0x0000000000000020 3 5 0 0 0 epilogue_begin +; DWARF-DUMP-NEXT: 0x0000000000000028 3 5 0 0 0 end_sequence ; ModuleID = 'dwarf-riscv-relocs.c' source_filename = "dwarf-riscv-relocs.c" diff --git a/llvm/test/DebugInfo/X86/basic-block-sections_1.ll b/llvm/test/DebugInfo/X86/basic-block-sections_1.ll --- a/llvm/test/DebugInfo/X86/basic-block-sections_1.ll +++ b/llvm/test/DebugInfo/X86/basic-block-sections_1.ll @@ -54,7 +54,8 @@ ; BB-SECTIONS-LINE-TABLE-NEXT: 0x0000000000000015 0 5 1 0 0 ; BB-SECTIONS-LINE-TABLE-NEXT: 0x000000000000001a 5 5 1 0 0 is_stmt ; BB-SECTIONS-LINE-TABLE-NEXT: 0x000000000000001e 6 1 1 0 0 is_stmt -; BB-SECTIONS-LINE-TABLE-NEXT: 0x0000000000000024 6 1 1 0 0 is_stmt end_sequence +; BB-SECTIONS-LINE-TABLE-NEXT: 0x0000000000000022 6 1 1 0 0 epilogue_begin +; BB-SECTIONS-LINE-TABLE-NEXT: 0x0000000000000024 6 1 1 0 0 end_sequence ; Function Attrs: noinline nounwind optnone uwtable define dso_local i32 @_Z3fooi(i32 %0) !dbg !7 !prof !34 !section_prefix !35 { diff --git a/llvm/test/DebugInfo/X86/multiple-epilogue.ll b/llvm/test/DebugInfo/X86/multiple-epilogue.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/X86/multiple-epilogue.ll @@ -0,0 +1,100 @@ +; RUN: llc -O1 %s -mtriple=x86_64 -filetype=obj -o %t && llvm-dwarfdump -debug-line %t | FileCheck -v --check-prefix=LINE-TABLE %s + +; based on +; +; 1: int bar(); +; 2: int baz(); +; 3; +; 4: int foo(int a) { +; 5: if (a > 20) +; 6: return bar(); +; 7: else +; 8: return baz(); +; 9: } +; +; compiled with -g -S -emit-llvm -O1 + + +; LINE-TABLE: .debug_line contents: +; LINE-TABLE: Line table prologue: +; LINE-TABLE: total_length: 0x00000069 +; LINE-TABLE: format: DWARF32 +; LINE-TABLE: version: 5 +; LINE-TABLE: address_size: 8 +; LINE-TABLE: seg_select_size: 0 +; LINE-TABLE: prologue_length: 0x00000037 + +; LINE-TABLE: Address Line Column File ISA Discriminator Flags +; LINE-TABLE-NEXT: ------------------ ------ ------ ------ --- ------------- ------------- +; LINE-TABLE-NEXT: 0x0000000000000000 4 0 0 0 0 is_stmt +; LINE-TABLE-NEXT: 0x0000000000000001 5 9 0 0 0 is_stmt prologue_end +; LINE-TABLE-NEXT: 0x0000000000000004 5 7 0 0 0 +; LINE-TABLE-NEXT: 0x0000000000000006 6 12 0 0 0 is_stmt +; LINE-TABLE-NEXT: 0x000000000000000b 9 1 0 0 0 is_stmt epilogue_begin +; LINE-TABLE-NEXT: 0x000000000000000d 8 12 0 0 0 is_stmt +; LINE-TABLE-NEXT: 0x0000000000000012 9 1 0 0 0 is_stmt epilogue_begin +; LINE-TABLE-NEXT: 0x0000000000000014 9 1 0 0 0 is_stmt end_sequence + + + + +; Function Attrs: mustprogress uwtable +define dso_local noundef i32 @_Z3fooi(i32 noundef %a) local_unnamed_addr #0 !dbg !8 { +entry: + call void @llvm.dbg.value(metadata i32 %a, metadata !13, metadata !DIExpression()), !dbg !14 + %cmp = icmp sgt i32 %a, 20, !dbg !15 + br i1 %cmp, label %if.then, label %if.else, !dbg !17 + +if.then: ; preds = %entry + %call = call noundef i32 @_Z3barv(), !dbg !18 + br label %return, !dbg !19 + +if.else: ; preds = %entry + %call1 = call noundef i32 @_Z3bazv(), !dbg !20 + br label %return, !dbg !21 + +return: ; preds = %if.else, %if.then + %retval.0 = phi i32 [ %call, %if.then ], [ %call1, %if.else ], !dbg !22 + ret i32 %retval.0, !dbg !23 +} + +declare !dbg !24 dso_local noundef i32 @_Z3barv() local_unnamed_addr #1 + +declare !dbg !28 dso_local noundef i32 @_Z3bazv() local_unnamed_addr #1 + +; Function Attrs: nofree nosync nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) #2 + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!2, !3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 15.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None) +!1 = !DIFile(filename: "q.cpp", directory: "/", checksumkind: CSK_MD5, checksum: "6b5f6118d466ba2f6510ac0790b09bef") +!2 = !{i32 7, !"Dwarf Version", i32 5} +!3 = !{i32 2, !"Debug Info Version", i32 3} +!4 = !{i32 1, !"wchar_size", i32 4} +!5 = !{i32 7, !"uwtable", i32 2} +!6 = !{i32 7, !"frame-pointer", i32 2} +!7 = !{!"clang version 15.0.0"} +!8 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !1, file: !1, line: 4, type: !9, scopeLine: 4, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12) +!9 = !DISubroutineType(types: !10) +!10 = !{!11, !11} +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{!13} +!13 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 4, type: !11) +!14 = !DILocation(line: 0, scope: !8) +!15 = !DILocation(line: 5, column: 9, scope: !16) +!16 = distinct !DILexicalBlock(scope: !8, file: !1, line: 5, column: 7) +!17 = !DILocation(line: 5, column: 7, scope: !8) +!18 = !DILocation(line: 6, column: 12, scope: !16) +!19 = !DILocation(line: 6, column: 5, scope: !16) +!20 = !DILocation(line: 8, column: 12, scope: !16) +!21 = !DILocation(line: 8, column: 5, scope: !16) +!22 = !DILocation(line: 0, scope: !16) +!23 = !DILocation(line: 9, column: 1, scope: !8) +!24 = !DISubprogram(name: "bar", linkageName: "_Z3barv", scope: !1, file: !1, line: 1, type: !25, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !27) +!25 = !DISubroutineType(types: !26) +!26 = !{!11} +!27 = !{} +!28 = !DISubprogram(name: "baz", linkageName: "_Z3bazv", scope: !1, file: !1, line: 2, type: !25, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !27) diff --git a/llvm/test/DebugInfo/X86/stmt-list-multiple-compile-units.ll b/llvm/test/DebugInfo/X86/stmt-list-multiple-compile-units.ll --- a/llvm/test/DebugInfo/X86/stmt-list-multiple-compile-units.ll +++ b/llvm/test/DebugInfo/X86/stmt-list-multiple-compile-units.ll @@ -15,7 +15,7 @@ ; CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000010) ; CHECK: DW_TAG_compile_unit -; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x0000003d) +; CHECK: DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000040) ; CHECK: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000010) ; CHECK: DW_AT_high_pc [DW_FORM_data4] (0x00000009) ; CHECK: DW_TAG_subprogram @@ -26,7 +26,7 @@ ; CHECK: .debug_line contents: ; CHECK-NEXT: debug_line[{{.*}}] ; CHECK-NEXT: Line table prologue: -; CHECK-NEXT: total_length: 0x00000039 +; CHECK-NEXT: total_length: 0x0000003c ; CHECK: file_names[ 1]: ; CHECK-NEXT: name: "simple.c" ; CHECK-NEXT: dir_index: 0 @@ -43,13 +43,13 @@ ; DWARF3: DW_AT_stmt_list [DW_FORM_data4] (0x00000000) ; DWARF3: DW_TAG_compile_unit -; DWARF3: DW_AT_stmt_list [DW_FORM_data4] (0x0000003c) +; DWARF3: DW_AT_stmt_list [DW_FORM_data4] (0x0000003f) ; DWARF3: .debug_line contents: ; DWARF3-NEXT: debug_line[{{.*}}] ; DWARF3-NEXT: Line table prologue: -; DWARF3-NEXT: total_length: 0x00000038 +; DWARF3-NEXT: total_length: 0x0000003b ; DWARF3: file_names[ 1]: ; DWARF3-NEXT: name: "simple.c" ; DWARF3-NEXT: dir_index: 0