Skip to content

Commit

Permalink
Recommit r288212: Emit 'no line' information for interesting 'orphan'…
Browse files Browse the repository at this point in the history
… instructions.

The LLDB tests are now ready for this patch.

DWARF specifies that "line 0" really means "no appropriate source
location" in the line table.  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).

Differential Revision: http://reviews.llvm.org/D24180


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288283 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
pogo59 committed Nov 30, 2016
1 parent b89fb12 commit 241e679
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 17 deletions.
4 changes: 3 additions & 1 deletion lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,10 @@ void DebugHandlerBase::endInstruction() {
assert(CurMI != nullptr);
// Don't create a new label after DBG_VALUE instructions.
// They don't generate code.
if (!CurMI->isDebugValue())
if (!CurMI->isDebugValue()) {
PrevLabel = nullptr;
PrevInstBB = CurMI->getParent();
}

DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
LabelsAfterInsn.find(CurMI);
Expand Down
6 changes: 4 additions & 2 deletions lib/CodeGen/AsmPrinter/DebugHandlerBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ class DebugHandlerBase : public AsmPrinterHandler {
MachineModuleInfo *MMI;

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

/// This location indicates end of function prologue and beginning of
/// function body.
Expand Down
55 changes: 47 additions & 8 deletions lib/CodeGen/AsmPrinter/DwarfDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,31 +1010,70 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
if (MI->isDebugValue())
return;
const DebugLoc &DL = MI->getDebugLoc();
if (DL == PrevInstLoc)
// When we emit a line-0 record, we don't update PrevInstLoc; so look at
// the last line number actually emitted, to see if it was line 0.
unsigned LastAsmLine =
Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine();

if (DL == PrevInstLoc) {
// If we have an ongoing unspecified location, nothing to do here.
if (!DL)
return;
// We have an explicit location, same as the previous location.
// But we might be coming back to it after a line 0 record.
if (LastAsmLine == 0 && DL.getLine() != 0) {
// Reinstate the source location but not marked as a statement.
const MDNode *Scope = DL.getScope();
recordSourceLine(DL.getLine(), DL.getCol(), Scope, /*Flags=*/0);
}
return;
}

if (!DL) {
// We have an unspecified location, which might want to be line 0.
if (UnknownLocations) {
PrevInstLoc = DL;
recordSourceLine(0, 0, nullptr, 0);
// If we have already emitted a line-0 record, don't repeat it.
if (LastAsmLine == 0)
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 || PrevLabel ||
(PrevInstBB && PrevInstBB != MI->getParent())) {
// Preserve the file number, if we can, to save space in the line table.
// Do not update PrevInstLoc, it remembers the last non-0 line.
// FIXME: Also preserve the column number, to save more space?
const MDNode *Scope = PrevInstLoc ? PrevInstLoc.getScope() : nullptr;
recordSourceLine(0, 0, Scope, 0);
}
return;
}

// We have a new, explicit location.
// 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 (DL.getLine() == 0 && LastAsmLine == 0)
return;
unsigned Flags = 0;
PrevInstLoc = DL;
if (DL == PrologEndLoc) {
Flags |= DWARF2_FLAG_PROLOGUE_END | DWARF2_FLAG_IS_STMT;
PrologEndLoc = DebugLoc();
}
if (DL.getLine() !=
Asm->OutStreamer->getContext().getCurrentDwarfLoc().getLine())
// 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;
}

static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {
Expand Down
15 changes: 10 additions & 5 deletions test/CodeGen/X86/stack-protector.ll
Original file line number Diff line number Diff line change
Expand Up @@ -3888,23 +3888,27 @@ entry:
define void @test32() #1 !dbg !7 {
entry:
; LINUX-I386-LABEL: test32:
; LINUX-I386: .loc 1 0 0 prologue_end
; LINUX-I386: .loc 1 4 2 prologue_end
; LINUX-I386: .loc 1 0 0
; LINUX-I386-NEXT: calll __stack_chk_fail

; LINUX-X64-LABEL: test32:
; LINUX-X64: .loc 1 0 0 prologue_end
; LINUX-X64: .loc 1 4 2 prologue_end
; LINUX-X64: .loc 1 0 0
; LINUX-X64-NEXT: callq __stack_chk_fail

; LINUX-KERNEL-X64-LABEL: test32:
; LINUX-KERNEL-X64: .loc 1 0 0 prologue_end
; LINUX-KERNEL-X64: .loc 1 4 2 prologue_end
; LINUX-KERNEL-X64: .loc 1 0 0
; LINUX-KERNEL-X64-NEXT: callq __stack_chk_fail

; OPENBSD-AMD64-LABEL: test32:
; OPENBSD-AMD64: .loc 1 0 0 prologue_end
; OPENBSD-AMD64: .loc 1 4 2 prologue_end
; OPENBSD-AMD64: .loc 1 0 0
; OPENBSD-AMD64-NEXT: movl
; OPENBSD-AMD64-NEXT: callq __stack_smash_handler
%0 = alloca [5 x i8], align 1
ret void
ret void, !dbg !9
}

declare double @testi_aux()
Expand Down Expand Up @@ -3940,3 +3944,4 @@ attributes #5 = { ssp "stack-protector-buffer-size"="6" }
!6 = distinct !DISubprogram(name: "__stack_chk_fail", scope: !1, type: !8, unit: !0)
!7 = distinct !DISubprogram(name: "test32", scope: !1, type: !8, unit: !0)
!8 = !DISubroutineType(types: !2)
!9 = !DILocation(line: 4, column: 2, scope: !7)
2 changes: 1 addition & 1 deletion test/DebugInfo/AArch64/line-header.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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: 0x0000003c
CHECK: total_length: 0x0000003e
74 changes: 74 additions & 0 deletions test/DebugInfo/X86/dwarf-no-source-loc.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
; Verify "no source location" directives appear in appropriate places.
; RUN: llc %s -o - | FileCheck %s

; Generated from this .cpp targeting linux using -g
; and then removed function attributes as clutter.
;
; void bar(int *);
; void baz(int *);
; # 5 "no-source-loc.cpp"
; void foo(int x) {
; int z;
; if (x)
; # 20 "include.h"
; bar(&z);
; # 10 "no-source-loc.cpp"
; baz(&z);
; }

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: uwtable
define void @_Z3fooi(i32 %x) !dbg !6 {
entry:
%x.addr = alloca i32, align 4
%z = alloca i32, align 4
store i32 %x, i32* %x.addr, align 4
%0 = load i32, i32* %x.addr, align 4, !dbg !8
%tobool = icmp ne i32 %0, 0, !dbg !8
br i1 %tobool, label %if.then, label %if.end, !dbg !8

if.then: ; preds = %entry
call void @_Z3barPi(i32* %z), !dbg !9
br label %if.end, !dbg !9

if.end: ; preds = %if.then, %entry
call void @_Z3bazPi(i32* %z), !dbg !12
ret void, !dbg !14
}

; CHECK: .loc 1 7 7
; CHECK-NOT: .loc
; CHECK: .loc 1 0 0 is_stmt 0
; CHECK-NOT: .loc
; CHECK: .loc 2 20 5 is_stmt 1
; CHECK: .LBB0_2:
; CHECK-NEXT: .loc 2 0 0 is_stmt 0
; CHECK-NOT: .loc
; CHECK: .loc 1 10 3 is_stmt 1


declare void @_Z3barPi(i32*)

declare void @_Z3bazPi(i32*)

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!llvm.ident = !{!5}

!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)
!1 = !DIFile(filename: "no-source-loc.cpp", directory: "/tests")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{!"clang version 4.0.0 (trunk 278782)"}
!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)
!7 = !DISubroutineType(types: !2)
!8 = !DILocation(line: 7, column: 7, scope: !6)
!9 = !DILocation(line: 20, column: 5, scope: !10)
!10 = !DILexicalBlockFile(scope: !6, file: !11, discriminator: 0)
!11 = !DIFile(filename: "include.h", directory: "/tests")
!12 = !DILocation(line: 10, column: 3, scope: !13)
!13 = !DILexicalBlockFile(scope: !6, file: !1, discriminator: 0)
!14 = !DILocation(line: 11, column: 1, scope: !13)

0 comments on commit 241e679

Please sign in to comment.