diff options
author | Matthias Braun <matze@braunis.de> | 2018-10-05 18:29:24 +0000 |
---|---|---|
committer | Matthias Braun <matze@braunis.de> | 2018-10-05 18:29:24 +0000 |
commit | fb43114ba25f81b3c22a8cb27c532b559100d63a (patch) | |
tree | 59a0834b1c4c5c00e20b1f63dccdb5a0ba7f17a2 /llvm | |
parent | 90fc1007425b3e0a46146eaba1afcde8f2787e5c (diff) | |
download | bcm5719-llvm-fb43114ba25f81b3c22a8cb27c532b559100d63a.tar.gz bcm5719-llvm-fb43114ba25f81b3c22a8cb27c532b559100d63a.zip |
DwarfDebug: Pick next location in case of missing location at block begin
Context: Compiler generated instructions do not have a debug location
assigned to them. However emitting 0-line records for all of them bloats
the line tables for very little benefit so we usually avoid doing that.
Not emitting anything will lead to the previous debug location getting
applied to the locationless instructions. This is not desirable for
block begin and after labels. Previously we would emit simply emit
line-0 records in this case, this patch changes the behavior to do a
forward search for a debug location in these cases before emitting a
line-0 record to further reduce line table bloat.
Inspired by the discussion in https://reviews.llvm.org/D52862
llvm-svn: 343874
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 112 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 3 | ||||
-rw-r--r-- | llvm/test/DebugInfo/AArch64/line-header.ll | 2 | ||||
-rw-r--r-- | llvm/test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll | 3 | ||||
-rw-r--r-- | llvm/test/DebugInfo/Mips/delay-slot.ll | 2 | ||||
-rw-r--r-- | llvm/test/DebugInfo/NVPTX/debug-info.ll | 2 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll | 11 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/dwarf-no-source-loc.mir | 74 |
8 files changed, 157 insertions, 52 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 6c6a861306d..ede606131ff 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1313,6 +1313,49 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU, } } +static const DebugLoc & +findNextDebugLoc(MachineBasicBlock::const_iterator MBBI, + MachineBasicBlock::const_iterator MBBE) { + static DebugLoc NoLocation; + for ( ; MBBI != MBBE; ++MBBI) { + if (MBBI->isDebugInstr()) + continue; + const DebugLoc &DL = MBBI->getDebugLoc(); + if (DL) + return DL; + } + return NoLocation; +} + +void DwarfDebug::emitDebugLoc(const DebugLoc &DL) { + unsigned LastAsmLine = + Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine(); + + // We have an explicit location, different from the previous location. + // Don't repeat a line-0 record, but otherwise emit the new location. + // (The new location might be an explicit line 0, which we do emit.) + unsigned Line = DL.getLine(); + if (PrevInstLoc && Line == 0 && LastAsmLine == 0) + return; + unsigned Flags = 0; + if (DL == PrologEndLoc) { + Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT; + PrologEndLoc = DebugLoc(); + } + // If the line changed, we call that a new statement; unless we went to + // line 0 and came back, in which case it is not a new statement. + unsigned OldLine = PrevInstLoc ? PrevInstLoc.getLine() : LastAsmLine; + if (Line && Line != OldLine) + Flags |= DWARF2_FLAG_IS_STMT; + + const MDNode *Scope = DL.getScope(); + recordSourceLine(Line, DL.getCol(), Scope, Flags); + + // If we're not at line 0, remember this location. + if (Line) + PrevInstLoc = DL; +} + // Process beginning of an instruction. void DwarfDebug::beginInstruction(const MachineInstr *MI) { DebugHandlerBase::beginInstruction(MI); @@ -1352,54 +1395,41 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) { // If we have already emitted a line-0 record, don't repeat it. if (LastAsmLine == 0) return; + // By default we emit nothing to avoid line table bloat. However at the + // beginning of a basic block or after a label it is undesirable to let + // the previous location unchanged. In these cases do a forward search for + // the next valid debug location. + if (UnknownLocations == Default) { + const MachineBasicBlock &MBB = *MI->getParent(); + if (!PrevLabel && PrevInstBB == &MBB) + return; + + const DebugLoc &NextDL = findNextDebugLoc(MI->getIterator(), MBB.end()); + if (NextDL) { + emitDebugLoc(NextDL); + return; + } + } + + // We should emit a line-0 record. // If user said Don't Do That, don't do that. if (UnknownLocations == Disable) return; - // See if we have a reason to emit a line-0 record now. - // Reasons to emit a line-0 record include: - // - User asked for it (UnknownLocations). - // - Instruction has a label, so it's referenced from somewhere else, - // possibly debug information; we want it to have a source location. - // - Instruction is at the top of a block; we don't want to inherit the - // location from the physically previous (maybe unrelated) block. - if (UnknownLocations == Enable || PrevLabel || - (PrevInstBB && PrevInstBB != MI->getParent())) { - // Preserve the file and column numbers, if we can, to save space in - // the encoded line table. - // Do not update PrevInstLoc, it remembers the last non-0 line. - const MDNode *Scope = nullptr; - unsigned Column = 0; - if (PrevInstLoc) { - Scope = PrevInstLoc.getScope(); - Column = PrevInstLoc.getCol(); - } - recordSourceLine(/*Line=*/0, Column, Scope, /*Flags=*/0); + // Emit a line-0 record now. + // Preserve the file and column numbers, if we can, to save space in + // the encoded line table. + // Do not update PrevInstLoc, it remembers the last non-0 line. + const MDNode *Scope = nullptr; + unsigned Column = 0; + if (PrevInstLoc) { + Scope = PrevInstLoc.getScope(); + Column = PrevInstLoc.getCol(); } + recordSourceLine(/*Line=*/0, Column, Scope, /*Flags=*/0); return; } - // We have an explicit location, different from the previous location. - // Don't repeat a line-0 record, but otherwise emit the new location. - // (The new location might be an explicit line 0, which we do emit.) - if (PrevInstLoc && DL.getLine() == 0 && LastAsmLine == 0) - return; - unsigned Flags = 0; - if (DL == PrologEndLoc) { - Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT; - PrologEndLoc = DebugLoc(); - } - // If the line changed, we call that a new statement; unless we went to - // line 0 and came back, in which case it is not a new statement. - unsigned OldLine = PrevInstLoc ? PrevInstLoc.getLine() : LastAsmLine; - if (DL.getLine() && DL.getLine() != OldLine) - Flags |= DWARF2_FLAG_IS_STMT; - - const MDNode *Scope = DL.getScope(); - recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags); - - // If we're not at line 0, remember this location. - if (DL.getLine()) - PrevInstLoc = DL; + emitDebugLoc(DL); } static DebugLoc findPrologueEndLoc(const MachineFunction *MF) { diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 23aa2ba094e..ba40ad28eb7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -719,6 +719,9 @@ public: bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; } bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; } /// @} + +private: + void emitDebugLoc(const DebugLoc &DL); }; } // end namespace llvm diff --git a/llvm/test/DebugInfo/AArch64/line-header.ll b/llvm/test/DebugInfo/AArch64/line-header.ll index 1d9156debf1..2ac94728b86 100644 --- 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: 0x0000003f +CHECK: total_length: 0x0000003c diff --git a/llvm/test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll b/llvm/test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll index af76c889353..fa1dbb531d3 100644 --- a/llvm/test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll +++ b/llvm/test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll @@ -31,11 +31,10 @@ if.then: ; preds = %entry if.end: ; preds = %entry ; Materialize the constant. -; CHECK: .loc 1 0 +; CHECK: .loc 1 7 5 ; CHECK-NEXT: mvn r0, #0 ; The backend performs the store to %retval first, for some reason. -; CHECK-NEXT: .loc 1 7 5 ; CHECK-NEXT: str r0, [sp, #4] store i32 -1, i32* %x, align 4, !dbg !19 diff --git a/llvm/test/DebugInfo/Mips/delay-slot.ll b/llvm/test/DebugInfo/Mips/delay-slot.ll index 8f444bce30f..f8959a2c52b 100644 --- a/llvm/test/DebugInfo/Mips/delay-slot.ll +++ b/llvm/test/DebugInfo/Mips/delay-slot.ll @@ -16,7 +16,7 @@ ; CHECK: 0x0000000000000004 2 0 1 0 0 is_stmt prologue_end ; CHECK: 0x0000000000000024 3 0 1 0 0 is_stmt ; CHECK: 0x0000000000000034 4 0 1 0 0 is_stmt -; CHECK: 0x0000000000000048 5 0 1 0 0 is_stmt +; CHECK: 0x0000000000000044 5 0 1 0 0 is_stmt ; CHECK: 0x0000000000000058 5 0 1 0 0 is_stmt end_sequence diff --git a/llvm/test/DebugInfo/NVPTX/debug-info.ll b/llvm/test/DebugInfo/NVPTX/debug-info.ll index d5dee4055f0..f80a8426286 100644 --- a/llvm/test/DebugInfo/NVPTX/debug-info.ll +++ b/llvm/test/DebugInfo/NVPTX/debug-info.ll @@ -36,6 +36,7 @@ ; CHECK: setp.ge.s32 %p{{.+}}, %r{{.+}}, %r{{.+}}; ; CHECK: .loc [[DEBUG_INFO_CU]] 7 7 ; CHECK: @%p{{.+}} bra [[BB:.+]]; +; CHECK: .loc [[DEBUG_INFO_CU]] 8 13 ; CHECK: ld.param.f32 %f{{.+}}, [{{.+}}]; ; CHECK: ld.param.u64 %rd{{.+}}, [{{.+}}]; ; CHECK: cvta.to.global.u64 %rd{{.+}}, %rd{{.+}}; @@ -43,7 +44,6 @@ ; CHECK: cvta.to.global.u64 %rd{{.+}}, %rd{{.+}}; ; CHECK: mul.wide.u32 %rd{{.+}}, %r{{.+}}, 4; ; CHECK: add.s64 %rd{{.+}}, %rd{{.+}}, %rd{{.+}}; -; CHECK: .loc [[DEBUG_INFO_CU]] 8 13 ; CHECK: ld.global.f32 %f{{.+}}, [%rd{{.+}}]; ; CHECK: add.s64 %rd{{.+}}, %rd{{.+}}, %rd{{.+}}; ; CHECK: .loc [[DEBUG_INFO_CU]] 8 19 diff --git a/llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll b/llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll index 60d50a391a1..57030f93474 100644 --- a/llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll +++ b/llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll @@ -40,15 +40,14 @@ if.end: ; preds = %if.then, %entry ret void, !dbg !14 } -; CHECK: .loc 1 7 7 +; CHECK: .loc 1 7 7 prologue_end ; CHECK-NOT: .loc -; CHECK: .loc 1 0 7 is_stmt 0 +; CHECK: # %bb.1 +; CHECK-NEXT: .file 2 "/tests/include.h" +; CHECK-NEXT: .loc 2 20 5 ; CHECK-NOT: .loc -; CHECK: .loc 2 20 5 is_stmt 1 ; CHECK: .LBB0_2: -; CHECK-NEXT: .loc 2 0 5 is_stmt 0 -; CHECK-NOT: .loc -; CHECK: .loc 1 10 3 is_stmt 1 +; CHECK: .loc 1 10 3 ; ; DISABLE-NOT: .loc 1 0 diff --git a/llvm/test/DebugInfo/X86/dwarf-no-source-loc.mir b/llvm/test/DebugInfo/X86/dwarf-no-source-loc.mir new file mode 100644 index 00000000000..f6ad6ee6d4c --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarf-no-source-loc.mir @@ -0,0 +1,74 @@ +# RUN: llc -o - %s -start-before=patchable-function -use-unknown-locations=Default | FileCheck %s --check-prefixes=CHECK,DEFAULT +# RUN: llc -o - %s -start-before=patchable-function -use-unknown-locations=Enable | FileCheck %s --check-prefixes=CHECK,ENABLE +# RUN: llc -o - %s -start-before=patchable-function -use-unknown-locations=Disable | FileCheck %s --check-prefixes=CHECK,DISABLE +--- | + target triple = "x86_64--" + + !0 = !DIFile(filename: "dwarf-no-source-loc.mir", directory: "/") + !1 = distinct !DICompileUnit(file: !0, language: DW_LANG_C, emissionKind: LineTablesOnly) + !2 = distinct !DISubprogram(name: "func", unit: !1) + !3 = !DILocation(line: 17, scope: !2) + !4 = !DILocation(line: 42, scope: !2) + + !llvm.dbg.cu = !{!1} + !llvm.module.flags = !{!10, !11} + !10 = !{i32 2, !"Dwarf Version", i32 4} + !11 = !{i32 2, !"Debug Info Version", i32 3} + + define void @func() !dbg !2 { + unreachable + } +... +--- +name: func +body: | + bb.0: + NOOP + NOOP + $eax = MOV32ri 1, debug-location !3 + ; CHECK-LABEL: bb.0 + ; CHECK: nop + ; CHECK: nop + ; CHECK: .loc 1 17 0 prologue_end + ; CHECK: movl $1, %eax + + bb.1: + NOOP + $ebx = MOV32ri 2, debug-location !4 + ; CHECK-LABEL: bb.1 + ; DEFAULT: .loc 1 42 0 + ; ENABLE: .loc 1 0 + ; DISABLE-NOT: .loc 1 0 + ; CHECK: nop + ; ENABLE: .loc 1 42 0 + ; CHECK: movl $2, %ebx + + bb.2: + NOOP + ; CHECK-LABEL: bb.2 + ; DEFAULT: .loc 1 0 0 is_stmt 0 + ; ENABLE: .loc 1 0 0 is_stmt 0 + ; DISABLE-NOT: .loc 1 0 + ; CHECK: nop + + bb.3: + NOOP + $ecx = MOV32ri 3, debug-location !3 + ; CHECK-LABEL: bb.3 + ; CHECK: nop + ; DEFAULT: .loc 1 17 0 is_stmt 1 + ; ENABLE: .loc 1 17 0 is_stmt 1 + ; DISABLE-NOT: .loc 1 0 + ; CHECK: movl $3, %ecx + + bb.4: + NOOP + $edx = MOV32ri 4, debug-location !4 + ; CHECK: bb.4 + ; DEFAULT: .loc 1 42 0 + ; ENABLE: .loc 1 0 0 is_stmt 0 + ; DISABLE-NOT: .loc 1 0 + ; CHECK: nop + ; ENABLE: .loc 1 42 0 is_stmt 1 + ; CHECK: movl $4, %edx +... |