diff options
-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 +... |