Skip to content

Commit ac7fe5e

Browse files
committedDec 12, 2016
Recommit r288212: Emit 'no line' information for interesting 'orphan' instructions.
DWARF specifies that "line 0" really means "no appropriate source location" in the line table. By default, use this for branch targets and some other cases that have no specified source location, to prevent inheriting unfortunate line numbers from physically preceding instructions (which might be from completely unrelated source). Updated patch allows enabling or suppressing this behavior for all unspecified source locations. Differential Revision: http://reviews.llvm.org/D24180 llvm-svn: 289468
1 parent d4be889 commit ac7fe5e

File tree

9 files changed

+155
-25
lines changed

9 files changed

+155
-25
lines changed
 

‎llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,10 @@ void DebugHandlerBase::endInstruction() {
200200
assert(CurMI != nullptr);
201201
// Don't create a new label after DBG_VALUE instructions.
202202
// They don't generate code.
203-
if (!CurMI->isDebugValue())
203+
if (!CurMI->isDebugValue()) {
204204
PrevLabel = nullptr;
205+
PrevInstBB = CurMI->getParent();
206+
}
205207

206208
DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
207209
LabelsAfterInsn.find(CurMI);

‎llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ class DebugHandlerBase : public AsmPrinterHandler {
3838
MachineModuleInfo *MMI;
3939

4040
/// Previous instruction's location information. This is used to
41-
/// determine label location to indicate scope boundries in dwarf
42-
/// debug info.
41+
/// determine label location to indicate scope boundaries in debug info.
42+
/// We track the previous instruction's source location (if not line 0),
43+
/// whether it was a label, and its parent BB.
4344
DebugLoc PrevInstLoc;
4445
MCSymbol *PrevLabel = nullptr;
46+
const MachineBasicBlock *PrevInstBB = nullptr;
4547

4648
/// This location indicates end of function prologue and beginning of
4749
/// function body.

‎llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

+57-13
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,6 @@ static cl::opt<bool>
6262
DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
6363
cl::desc("Disable debug info printing"));
6464

65-
static cl::opt<bool> UnknownLocations(
66-
"use-unknown-locations", cl::Hidden,
67-
cl::desc("Make an absence of debug location information explicit."),
68-
cl::init(false));
69-
7065
static cl::opt<bool>
7166
GenerateGnuPubSections("generate-gnu-dwarf-pub-sections", cl::Hidden,
7267
cl::desc("Generate GNU-style pubnames and pubtypes"),
@@ -81,6 +76,13 @@ namespace {
8176
enum DefaultOnOff { Default, Enable, Disable };
8277
}
8378

79+
static cl::opt<DefaultOnOff> UnknownLocations(
80+
"use-unknown-locations", cl::Hidden,
81+
cl::desc("Make an absence of debug location information explicit."),
82+
cl::values(clEnumVal(Default, "At top of block or after label"),
83+
clEnumVal(Enable, "In all cases"), clEnumVal(Disable, "Never")),
84+
cl::init(Default));
85+
8486
static cl::opt<DefaultOnOff>
8587
DwarfAccelTables("dwarf-accel-tables", cl::Hidden,
8688
cl::desc("Output prototype dwarf accelerator tables."),
@@ -1010,31 +1012,73 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
10101012
if (MI->isDebugValue() || MI->isCFIInstruction())
10111013
return;
10121014
const DebugLoc &DL = MI->getDebugLoc();
1013-
if (DL == PrevInstLoc)
1015+
// When we emit a line-0 record, we don't update PrevInstLoc; so look at
1016+
// the last line number actually emitted, to see if it was line 0.
1017+
unsigned LastAsmLine =
1018+
Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();
1019+
1020+
if (DL == PrevInstLoc) {
1021+
// If we have an ongoing unspecified location, nothing to do here.
1022+
if (!DL)
1023+
return;
1024+
// We have an explicit location, same as the previous location.
1025+
// But we might be coming back to it after a line 0 record.
1026+
if (LastAsmLine == 0 && DL.getLine() != 0) {
1027+
// Reinstate the source location but not marked as a statement.
1028+
const MDNode *Scope = DL.getScope();
1029+
recordSourceLine(DL.getLine(), DL.getCol(), Scope, /*Flags=*/0);
1030+
}
10141031
return;
1032+
}
10151033

10161034
if (!DL) {
10171035
// We have an unspecified location, which might want to be line 0.
1018-
if (UnknownLocations) {
1019-
PrevInstLoc = DL;
1020-
recordSourceLine(0, 0, nullptr, 0);
1036+
// If we have already emitted a line-0 record, don't repeat it.
1037+
if (LastAsmLine == 0)
1038+
return;
1039+
// If user said Don't Do That, don't do that.
1040+
if (UnknownLocations == Disable)
1041+
return;
1042+
// See if we have a reason to emit a line-0 record now.
1043+
// Reasons to emit a line-0 record include:
1044+
// - User asked for it (UnknownLocations).
1045+
// - Instruction has a label, so it's referenced from somewhere else,
1046+
// possibly debug information; we want it to have a source location.
1047+
// - Instruction is at the top of a block; we don't want to inherit the
1048+
// location from the physically previous (maybe unrelated) block.
1049+
if (UnknownLocations == Enable || PrevLabel ||
1050+
(PrevInstBB && PrevInstBB != MI->getParent())) {
1051+
// Preserve the file number, if we can, to save space in the line table.
1052+
// Do not update PrevInstLoc, it remembers the last non-0 line.
1053+
// FIXME: Also preserve the column number, to save more space?
1054+
const MDNode *Scope = PrevInstLoc ? PrevInstLoc.getScope() : nullptr;
1055+
recordSourceLine(0, 0, Scope, 0);
10211056
}
10221057
return;
10231058
}
10241059

1025-
// We have a new, explicit location.
1060+
// We have an explicit location, different from the previous location.
1061+
// Don't repeat a line-0 record, but otherwise emit the new location.
1062+
// (The new location might be an explicit line 0, which we do emit.)
1063+
if (DL.getLine() == 0 && LastAsmLine == 0)
1064+
return;
10261065
unsigned Flags = 0;
1027-
PrevInstLoc = DL;
10281066
if (DL == PrologEndLoc) {
10291067
Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT;
10301068
PrologEndLoc = DebugLoc();
10311069
}
1032-
if (DL.getLine() !=
1033-
Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine())
1070+
// If the line changed, we call that a new statement; unless we went to
1071+
// line 0 and came back, in which case it is not a new statement.
1072+
unsigned OldLine = PrevInstLoc ? PrevInstLoc.getLine() : LastAsmLine;
1073+
if (DL.getLine() && DL.getLine() != OldLine)
10341074
Flags |= DWARF2_FLAG_IS_STMT;
10351075

10361076
const MDNode *Scope = DL.getScope();
10371077
recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
1078+
1079+
// If we're not at line 0, remember this location.
1080+
if (DL.getLine())
1081+
PrevInstLoc = DL;
10381082
}
10391083

10401084
static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {

‎llvm/test/CodeGen/X86/stack-protector.ll

+10-5
Original file line numberDiff line numberDiff line change
@@ -3888,23 +3888,27 @@ entry:
38883888
define void @test32() #1 !dbg !7 {
38893889
entry:
38903890
; LINUX-I386-LABEL: test32:
3891-
; LINUX-I386: .loc 1 0 0 prologue_end
3891+
; LINUX-I386: .loc 1 4 2 prologue_end
3892+
; LINUX-I386: .loc 1 0 0
38923893
; LINUX-I386-NEXT: calll __stack_chk_fail
38933894

38943895
; LINUX-X64-LABEL: test32:
3895-
; LINUX-X64: .loc 1 0 0 prologue_end
3896+
; LINUX-X64: .loc 1 4 2 prologue_end
3897+
; LINUX-X64: .loc 1 0 0
38963898
; LINUX-X64-NEXT: callq __stack_chk_fail
38973899

38983900
; LINUX-KERNEL-X64-LABEL: test32:
3899-
; LINUX-KERNEL-X64: .loc 1 0 0 prologue_end
3901+
; LINUX-KERNEL-X64: .loc 1 4 2 prologue_end
3902+
; LINUX-KERNEL-X64: .loc 1 0 0
39003903
; LINUX-KERNEL-X64-NEXT: callq __stack_chk_fail
39013904

39023905
; OPENBSD-AMD64-LABEL: test32:
3903-
; OPENBSD-AMD64: .loc 1 0 0 prologue_end
3906+
; OPENBSD-AMD64: .loc 1 4 2 prologue_end
3907+
; OPENBSD-AMD64: .loc 1 0 0
39043908
; OPENBSD-AMD64-NEXT: movl
39053909
; OPENBSD-AMD64-NEXT: callq __stack_smash_handler
39063910
%0 = alloca [5 x i8], align 1
3907-
ret void
3911+
ret void, !dbg !9
39083912
}
39093913

39103914
declare double @testi_aux()
@@ -3940,3 +3944,4 @@ attributes #5 = { ssp "stack-protector-buffer-size"="6" }
39403944
!6 = distinct !DISubprogram(name: "__stack_chk_fail", scope: !1, type: !8, unit: !0)
39413945
!7 = distinct !DISubprogram(name: "test32", scope: !1, type: !8, unit: !0)
39423946
!8 = !DISubroutineType(types: !2)
3947+
!9 = !DILocation(line: 4, column: 2, scope: !7)

‎llvm/test/CodeGen/X86/unknown-location.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: llc < %s -asm-verbose=false -mtriple=x86_64-apple-darwin10 -use-unknown-locations | FileCheck %s
1+
; RUN: llc < %s -asm-verbose=false -mtriple=x86_64-apple-darwin10 -use-unknown-locations=Enable | FileCheck %s
22

33
; The divide instruction does not have a debug location. CodeGen should
44
; represent this in the debug information. This is done by setting line

‎llvm/test/DebugInfo/AArch64/line-header.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
; check line table length is correctly calculated for both big and little endian
55
CHECK-LABEL: .debug_line contents:
6-
CHECK: total_length: 0x0000003c
6+
CHECK: total_length: 0x0000003e

‎llvm/test/DebugInfo/MIR/X86/no-cfi-loc.mir

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Verify that a CFI instruction with no debug location
22
# does not result in a line-0 location in the assembler.
3-
# RUN: %llc_dwarf -start-after=prologepilog -march=x86-64 -use-unknown-locations %s -o - | FileCheck %s
3+
# RUN: %llc_dwarf -start-after=prologepilog -march=x86-64 -use-unknown-locations=Enable %s -o - | FileCheck %s
44
#
55
# CHECK-NOT: .loc 1 0
66
# CHECK: .cfi_def_cfa_offset
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
; Verify "no source location" directives appear in appropriate places,
2+
; but don't appear when we explicitly suppress them.
3+
; RUN: llc < %s -o - | FileCheck %s
4+
; RUN: llc < %s -o - -use-unknown-locations=Disable | FileCheck %s --check-prefix=DISABLE
5+
6+
; Generated from this .cpp targeting linux using -g
7+
; and then removed function attributes as clutter.
8+
;
9+
; void bar(int *);
10+
; void baz(int *);
11+
; # 5 "no-source-loc.cpp"
12+
; void foo(int x) {
13+
; int z;
14+
; if (x)
15+
; # 20 "include.h"
16+
; bar(&z);
17+
; # 10 "no-source-loc.cpp"
18+
; baz(&z);
19+
; }
20+
21+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
22+
target triple = "x86_64-unknown-linux-gnu"
23+
24+
; Function Attrs: uwtable
25+
define void @_Z3fooi(i32 %x) !dbg !6 {
26+
entry:
27+
%x.addr = alloca i32, align 4
28+
%z = alloca i32, align 4
29+
store i32 %x, i32* %x.addr, align 4
30+
%0 = load i32, i32* %x.addr, align 4, !dbg !8
31+
%tobool = icmp ne i32 %0, 0, !dbg !8
32+
br i1 %tobool, label %if.then, label %if.end, !dbg !8
33+
34+
if.then: ; preds = %entry
35+
call void @_Z3barPi(i32* %z), !dbg !9
36+
br label %if.end, !dbg !9
37+
38+
if.end: ; preds = %if.then, %entry
39+
call void @_Z3bazPi(i32* %z), !dbg !12
40+
ret void, !dbg !14
41+
}
42+
43+
; CHECK: .loc 1 7 7
44+
; CHECK-NOT: .loc
45+
; CHECK: .loc 1 0 0 is_stmt 0
46+
; CHECK-NOT: .loc
47+
; CHECK: .loc 2 20 5 is_stmt 1
48+
; CHECK: .LBB0_2:
49+
; CHECK-NEXT: .loc 2 0 0 is_stmt 0
50+
; CHECK-NOT: .loc
51+
; CHECK: .loc 1 10 3 is_stmt 1
52+
;
53+
; DISABLE-NOT: .loc 1 0
54+
55+
declare void @_Z3barPi(i32*)
56+
57+
declare void @_Z3bazPi(i32*)
58+
59+
!llvm.dbg.cu = !{!0}
60+
!llvm.module.flags = !{!3, !4}
61+
!llvm.ident = !{!5}
62+
63+
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 4.0.0 (trunk 278782)", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: !2)
64+
!1 = !DIFile(filename: "no-source-loc.cpp", directory: "/tests")
65+
!2 = !{}
66+
!3 = !{i32 2, !"Dwarf Version", i32 4}
67+
!4 = !{i32 2, !"Debug Info Version", i32 3}
68+
!5 = !{!"clang version 4.0.0 (trunk 278782)"}
69+
!6 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 5, type: !7, isLocal: false, isDefinition: true, scopeLine: 5, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
70+
!7 = !DISubroutineType(types: !2)
71+
!8 = !DILocation(line: 7, column: 7, scope: !6)
72+
!9 = !DILocation(line: 20, column: 5, scope: !10)
73+
!10 = !DILexicalBlockFile(scope: !6, file: !11, discriminator: 0)
74+
!11 = !DIFile(filename: "include.h", directory: "/tests")
75+
!12 = !DILocation(line: 10, column: 3, scope: !13)
76+
!13 = !DILexicalBlockFile(scope: !6, file: !1, discriminator: 0)
77+
!14 = !DILocation(line: 11, column: 1, scope: !13)

‎llvm/test/DebugInfo/X86/tail-merge.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: llc %s -mtriple=x86_64-unknown-unknown -use-unknown-locations=true -o - | FileCheck %s
1+
; RUN: llc %s -mtriple=x86_64-unknown-unknown -use-unknown-locations=Enable -o - | FileCheck %s
22

33
; Generated with "clang -gline-tables-only -c -emit-llvm -o - | opt -sroa -S"
44
; from source:

0 commit comments

Comments
 (0)
Please sign in to comment.