Description
(I'm opening this issue because I can't find a pre-existing one)
llvm.dbg.declare
describes the location in memory of a debuginfo variable, whereas llvm.dbg.value
describes the value itself directly. Today we only use the former, which means that in debug mode, all named variables are placed on the stack, even if they're simple scalars (e.g. integers).
Ideally, we'd use llvm.dbg.value
in the same situations where we skip creating a stack slot (e.g. LLVM alloca
), i.e. for scalars, vectors and pairs of scalars.
However, this is much harder than I expected, mostly due to LLVM being too eager to throw away llvm.dbg.value
if computing the value can be avoided (i.e. it's not used by anything else).
I think llvm.dbg.declare
only fares better because at opt-level=0
, the lack of SROA means alloca
s are kept around pretty much completely intact.
FastISel
(used at opt-level=0
) throws away any non-trivial llvm.dbg.value
, but disabling it with -C llvm-args=-fast-isel=0
only helps some simple cases (such as a reference to another stack variable - IMO FastISel
should be improved to handle those, I don't see why it couldn't).
In general, it looks like Instruction Selection ("ISel
") in LLVM ignores llvm.dbg.value
s while building all of the machine instructions for a BB, and only afterwards does it come back to the llvm.dbg.value
s and lower them to DBG_VALUE
, using the value only if it already exists (i.e. something else needs that same value, at runtime), and otherwise it leads to <optimized out>
vars.
Maybe the upcoming GlobalISel
approach handles llvm.dbg.value
better, but I would need to target AArch64
to even try it out, from what I hear (I might still do it out of curiosity).
While investigating this I also came across #8855 (comment) - but setting AlwaysPreserve
to true
only keeps the debuginfo variable around, it doesn't help at all with keeping any value alive (so you end up with <optimized out>
in the debugger, instead of the variable missing).
I haven't seen anything that would make llvm.dbg.value
keep the value alive so it's guaranteed to be available to the debugger, but if there is such a thing, it's probably the way to go, if we want to avoid relying on the stack so much.