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:
parent
685525f3ae
commit
81c0c6d2aa
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user