I'm trying to replace inttoptr
uses that happen when ccall
s are generated. I've gotten as far as drilling down to the operand with inttoptr
, but I can't figure out the next step.
using LLVM
ctx = Context()
mod = parse(LLVM.Module, """
define double @fun() {
top:
%0 = call double inttoptr (i32 -137186077 to double ()*)()
ret double %0
}
""", ctx)
inst = first(instructions(first(blocks(functions(mod)["fun"]))))
ops = operands(inst)
op = first(ops)
There are not many methods that can operate on the operand, and I don't see any way to check that it is an inttoptr
.
julia> inst = first(instructions(first(blocks(functions(mod)["fun"]))))
%0 = call double inttoptr (i32 -137186077 to double ()*)()
julia> ops = operands(inst)
LLVM.UserOperandSet( %0 = call double inttoptr (i32 -137186077 to double ()*)())
julia> op = first(ops)
double ()* inttoptr (i32 -137186077 to double ()*)
julia> filter!(s->!occursin("builder", s), string.(methodswith(typeof(op),supertypes=true)))
14-element Array{String,1}:
"condition!(br::Instruction, cond::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/instructions.jl:153"
"context(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:54"
"initializer!(gv::GlobalVariable, val::LLVM.Constant) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value/constant.jl:223"
"isconstant(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:50"
"isnull(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value/constant.jl:7"
"isundef(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:52"
"llvmtype(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:36"
"name(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:38"
"name!(val::Value, name::String) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:39"
"operands(user::LLVM.User) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value/user.jl:13"
"replace_uses!(old::Value, new::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:46"
"show(io::IO, val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:42"
"uses(val::Value) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value.jl:87"
"setindex!(iter::LLVM.UserOperandSet, val::Value, i) in LLVM at /home/tshort/.julia/packages/LLVM/ViliQ/src/core/value/user.jl:20"
I can get the address of the pointer with, but I can't tell how to check whether it's an inttoptr
.
julia> first(operands(op))
i32 -137186077
There is LLVM.IntToPtrInst
, but that is an instruction, and what I'm trying to detect is part of an operand.
Tim pointed me to the following code that used
string
to check:https://github.com/JuliaGPU/CUDAnative.jl/blob/84126dcb8ba6cbf250ee289a1aac3ef67ba4647a/src/compiler/validation.jl#L254