If you’re lowering into the LLVM dialect directly your best reference is probably the StandardToLLVM conversion. I don’t know that there’s any generic transformation that does what you’re looking for directly, however.
There’s a thread on here somewhere where we were discussing how to get something like it into the core APIs, but honestly, it feel off my radar. If it looks useful, we could revive that, or you’re welcome to take it.
Thanks, I missed the region signature converter part in the manual. It was a bit challenging to figure out the interaction between the signature converter and the argument materialisation logic though.
I ended up with a signature converter in a FuncOp rewriter pattern that splits the structs into separate arguments per fields, and an argument materialiser that reassembles the struct from the split arguments. This combined with a type rewriter for function pointers, and a CallOp-like rewriter pattern for unpacking the structs before actually calling the functions.
This was all hacked into our LLVM lowering pass, I am sure I could make it better, especially as the pass is now tightly tied to the target architecture. I suppose the long term approach in our case would be to lower to CIL instead.