I tried to implement function pointers with a new LLVM::FunctionAddressOfOp
op in order not to mess too much with the coupling between GlobalOp
/AddressOfOp
. Then I noticed that ConstantOp
was already doing what I wanted to implement, so I reverted everything again. Later I regretted this because the verifier of ConstantOp
is not very great (at least not with symbol references). For example, there is no type-checking against the function signature, which easily triggers assertion failures during translation to LLVM IR. Also it is not obvious whether ConstantOp
’s result type should be a function type or a pointer to it (void(int)
vs void(*)(int)
in C++ speech).
I can see several options:
- Implement better builders and verification for
ConstantOp
. - Create a
FunctionAddressOfOp
paired withLLVMFuncOp
.AddressOfOp
would work only withGlobalOp
. - Add
AddressOfOp::getFuncOp()
and something likeAddressOfOp::isFuncOp()
.
#2 might actually be the most user-friendly option, IMHO.
Would we also need a way to declare a FuncOp
in the case there are circular indirect calls? I don’t know at what point the verifier is run, i.e. can it be that the verifier is executed on an operator with a symbol reference whose symbol has not been defined, yet?
I’m asking because translation to LLVM IR has some special handling for cyclic call graphs (llvm-project/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp at main · llvm/llvm-project · GitHub).
Since ConstantOp
does no verification, it can handle these cases already (which is important for me).