Skip to content

Commit

Permalink
[DebugInfo] Stop changing labels for register-described parameter DBG…
Browse files Browse the repository at this point in the history
…_VALUEs

Summary:
This is a follow-up to D57510. This patch stops DebugHandlerBase from
changing the starting label for the first non-overlapping,
register-described parameter DBG_VALUEs to the beginning of the
function. That code did not consider what defined the registers, which
could result in the ranges for the debug values starting before their
defining instructions. We currently do not emit debug values for
constant values directly at the start of the function, so this code is
still useful for such values, but my intention is to remove the code
from DebugHandlerBase completely when we get there. One reason for
removing it is that the code violates the history map's ranges, which I
think can make it quite confusing when troubleshooting.

In D57510, PrologEpilogInserter was amended so that parameter DBG_VALUEs
now are kept at the start of the entry block, even after emission of
prologue code. That was done to reduce the degradation of debug
completeness from this patch. PR40638 is another example, where the
lexical-scope trimming that LDV does, in combination with scheduling,
results in instructions after the prologue being left without locations.
There might be other cases where the DBG_VALUEs are pushed further down,
for which the DebugHandlerBase code may be helpful, but as it now quite
often result in incorrect locations, even after the prologue, it seems
better to remove that code, and try to work our way up with accurate
locations.

In the long run we should maybe not aim to provide accurate locations
inside the prologue. Some single location descriptions, at least those
referring to stack values, generate inaccurate values inside the
epilogue, so we maybe should not aim to achieve accuracy for location
lists. However, it seems that we now emit line number programs that can
result in GDB and LLDB stopping inside the prologue when doing line
number stepping into functions. See PR40188 for more information.

A summary of some of the changed test cases is available in PR40188#c2.

Reviewers: aprantl, dblaikie, rnk, jmorse

Reviewed By: aprantl

Subscribers: jdoerfert, jholewinski, jvesely, javed.absar, llvm-commits

Tags: #debug-info, #llvm

Differential Revision: https://reviews.llvm.org/D57511

llvm-svn: 353928
  • Loading branch information
dstenb committed Feb 13, 2019
1 parent ab061d3 commit 9dbeca3
Show file tree
Hide file tree
Showing 12 changed files with 35 additions and 21 deletions.
26 changes: 19 additions & 7 deletions llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
Expand Up @@ -215,24 +215,36 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
if (Ranges.empty())
continue;

// The first mention of a function argument gets the CurrentFnBegin
// label, so arguments are visible when breaking at function entry.
auto IsDescribedByReg = [](const MachineInstr *MI) {
return MI->getOperand(0).isReg() && MI->getOperand(0).getReg();
};

// The first mention of a function argument gets the CurrentFnBegin label,
// so arguments are visible when breaking at function entry.
//
// We do not change the label for values that are described by registers,
// as that could place them above their defining instructions. We should
// ideally not change the labels for constant debug values either, since
// doing that violates the ranges that are calculated in the history map.
// However, we currently do not emit debug values for constant arguments
// directly at the start of the function, so this code is still useful.
const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable();
if (DIVar->isParameter() &&
getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
if (!IsDescribedByReg(Ranges.front().first))
LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
if (Ranges.front().first->getDebugExpression()->isFragment()) {
// Mark all non-overlapping initial fragments.
for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
const DIExpression *Fragment = I->first->getDebugExpression();
if (std::all_of(Ranges.begin(), I,
if (std::any_of(Ranges.begin(), I,
[&](DbgValueHistoryMap::InstrRange Pred) {
return !Fragment->fragmentsOverlap(
return Fragment->fragmentsOverlap(
Pred.first->getDebugExpression());
}))
LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();
else
break;
if (!IsDescribedByReg(I->first))
LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/AMDGPU/llvm.dbg.value.ll
Expand Up @@ -4,6 +4,7 @@
; GCN-LABEL: {{^}}test_debug_value:
; NOOPT: .loc 1 1 42 prologue_end ; /tmp/test_debug_value.cl:1:42
; NOOPT-NEXT: s_load_dwordx2 s[4:5], s[4:5], 0x0
; NOOPT-NEXT: .Ltmp
; NOOPT-NEXT: ;DEBUG_VALUE: test_debug_value:globalptr_arg <- $sgpr4_sgpr5

; GCN: flat_store_dword
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/DebugInfo/AArch64/asan-stack-vars.mir
Expand Up @@ -28,7 +28,7 @@
# CHECK: "_cmd"
# CHECK: DW_TAG_formal_parameter
# CHECK-NEXT: DW_AT_location
# CHECK-NEXT: [0x{{0*}}, 0x{{.*}}):
# CHECK-NEXT: [0x{{.*}}, 0x{{.*}}):
# CHECK-NOT: DW_AT_
# CHECK: [0x{{.*}}, [[FN_END]]):
# CHECK-NEXT: DW_AT_name {{.*}}"imageSize"
Expand Down
1 change: 1 addition & 0 deletions llvm/test/DebugInfo/ARM/partial-subreg.ll
Expand Up @@ -9,6 +9,7 @@
; CHECK: DW_AT_name {{.*}}"subscript.get"
; CHECK: DW_TAG_formal_parameter
; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] ({{.*}}
; CHECK-NEXT: [0x{{.*}}, 0x{{.*}}): DW_OP_regx D16, DW_OP_piece 0x8, DW_OP_regx D17, DW_OP_piece 0x4
; CHECK-NEXT: [0x{{.*}}, 0x{{.*}}): DW_OP_regx D16, DW_OP_piece 0x8, DW_OP_regx D17, DW_OP_piece 0x4, DW_OP_regx D16, DW_OP_piece 0x8, DW_OP_regx D17, DW_OP_piece 0x4

source_filename = "simd.ll"
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/DebugInfo/COFF/fp-stack.ll
Expand Up @@ -10,14 +10,14 @@ entry:
ret double %sub
}

; ASM: .cv_def_range Lfunc_begin0 Lfunc_end0, "A\021\200\000\000\000"
; ASM: .cv_def_range Ltmp1 Lfunc_end0, "A\021\200\000\000\000"
; OBJ: DefRangeRegisterSym {
; OBJ: Register: ST0 (0x80)
; OBJ: MayHaveNoName: 0
; OBJ: LocalVariableAddrRange {
; OBJ: OffsetStart: .text+0x0
; OBJ: OffsetStart: .text+0x6
; OBJ: ISectStart: 0x0
; OBJ: Range: 0x7
; OBJ: Range: 0x1
; OBJ: }
; OBJ: }

Expand Down
2 changes: 1 addition & 1 deletion llvm/test/DebugInfo/COFF/fpo-stack-protect.ll
Expand Up @@ -30,7 +30,7 @@
; CHECK: addl $20, %esp
; CHECK: popl %esi
; CHECK: retl
; CHECK: Ltmp2:
; CHECK: Ltmp3:
; CHECK: .cv_fpo_endproc

; ModuleID = 't.c'
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/DebugInfo/COFF/pieces.ll
Expand Up @@ -136,7 +136,7 @@
; ASM: .asciz "pad_right" # Function name
; ASM: .short 4414 # Record kind: S_LOCAL
; ASM: .asciz "o"
; ASM: .cv_def_range .Lfunc_begin1 .Ltmp8, "C\021\021\000\000\000\004\000\000\000"
; ASM: .cv_def_range .Ltmp8 .Ltmp8, "C\021\021\000\000\000\004\000\000\000"

; OBJ-LABEL: GlobalProcIdSym {
; OBJ: Kind: S_GPROC32_ID (0x1147)
Expand All @@ -159,7 +159,7 @@
; ASM: .asciz "pad_left" # Function name
; ASM: .short 4414 # Record kind: S_LOCAL
; ASM: .asciz "o"
; ASM: .cv_def_range .Lfunc_begin2 .Ltmp10, "C\021\021\000\000\000\000\000\000\000"
; ASM: .cv_def_range .Ltmp10 .Ltmp10, "C\021\021\000\000\000\000\000\000\000"

; OBJ-LABEL: GlobalProcIdSym {
; OBJ: Kind: S_GPROC32_ID (0x1147)
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/DebugInfo/MIR/AArch64/clobber-sp.mir
Expand Up @@ -4,7 +4,7 @@
# CHECK: DW_TAG_formal_parameter
# CHECK: DW_TAG_formal_parameter
# CHECK-NEXT: DW_AT_location
# CHECK-NEXT: [0x0000000000000000, 0x0000000000000014): DW_OP_reg1 W1
# CHECK-NEXT: [0x0000000000000010, 0x0000000000000014): DW_OP_reg1 W1
# CHECK-NEXT: [0x0000000000000014, 0x0000000000000038): DW_OP_breg31 WSP+8
# CHECK-NEXT: DW_AT_name {{.*}}"y"

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/DebugInfo/NVPTX/debug-info.ll
Expand Up @@ -4781,8 +4781,8 @@ if.end: ; preds = %if.then, %entry
; CHECK-NEXT: .b8 6 // DW_AT_call_line
; CHECK-NEXT: .b8 43 // Abbrev [43] 0x270e:0x22 DW_TAG_inlined_subroutine
; CHECK-NEXT: .b32 9791 // DW_AT_abstract_origin
; CHECK-NEXT: .b64 Ltmp9 // DW_AT_low_pc
; CHECK-NEXT: .b64 Ltmp10 // DW_AT_high_pc
; CHECK-NEXT: .b64 Ltmp10 // DW_AT_low_pc
; CHECK-NEXT: .b64 Ltmp11 // DW_AT_high_pc
; CHECK-NEXT: .b8 12 // DW_AT_call_file
; CHECK-NEXT: .b8 8 // DW_AT_call_line
; CHECK-NEXT: .b8 44 // Abbrev [44] 0x2725:0x5 DW_TAG_formal_parameter
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/DebugInfo/X86/debug-loc-asan.mir
Expand Up @@ -27,7 +27,7 @@
# We expect two location ranges for the variable.
#
# First, its address is stored in %rcx:
# CHECK: .quad .Lfunc_begin0-.Lfunc_begin0
# CHECK: .quad .Ltmp0-.Lfunc_begin0
# CHECK-NEXT: .quad [[START_LABEL]]-.Lfunc_begin0
# CHECK: DW_OP_breg2
# DWARF: DW_TAG_formal_parameter
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/DebugInfo/X86/debug-loc-offset.mir
Expand Up @@ -42,7 +42,7 @@
# CHECK: DW_TAG_formal_parameter
# CHECK-NOT: DW_TAG
# CHECK: DW_AT_location [DW_FORM_sec_offset] ({{.*}}
# CHECK-NEXT: [0x00000020, 0x00000037): DW_OP_breg0 EAX+0, DW_OP_deref
# CHECK-NEXT: [0x00000029, 0x00000037): DW_OP_breg0 EAX+0, DW_OP_deref
# CHECK-NEXT: [0x00000037, 0x00000063): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref
# CHECK-NEXT: DW_AT_name [DW_FORM_strp]{{.*}}"a"
#
Expand Down Expand Up @@ -70,7 +70,7 @@
# CHECK-NEXT: [0x00000000, 0x0000000a): DW_OP_consts +0, DW_OP_stack_value
# CHECK-NEXT: [0x0000000a, 0x00000017): DW_OP_consts +1, DW_OP_stack_value
# CHECK: 0x00000022:
# CHECK-NEXT: [0x00000000, 0x00000017): DW_OP_breg0 EAX+0, DW_OP_deref
# CHECK-NEXT: [0x00000009, 0x00000017): DW_OP_breg0 EAX+0, DW_OP_deref
# CHECK-NEXT: [0x00000017, 0x00000043): DW_OP_breg5 EBP-8, DW_OP_deref, DW_OP_deref
--- |
target triple = "i386-unknown-linux-gnu"
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/DebugInfo/X86/dw_op_minus_direct.ll
Expand Up @@ -17,7 +17,7 @@

; CHECK: .debug_loc contents:
; CHECK: 0x00000000:
; CHECK-NEXT: [0x0000000000000000, 0x0000000000000004): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_lit1, DW_OP_minus, DW_OP_stack_value
; CHECK-NEXT: [0x0000000000000003, 0x0000000000000004): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_lit1, DW_OP_minus, DW_OP_stack_value
; rax+0, constu 0xffffffff, and, constu 0x00000001, minus, stack-value

source_filename = "minus.c"
Expand Down

0 comments on commit 9dbeca3

Please sign in to comment.