diff options
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h | 6 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 55 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/stack-protector.ll | 15 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/AArch64/line-header.ll | 2 | ||||
| -rw-r--r-- | llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll | 74 | 
6 files changed, 139 insertions, 17 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index d30f106a939..5607242a7f1 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -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); diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h index b8bbcec133f..cd02c4446a7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.h @@ -38,10 +38,12 @@ protected:    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. diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 884e03d3f0a..949516b17a0 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -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) { diff --git a/llvm/test/CodeGen/X86/stack-protector.ll b/llvm/test/CodeGen/X86/stack-protector.ll index d3ff61743ed..5166ed5b02a 100644 --- a/llvm/test/CodeGen/X86/stack-protector.ll +++ b/llvm/test/CodeGen/X86/stack-protector.ll @@ -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() @@ -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) diff --git a/llvm/test/DebugInfo/AArch64/line-header.ll b/llvm/test/DebugInfo/AArch64/line-header.ll index f8220233faa..38d06f263e2 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: 0x0000003c +CHECK: total_length: 0x0000003e diff --git a/llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll b/llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll new file mode 100644 index 00000000000..d71f95d999e --- /dev/null +++ b/llvm/test/DebugInfo/X86/dwarf-no-source-loc.ll @@ -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)  | 

