Suppose I have a pointer to some Value* val in LLVM. I want to get a pointer to Instruction that assigned value to the variable that val points to. How can I do it? This is an example of code
%add = add nsw i32 %aa, %bb
%div = sdiv i32 %add, %cc
I have a pointer to variable add
and I want to get a pointer to the Instruction that assigned to variable add, which is pointer to %add = add nsw i32 %aa, %bb
instruction
So far the only thing I found was a pointer to Basicblock that the variable belongs to. This is how I did it
Instruction * tmpI = dyn_cast<Instruction>(val);
BasicBlock * b = tmpI->getParent();
The correct answer was provided in the comments by jmmartinez:
The LLVM-IR is a Static-Single-Assignment Intermediate Representation. The pointer to the instruction IS the pointer to the assignment. The add instruction and the assignment to the add register have a one-to-one matching since registers can only be assigned once, and instructions can only assign to a single register.
[...] In your code example. if the variable
val
points to the register%add
. It happens thatval
points to anllvm::Instruction
(which inherits fromllvm::Value
). And this instruction is the addition you're looking for.
To add a bit more detail, the LLVM Value
type is a base class of the LLVM Instruction
type. For IR values like %add
in the example, the IR allocates a specific Instruction
subtype, BinaryOperator
in the case of an add
instruction. So the pointer to a Value
for %add
is actually a pointer to the same object as the instruction, just using its base class.
LLVM also has a special system for casting these pointers between types in the IR type hierarchy: https://llvm.org/docs/ProgrammersManual.html#the-isa-cast-and-dyn-cast-templates
Here are some example functions that take a specific llvm::Value
and return the llvm::Instruction
that produces that value:
#include <llvm/IR/Value.h>
#include <llvm/IR/Instruction.h>
using llvm::Value;
using llvm::Instruction;
using llvm::cast;
using llvm::dyn_cast;
using llvm::dyn_cast_or_null;
using llvm::isa;
// Either convert a `Value` to an `Instruction`
// or return null.
auto tryGetInstr(Value* value) -> Instruction* {
return dyn_cast<Instruction>(value);
}
// Just test whether a value was computed with an
// `Instruction` without converting it. Don't use
// this if you'll just end up converting it, use
// the above that combines the two.
auto isInstr(Value* value) -> Instruction* {
return isa<Instruction>(value);
}
// When you already know the value *must* be computed
// by an instruction, you can assert this and convert
// it in a way that will never produce a null.
auto getInstr(Value* value) -> Instruction* {
return cast<Instruction>(value);
}
// If `value` is non-null, try to convert it to an
// `Instruction`. Returns null if `value` is null
// or it isn't referencing an `Instruction`.
auto tryGetInstrIfNonNull(Value* value) -> Instruction* {
return dyn_cast_or_null<Instruction>(value);
}