[PATCH] D83495: [DebugInfo] Add DWARF emission for DBG_VALUE_LIST
Stephen Tozer via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 15 09:30:48 PST 2021
StephenTozer added inline comments.
================
Comment at: llvm/test/DebugInfo/X86/dbg_value_list_emission.mir:51-55
+ ; (1) Check a single reg arg works.
+ DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $eax, debug-location !15
+ ; CHECK: DW_TAG_variable
+ ; CHECK-NEXT: (DW_OP_breg0 RAX+0, DW_OP_stack_value)
+ ; CHECK-NEXT: DW_AT_name ("locala")
----------------
scott.linder wrote:
> Why does this behave differently than (what I understand to be) the equivalent `DBG_VALUE` ?
>
> ```
> DBG_VALUE $eax, $noreg, !12, !DIExpression(DW_OP_stack_value), debug-location !15
> ; becomes: DW_AT_location (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value)
> ```
>
> It seems like the `DW_OP_and` is there to select a subregister (I assume EAX), but oddly it comes after the value of the register is already read (i.e. after the DW_OP_breg). I'm lost on what the intended behavior is, and why it differs between `DBG_VALUE` and `DBG_VALUE_LIST`.
>
> There is also the existing confusion around the "isIndirect" flag in `DBG_VALUE` which makes these two equivalent (and both seemingly wrong):
>
> ```
> DBG_VALUE $eax, $noreg, !25, !DIExpression(DW_OP_stack_value), debug-location !15
> ; becomes: DW_AT_location (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value)
>
> DBG_VALUE $eax, 0, !26, !DIExpression(DW_OP_stack_value), debug-location !15
> ; becomes: DW_AT_location (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value)
> ```
>
> which makes it harder still to compare.
>
>
> Would it be more straightforward to always be explicit about indirection in the new form? Why does `DW_OP_stack_value` imply a `DW_OP_deref` at all? I.e. why do we not get:
>
> ```
> DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $eax, debug-location !15
> ; CHECK: DW_TAG_variable
> ; CHECK-NEXT: (DW_OP_reg RAX, DW_OP_stack_value)
> ; CHECK-NEXT: DW_AT_name ("locala")
> ```
>
> which in this case I imagine would just be an error. I would expect the correct expression to generate the `DW_OP_breg` would be something like:
>
> ```
> DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref, DW_OP_stack_value), $eax, debug-location !15
> ; CHECK: DW_TAG_variable
> ; CHECK-NEXT: (DW_OP_breg0 RAX+0, DW_OP_stack_value)
> ; CHECK-NEXT: DW_AT_name ("locala")
> ```
>
> If we don't do this, we seem to retain some of the same ambiguity that makes the old "isIndirect" field so confusing.
To the first point: I'm looking into it now; I noticed the `DW_OP_and` before, but I'm not sure where it's coming from myself yet - the `DBG_VALUE_LIST` handling should be following essentially the same code path as `DBG_VALUE`, so this is a bug one way or another.
To the second point, I think your examples are slightly incorrect:
The `isIndirect` flag in `DBG_VALUE` is confusing and inconsistent, what it actually does is dependent on the DIExpression and not well explained. The `DBG_VALUE_LIST` implementation has no such inconsistencies however (I hope). The problem with your examples is that I think you're using `DW_OP_reg` to mean a register's literal value, and `DW_OP_breg` to mean the address pointed to by a register. This isn't quite correct, although they do act like that for most variable locations.
The actual meanings are slightly more complicated; the short answer is that `DW_OP_reg` is a Register location description: it refers to the register itself, not to the value of that register. `DW_OP_breg` on the other hand //does// refer to the literal value of a register; it's generally used with an offset as part of a Memory location expression, but if combined with `DW_OP_stack_value` then it gives the value in the register as the variable's value (albeit as an Implicit location rather than a Register location).
So with all of that said, the meaning of `(DW_OP_breg0 RAX+0, DW_OP_stack_value)` is that the variable's value can be found in `$rax`, but the variable should be read-only, which matches the meaning of the `DBG_VALUE_LIST`.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D83495/new/
https://reviews.llvm.org/D83495
More information about the llvm-commits
mailing list