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

Tozer, Stephen via llvm-dev llvm-dev at lists.llvm.org
Tue Feb 25 08:39:18 PST 2020


>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.



More information about the llvm-dev mailing list