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

Tozer, Stephen via llvm-dev llvm-dev at lists.llvm.org
Thu Feb 20 08:54:42 PST 2020

Currently, the debug intrinsic functions each have 3 arguments: an SSA value representing either the address or Value of a local variable, a DILocalVariable, and a complex expression. If the SSA value is an Instruction, and that Instruction is at some point deleted, we attempt to salvage the SSA value by recreating the instruction within the complex expression. If the instruction cannot be replicated by a complex expression, then the variable location is dropped causing a reduction in coverage. One of the key restrictions on this process at the moment is that each intrinsic can only reference a single SSA value; a numeric constant may be represented within the expression itself, allowing for binary operators with a constant operand to be salvaged:

%c = add i32 %a, 4
llvm.dbg.value(metadata i32 %c, DILocalVariable("x"), DIExpression())
; Salvage...
llvm.dbg.value(metadata i32 %a, DILocalVariable("x"), DIExpression(DW_OP_constu, 4, DW_OP_plus))

This proposal is to allow multiple SSA value references within a debug intrinsic, allowing binary operators with non-constant operands to be salvaged. This is a long-awaited feature, with an open bugzilla[0] and support from members of the community[1][2]. To implement this change, each debug intrinsic will contain a list of SSA values instead of just one, and a new operator will be added: DW_OP_LLVM_register, which takes as its only argument the index of an SSA value within the intrinsic's list, and pushes that SSA value onto the expression stack. Two proposed syntaxes for the list of SSA values - though suitable alternatives may be worth considering - are to either replace the first argument of the intrinsic function with an MDNode containing the SSA values as operands, or to remove the first argument and make the intrinsic function variadic, passing the SSA value list as vargs:

%c = add i32 %a, %b
llvm.dbg.value(metadata i32 %c, DILocalVariable("x"), DIExpression())
; Salvage...
llvm.dbg.value(!{metadata i32 %a, metadata i32 %b}, DILocalVariable("x"), DIExpression(DW_OP_LLVM_register, 0, DW_OP_LLVM_register, 1, DW_OP_plus))
; Alternatively, the intrinsic function could be made variadic...
llvm.dbg.value(DILocalVariable("x"), DIExpression(DW_OP_LLVM_register, 0, DW_OP_LLVM_register, 1, DW_OP_plus), metadata i32 %a, metadata i32 %b)

The new operator DW_OP_LLVM_register would exist in the IR and MIR, and further down the pipeline be replaced by the appropriate operator for the target debug output. For example, when producing DWARF this would be replaced by DW_OP_regval_type, which pushes the contents of a given register interpreted as a value of a given type onto the DWARF expression stack.

This has the potential to allow salvaging in a much greater number of cases than is currently possible. There are also potential follow-up tasks, such as allowing the salvaging of conditional values, that would further improve debug variable availability. The following table gives, for several of the multi-source application projects in the test suite, the number of successful invocations of SalvageDebugInfo, and the number of failed salvages for each type of unsalvageable instruction:

            Success             Variadic Binops     Variadic GEPs       Cmp Insts           Select Insts        Load Insts          Phi Nodes           Alloca Insts        Call Insts
ALAC        261                 29                  61                  0                   0                   1                   12                  0                   0
Burg        50                  1                   9                   0                   1                   95                  6                   0                   0
hbd         514                 16                  1                   0                   3                   45                  10                  0                   4
Lua         270                 12                  54                  0                   12                  46                  32                  1                   0
minisat     458                 10                  10                  3                   1                   35                  4                   0                   0
sgefa       439                 1                   121                 0                   20                  14                  55                  0                   0
SIBsim4     153                 15                  6                   0                   3                   40                  3                   0                   0
siod        112                 2                   1                   0                   0                   11                  5                   2                   1
SPASS       1241                70                  27                  27                  27                  2114                156                 0                   7
spiff       39                  0                   15                  0                   0                   7                   2                   1                   0
sqlite3     2322                94                  167                 6                   37                  1143                136                 4                   10
treecc      127                 1                   0                   0                   1                   350                 37                  0                   1
viterbi     7                   0                   1                   0                   1                   1                   0                   0                   0

Of these categories, the first 3 will become salvageable after this work is implemented, and Select Insts will also be salvageable with some follow-up work to enable conditional branching in complex expressions. The remainder are not salvageable in general, although it's possible that the specific passes that delete those instructions may be able to preserve the debug info as long as the code isn't totally dead.

[0] https://bugs.llvm.org/show_bug.cgi?id=39141
[1] https://reviews.llvm.org/D51976#1237060
[2] http://lists.llvm.org/pipermail/llvm-dev/2019-November/137021.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20200220/fbb46f08/attachment-0001.html>

More information about the llvm-dev mailing list