I am very new to LLVM. I have written a basic compiler using the LLVM bindings for Haskell. The basic compiler works fine. Now I want to enrich this compiler with some natively supported functions in its runtime (written in C) but I am failing to link the compiler with the runtime.
For example I have quite a complex implementation of a data structure in C (in a file runtime.c
) which involves a number of nested structs like this:
struct A {...}
struct B {...} //contains A
struct C {...} //contains B
// a complex function `new` which returns a nested struct
C new(int a, int b){..}
Now I want to expose this function at the surface language. The attempt that I am doing right now is compile the whole runtime.c
using clang -emit-llvm -femit-all-decls -S runtime.c
to emit a runtime.ll
file.
And in the compiler generated LLVM code I hope to make a call to this function new
and emit another llvm bitcode file. Finally I link the 2 .ll
files using something like this: LLVM IR: How to call a function in another .ll file
The problem with this approach is when I originally compile the runtime.c
file the LLVM generated seems to be very platform specific. For example the return type of @new
becomes void
and the structs are handled in a way specific to the platform ABI that I am compiling to.
This tells me that my approach might be incorrect. How do you generally connect the compiler and the runtime then?