1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

Remove overzealous verifier check on DW_OP_LLVM_entry_value and improve the documentation

Based on the comments in the code, the idea is that AsmPrinter is
unable to produce entry value blocks of arbitrary length, such as
DW_OP_entry_value [DW_OP_reg5 DW_OP_lit1 DW_OP_plus]. But the way the
Verifier check is written it also disallows DW_OP_entry_value
[DW_OP_reg5] DW_OP_lit1 DW_OP_plus which seems to overshoot the
target.

Note that this patch does not change any of the safety guards in
LiveDebugValues — there is zero behavior change for clang. It just
allows us to legalize more complex expressions in future patches.

rdar://73907559

Differential Revision: https://reviews.llvm.org/D95990
This commit is contained in:
Adrian Prantl 2021-02-04 10:57:44 -08:00
parent 685525f3ae
commit 81c0c6d2aa
3 changed files with 28 additions and 25 deletions

View File

@ -5259,26 +5259,28 @@ The current supported opcode vocabulary is limited:
of the stack is treated as an address. The second stack entry is treated as an of the stack is treated as an address. The second stack entry is treated as an
address space identifier. address space identifier.
- ``DW_OP_stack_value`` marks a constant value. - ``DW_OP_stack_value`` marks a constant value.
- ``DW_OP_LLVM_entry_value, N`` can only appear at the beginning of a - ``DW_OP_LLVM_entry_value, N`` may only appear in MIR and at the
``DIExpression``, and it specifies that all register and memory read beginning of a ``DIExpression``. In DWARF a ``DBG_VALUE``
operations for the debug value instruction's value/address operand and for instruction binding a ``DIExpression(DW_OP_LLVM_entry_value`` to a
the ``(N - 1)`` operations immediately following the register is lowered to a ``DW_OP_entry_value [reg]``, pushing the
``DW_OP_LLVM_entry_value`` refer to their respective values at function value the register had upon function entry onto the stack. The next
entry. For example, ``!DIExpression(DW_OP_LLVM_entry_value, 1, ``(N - 1)`` operations will be part of the ``DW_OP_entry_value``
DW_OP_plus_uconst, 123, DW_OP_stack_value)`` specifies an expression where block argument. For example, ``!DIExpression(DW_OP_LLVM_entry_value,
the entry value of the debug value instruction's value/address operand is 1, DW_OP_plus_uconst, 123, DW_OP_stack_value)`` specifies an
pushed to the stack, and is added with 123. Due to framework limitations expression where the entry value of the debug value instruction's
``N`` can currently only be 1. value/address operand is pushed to the stack, and is added
with 123. Due to framework limitations ``N`` can currently only
be 1.
``DW_OP_LLVM_entry_value`` is only legal in MIR. The operation is introduced The operation is introduced by the ``LiveDebugValues`` pass, which
by the ``LiveDebugValues`` pass; currently only for function parameters that applies it only to function parameters that are unmodified
are unmodified throughout a function. Support is limited to function throughout the function. Support is limited to simple register
parameter that are described as simple register location descriptions, or as location descriptions, or as indirect locations (e.g., when a struct
indirect locations (e.g. when a struct is passed-by-value to a callee via a is passed-by-value to a callee via a pointer to a temporary copy
pointer to a temporary copy made in the caller). The entry value op is also made in the caller). The entry value op is also introduced by the
introduced by the ``AsmPrinter`` pass when a call site parameter value ``AsmPrinter`` pass when a call site parameter value
(``DW_AT_call_site_parameter_value``) is represented as entry value of the (``DW_AT_call_site_parameter_value``) is represented as entry value
parameter. of the parameter.
- ``DW_OP_breg`` (or ``DW_OP_bregx``) represents a content on the provided - ``DW_OP_breg`` (or ``DW_OP_bregx``) represents a content on the provided
signed offset of the specified register. The opcode is only generated by the signed offset of the specified register. The opcode is only generated by the
``AsmPrinter`` pass to describe call site parameter value which requires an ``AsmPrinter`` pass to describe call site parameter value which requires an

View File

@ -1111,8 +1111,7 @@ bool DIExpression::isValid() const {
// entry values of a simple register location. One reason for this is that // entry values of a simple register location. One reason for this is that
// we currently can't calculate the size of the resulting DWARF block for // we currently can't calculate the size of the resulting DWARF block for
// other expressions. // other expressions.
return I->get() == expr_op_begin()->get() && I->getArg(0) == 1 && return I->get() == expr_op_begin()->get() && I->getArg(0) == 1;
getNumElements() == 2;
} }
case dwarf::DW_OP_LLVM_implicit_pointer: case dwarf::DW_OP_LLVM_implicit_pointer:
case dwarf::DW_OP_LLVM_convert: case dwarf::DW_OP_LLVM_convert:
@ -1279,9 +1278,10 @@ DIExpression *DIExpression::prependOpcodes(const DIExpression *Expr,
if (EntryValue) { if (EntryValue) {
Ops.push_back(dwarf::DW_OP_LLVM_entry_value); Ops.push_back(dwarf::DW_OP_LLVM_entry_value);
// Add size info needed for entry value expression. // Use a block size of 1 for the target register operand. The
// Add plus one for target register operand. // DWARF backend currently cannot emit entry values with a block
Ops.push_back(Expr->getNumElements() + 1); // size > 1.
Ops.push_back(1);
} }
// If there are no ops to prepend, do not even add the DW_OP_stack_value. // If there are no ops to prepend, do not even add the DW_OP_stack_value.

View File

@ -1,5 +1,6 @@
; RUN: opt -S < %s 2>&1 | FileCheck %s ; RUN: opt -S < %s 2>&1 | FileCheck %s
!named = !{!0} !named = !{!0, !1}
; CHECK-NOT: invalid expression ; CHECK-NOT: invalid expression
!0 = !DIExpression(DW_OP_LLVM_entry_value, 1) !0 = !DIExpression(DW_OP_LLVM_entry_value, 1)
!1 = !DIExpression(DW_OP_LLVM_entry_value, 1, DW_OP_lit0, DW_OP_plus)