I’m writing a pass that inserts the llvm.experimental.stackmap intrinsic into the IR, and I’d like to record the locations of all live values whenever I insert the intrinsic (all this entails is adding values as arguments to the intrinsic). Is there any pre-existing analysis pass which can give me the live values at a given instruction in a basic block? Or do I need to write an analysis pass to calculate this information?
I realize that live value analysis is usually performed during register allocation in the backend, but I was wondering if there was anything available in the optimizer.
the statepoint code has a liveness algorithm you may be able to repurpose.
If you want something faster, see https://hal.inria.fr/inria-00558509v1/document
I'm writing a pass that inserts the llvm.experimental.stackmap
intrinsic into the IR, and I'd like to record the locations of *all*
live values whenever I insert the intrinsic (all this entails is
What is your definition of a live value? Some more context on what
you intend to do with stackmaps will be helpful too.
LLVM has a restricted form of a live value analysis that in the
RewriteStatepointsForGC pass, and its intended use is to rewrite LLVM
IR in a way that it can work with a precise compacting garbage
collector; but it looks like you want something more general?
adding values as arguments to the intrinsic). Is there any
pre-existing analysis pass which can give me the live values at a
given instruction in a basic block? Or do I need to write an analysis
pass to calculate this information?
I’m interested in being able to reconstruct stack frames at runtime. In particular, I’d like to be able to unwind frames from a thread’s stack and inspect the live values of each individual activation. I’d like to be able to find all live values (whether they be programmer-defined variables or compiler-generated intermediates) at arbitrary, but statically-known, locations in the the code. Right now, I need the locations of all live values at function call sites.
Note that this should be a solved problem using DWARF debugging information – the only reason I’m investigating this route is because it seems that clang/LLVM produce bad DWARF info .
This sound very interesting! What do you intend to use this mechanism
for, if you don't mind sharing?
The liveness analysis in the statepoint lowering code cannot be
directly used for this, but it should be possible to extract out a
"liveness analysis utility" that is usable both by the statepoint
lowering code and by whatever it is that you're trying to do. I'll be
happy to review changes in this direction -- let me know if you're
interested in taking this on, and we can work out the details.
As an aside, have you thought about how you'd represent and lower this
information ("this information" == the set of values live over a
function call)? LLVM has a notion called operand bundles which may be
useful for you here -- we use it to represent deoptimization state for
specific physical frames, that lets the runtime replace the stack
frames running compiled code with stack frames running interpreted
code (is this similar to what you're trying to do?).
Hi Sanjoy & Daniel,
Thanks for your insights!
I’ve actually got kind of an esoteric use case – we’re exploring how to efficiently transform application state between ABIs at runtime, and thus we need a lot of info from the compiler on how things are laid out. I’m going to follow Daniel’s suggestion and try to implement an analysis pass based on the approaches detailed in . If you think this is useful for LLVM in general, I’d be happy to contribute it to the community. A word of warning – I’ll probably need some hand-holding to get it to an LLVM-acceptable level :).
On representing this information – I was planning on generating meta-data based on the analysis (similar to what happens with “-g”), but I can definitely explore using operand bundles to hold the data.
Rob Lyerly wrote:
On representing this information -- I was planning on generating
meta-data based on the analysis (similar to what happens with "-g"), but
I can definitely explore using operand bundles to hold the data.
"-g" is fine if the extra information is nice to have, but not
required for correctness. If you //need// to have all of the live
values for correctness then you should consider using operand bundles.