DBG_VALUE / DBG_VALUE_LIST handling when moving/cloning instructions

Hello,

When doing various transformations, such as moving or cloning, on instructions in the LLVM backend MIR, is there a recommended way to update or move their corresponding DBG_VALUE/DBG_VALUE_LIST instructions?

We WebAssembly devs couldn’t find a way two years ago so we created a simple class called WebAssemblyDebugValueManager, but now that LLVM gained DBG_VALUE_LIST instruction (which I came to know only recently), I’m wondering if we are reinventing the wheel. When other targets change/move/clone instructions, what do they usually use to update their corresponding debug value instructions?

Thank you,
Heejin

Hi Heejin,

When doing various transformations, such as moving or cloning, on instructions in the LLVM backend MIR, is there a recommended way to update or move their corresponding DBG_VALUE/DBG_VALUE_LIST instructions?

We WebAssembly devs couldn't find a way two years ago so we created a simple class called WebAssemblyDebugValueManager, but now that LLVM gained DBG_VALUE_LIST instruction (which I came to know only recently), I'm wondering if we are reinventing the wheel. When other targets change/move/clone instructions, what do they usually use to update their corresponding debug value instructions?

Unfortunately there is no overall strategy -- the debug intrinsics
need to be kept in the same position (or at least the same order), and
their operands kept referring to a {v,}reg containing the correct
value. Optimisations like machine-copy-propagate and machine-sink have
their own custom code to track debug intrinsics and update them
appropriately, which sometimes is a lot of work. I'm not familiar with
WebAssembly, but as it moves instructions around and re-writes
registers, it too will need to have its own custom tracking code.

Doing this for multiple registers in DBG_VALUE_LIST is much harder. If
it's too difficult, then it's safe to drop the DBG_VALUE_LIST by
making it's register operands $noreg. That should turn into "optimised
out" when seen by a debugger.

Shameless plug: there will be a new way of tracking variable locations
[0] that requires less maintenance in optimisations, and I'm now able
to make progress on it again. It's not completely clear that
WebAssembly would receive all the benefits though, as I understand it
there is no register allocation for WebAssembly.

[0] https://lists.llvm.org/pipermail/llvm-dev/2020-February/139440.html

Hello Jeremy,

Thanks for the reply! Given that our DebugValueManager does not handle DBG_VALUE_LIST correctly now, is there a way to disable generation of DBG_VALUE_LIST instruction or list version of dbg.value.list intrinsic in IR?

Some more questions are inline below:

Hi Heejin,

When doing various transformations, such as moving or cloning, on instructions in the LLVM backend MIR, is there a recommended way to update or move their corresponding DBG_VALUE/DBG_VALUE_LIST instructions?

We WebAssembly devs couldn’t find a way two years ago so we created a simple class called WebAssemblyDebugValueManager, but now that LLVM gained DBG_VALUE_LIST instruction (which I came to know only recently), I’m wondering if we are reinventing the wheel. When other targets change/move/clone instructions, what do they usually use to update their corresponding debug value instructions?

Unfortunately there is no overall strategy – the debug intrinsics
need to be kept in the same position (or at least the same order), and
their operands kept referring to a {v,}reg containing the correct
value. Optimisations like machine-copy-propagate and machine-sink have
their own custom code to track debug intrinsics and update them
appropriately, which sometimes is a lot of work. I’m not familiar with
WebAssembly, but as it moves instructions around and re-writes
registers, it too will need to have its own custom tracking code.

Doing this for multiple registers in DBG_VALUE_LIST is much harder. If
it’s too difficult, then it’s safe to drop the DBG_VALUE_LIST by
making it’s register operands $noreg. That should turn into “optimised
out” when seen by a debugger.

Can this also be achieved as just deleting the DBG_VALUE_LIST instruction, or is this going to lose even more info?

Shameless plug: there will be a new way of tracking variable locations
[0] that requires less maintenance in optimisations, and I’m now able
to make progress on it again. It’s not completely clear that
WebAssembly would receive all the benefits though, as I understand it
there is no register allocation for WebAssembly.

[0] https://lists.llvm.org/pipermail/llvm-dev/2020-February/139440.html

Thanks for the pointer! I’ll look forward to it.

Hi,

Thanks for the reply! Given that our DebugValueManager does not handle DBG_VALUE_LIST correctly now, is there a way to disable generation of DBG_VALUE_LIST instruction or list version of dbg.value.list intrinsic in IR?

Not at the moment, and as we're aiming to enhance more passes to emit
DBG_VALUE_LISTs it probably wouldn't last long. There's a better fix
(see below),

Doing this for multiple registers in DBG_VALUE_LIST is much harder. If
it's too difficult, then it's safe to drop the DBG_VALUE_LIST by
making it's register operands $noreg. That should turn into "optimised
out" when seen by a debugger.

Can this also be achieved as just deleting the DBG_VALUE_LIST instruction, or is this going to lose even more info?

Unfortunately deleting isn't safe. Instead, it's safe to replace any
DBG_VALUE_LIST you see with "DBG_VALUE $noreg". This indicates that
there _was_ a variable assignment here, but its value could not be
recovered. Taking that approach won't harm variable location coverage
at all: all the DBG_VALUE_LISTs produced would have been "DBG_VALUE
$noreg" in the past.

Hello Jeremy,

Thank you very much for your answers!

Regards,
Heejin