[llvm-dev] [RFC] Allowing debug intrinsics to reference multiple SSA Values

Adrian Prantl via llvm-dev llvm-dev at lists.llvm.org
Tue Feb 25 09:06:35 PST 2020



> On Feb 25, 2020, at 8:39 AM, Tozer, Stephen <stephen.tozer at sony.com> wrote:
> 
>> As the person who has advocated for DW_OP_LLVM_arg(N) before, my main motivation was to resolve the ambiguity of constant DIExpressions: As a worst-case example:
>> 
>> dbg.value(%undef, !DILocalVariable(x), DIExpression(DW_OP_constu, 42))
>> 
>> Is this undefined, or constant 42?
>> 
>> But if we make dbg.value fully variadic with all parameters pushed to the stack ahead of time, we can distinguish between
>> 
>> dbg.value(!DILocalVariable(x), DIExpression(DW_OP_constu, 42)) ; a constant
>> dbg.value(i32 42, !DILocalVariable(x), DIExpression()) ; the same constant dbg.value(%undef, !DILocalVariable(x), DIExpression(DW_OP_constu, 42)) ; undef + garbage leftover expression
>> 
>> If we do it this way and allow 0-n SSA values then I'm in support of the push-first scheme.
> 
> This seems like as good a case as any to go with the push-first approach, since it solves a meaningful problem that the alternative does not. 
> 
>> As a side note, updating dbg.values in salvageDebugInfo when we allow multiple SSA values per dbg.value will be interesting, but possible. We'll need to put the value we need to update at the top of the stack, prepend the salvage expression and then restore the order of arguments on the stack that the rest of the expression expects.
> 
> The difficulty here is that in DWARF5, there is no operator that can move an argument up the stack; there are specific operators that rotate the top 2 or 3 elements, but outside of that the only thing you can do is copy an element to the top with DW_OP_pick. Of course we don't have to stick to actual DWARF operators by any means, but I don't think there's any way to eventually express an indexed swap/move operator in DWARF either: you can duplicate an element from anywhere on the stack to the top, but you can't delete the original element or move the top element back down again. Because of this, it is necessary (I believe) to use DW_OP_pick in the general case even if all the arguments are initially pushed onto the stack, due to the limits on how we can manipulate the stack. Of course there are many expressions that don't require DW_OP_pick to evaluate, but for consistency's sake I think it's best to use it instead of the swap or rotate operators whenever any of them is needed.
> 
> Regardless of whether we push everything immediately or not, having an operator that pushes the SSA value at a given argument index onto the stack seems necessary - if we push elements initially then DW_OP_pick (or DW_OP_LLVM_pick), otherwise DW_OP_LLVM_register. In either of these cases, salvaging is simple: we simply append the salvage expression after the salvaged value's operator. It also translates cleanly to DWARF, since we can directly replace the operator in question with DW_OP_regval_type, using whichever register holds the value we're looking for as an argument, without needing to modify or even consider the rest of the expression at all.
> 

When we have <= 3 arguments (I don't want to call them registers because they may turn into constants or memory locations later on) we can use DW_OP_rot to move the one we need to adjust to the top and the DW_OP_rot the stack back into the original order. For 4-255 arguments, we need to add extra operations both to the beginning and the end of the expression, here an example for salvaging the 4th element from the top:

r0 r1 r2 r3    ; stack before
DW_OP_pick 0  

r0 r1 r2 r3 r0 ; stack after pick 0 ...
<adjustments>  ; the salvage operations for r0

r0 r1 r2 r3 r0'
DW_OP_pick 1

r0 r1 r2 r3 r0' r1
DW_OP_pick 2

r0 r1 r2 r3 r0' r1 r2
DW_OP_pick 3

r0 r1 r2 r3 r0' r1 r2 r3
<rest of expression>

r0 r1 r2 r3 result
DW_OP_swap

r0 r1 r2 result r3
DW_OP_drop

r0 r1 r2 result
DW_OP_swap

r0 r1 result r2
DW_OP_drop
DW_OP_rot
DW_OP_drop
DW_OP_drop

result

It's possible to do with just DWARF expressions, but the resulting expression may get a little long. We could also just say we support up to 3 arguments and that would probably be fine.

-- adrian


More information about the llvm-dev mailing list