summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp112
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h3
-rw-r--r--llvm/test/DebugInfo/AArch64/line-header.ll2
-rw-r--r--llvm/test/DebugInfo/ARM/single-constant-use-preserves-dbgloc.ll3
-rw-r--r--llvm/test/DebugInfo/Mips/delay-slot.ll2
-rw-r--r--llvm/test/DebugInfo/NVPTX/debug-info.ll2
-rw-r--r--llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll11
-rw-r--r--llvm/test/DebugInfo/X86/dwarf-no-source-loc.mir74
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
+...
OpenPOWER on IntegriCloud