diff --git a/llvm/include/llvm/MC/MCContext.h b/llvm/include/llvm/MC/MCContext.h --- a/llvm/include/llvm/MC/MCContext.h +++ b/llvm/include/llvm/MC/MCContext.h @@ -179,6 +179,9 @@ /// unit are separated. std::map MCDwarfLineTablesCUMap; + /// The current MCDwarfLineTable used from the last line entry. + MCDwarfLineTable *CurrentMCDwarfLineTable = nullptr; + /// The current dwarf line information from the last dwarf .loc directive. MCDwarfLoc CurrentDwarfLoc; bool DwarfLocSeen = false; @@ -694,6 +697,20 @@ return MCDwarfLineTablesCUMap[CUID]; } + // This checks if we emit the line entry for the same CU. + // If not, an end sequence is emitted to terminate the prior line + // table before adding it to the current line table. + void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) { + unsigned CUID = getDwarfCompileUnitID(); + auto *LineTable = &MCDwarfLineTablesCUMap[CUID]; + if (CurrentMCDwarfLineTable != nullptr && + LineTable != CurrentMCDwarfLineTable) { + CurrentMCDwarfLineTable->addEndSequence(LineEntry, Sec); + } + CurrentMCDwarfLineTable = LineTable; + CurrentMCDwarfLineTable->addLineEntry(LineEntry, Sec); + } + const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const { auto I = MCDwarfLineTablesCUMap.find(CUID); assert(I != MCDwarfLineTablesCUMap.end()); diff --git a/llvm/include/llvm/MC/MCDwarf.h b/llvm/include/llvm/MC/MCDwarf.h --- a/llvm/include/llvm/MC/MCDwarf.h +++ b/llvm/include/llvm/MC/MCDwarf.h @@ -188,6 +188,10 @@ MCSymbol *getLabel() const { return Label; } + // This indicates the line entry is synthesized for an end sequence in + // the current line table. + bool IsEndSequence = false; + // This is called when an instruction is assembled into the specified // section and if there is information from the last .loc directive that // has yet to have a line entry made for it is made. @@ -328,6 +332,18 @@ MCLineSection MCLineSections; public: + void addEndSequence(const MCDwarfLineEntry &LineEntry, MCSection *Sec) { + // Clone the line entry and set it for end_sequence. + MCDwarfLineEntry EndSequence = LineEntry; + EndSequence.IsEndSequence = true; + + addLineEntry(EndSequence, Sec); + } + + void addLineEntry(const MCDwarfLineEntry &LineEntry, MCSection *Sec) { + MCLineSections.addLineEntry(LineEntry, Sec); + } + // This emits the Dwarf file and the line tables for all Compile Units. static void emit(MCStreamer *MCOS, MCDwarfLineTableParams Params); diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -107,10 +107,7 @@ MCOS->getContext().clearDwarfLocSeen(); // Add the line entry to this section's entries. - MCOS->getContext() - .getMCDwarfLineTable(MCOS->getContext().getDwarfCompileUnitID()) - .getMCLineSections() - .addLineEntry(LineEntry, Section); + MCOS->getContext().addLineEntry(LineEntry, Section); } // @@ -157,7 +154,22 @@ MCSymbol *LastLabel = nullptr; // Loop through each MCDwarfLineEntry and encode the dwarf line number table. + bool EndSequenceEmitted = false; for (const MCDwarfLineEntry &LineEntry : LineEntries) { + MCSymbol *Label = LineEntry.getLabel(); + const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); + + if (LineEntry.IsEndSequence) { + MCOS->emitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, Label, + asmInfo->getCodePointerSize()); + Discriminator = 0; + LastLabel = nullptr; + LastLine = 1; + EndSequenceEmitted = true; + continue; + } + EndSequenceEmitted = false; + int64_t LineDelta = static_cast(LineEntry.getLine()) - LastLine; if (FileNum != LineEntry.getFileNum()) { @@ -195,12 +207,9 @@ if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN) MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin); - MCSymbol *Label = LineEntry.getLabel(); - // At this point we want to emit/create the sequence to encode the delta in // line numbers and the increment of the address from the previous Label // and the current Label. - const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, asmInfo->getCodePointerSize()); @@ -209,6 +218,11 @@ LastLabel = Label; } + // If an end sequence is already emitted at the last iteration of the loop, + // just skip emitting another end sequence. + if (EndSequenceEmitted) + return; + // Generate DWARF line end entry. MCOS->emitDwarfLineEndEntry(Section, LastLabel); } diff --git a/llvm/test/DebugInfo/debugline-endsequence.ll b/llvm/test/DebugInfo/debugline-endsequence.ll new file mode 100644 --- /dev/null +++ b/llvm/test/DebugInfo/debugline-endsequence.ll @@ -0,0 +1,42 @@ +; RUN: %llc_dwarf %s -filetype=obj -o - | llvm-dwarfdump -all - | FileCheck %s + +target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" +target triple = "arm64-apple-macosx12.0.0" + +; Check if the end_sequences are differently emitted per CU. + +; CHECK: 0x0000000000000004 [[T:.*]] end_sequence +define void @f1() !dbg !15 { + ret void, !dbg !18 +} + +; CHECK: 0x0000000000000008 [[T:.*]] end_sequence +define void @f2() !dbg !19 { + ret void, !dbg !20 +} + +!llvm.dbg.cu = !{!0, !3} +!llvm.ident = !{!5, !5} +!llvm.module.flags = !{!6, !7, !8, !9, !10, !11, !12, !13, !14} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "LLVM", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None, sysroot: "/") +!1 = !DIFile(filename: "", directory: "/") +!2 = !{} +!3 = distinct !DICompileUnit(language: DW_LANG_C99, file: !4, producer: "LLVM", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None, sysroot: "/") +!4 = !DIFile(filename: "", directory: "/") +!5 = !{!"clang"} +!6 = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 3]} +!7 = !{i32 7, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{i32 1, !"branch-target-enforcement", i32 0} +!11 = !{i32 1, !"sign-return-address", i32 0} +!12 = !{i32 1, !"sign-return-address-all", i32 0} +!13 = !{i32 1, !"sign-return-address-with-bkey", i32 0} +!14 = !{i32 7, !"PIC Level", i32 2} +!15 = distinct !DISubprogram(name: "f1", scope: !1, file: !1, line: 2, type: !16, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) +!16 = !DISubroutineType(types: !17) +!17 = !{null} +!18 = !DILocation(line: 3, column: 1, scope: !15) +!19 = distinct !DISubprogram(name: "f2", scope: !4, file: !4, line: 2, type: !16, scopeLine: 2, spFlags: DISPFlagDefinition, unit: !3, retainedNodes: !2) +!20 = !DILocation(line: 3, column: 1, scope: !19)