tags:

views:

743

answers:

3

I am writing a LLVM code generator for the language Timber, the current compiler emits C-code. My problem is that I need to call C functions from the generated LLVM files, for example the compiler has a real-time garbage collector and i need to call functions to notify when new objects are allocated on the heap. I have no idea on how to link these functions with my generated LLVM files.

The code generation is made by generate .ll-files and then manually compile these.

I'm trying to call an external function from LLVM but i have no luck. In the examples I've >found only C standard functions like "puts" and "printf" are called, but I want to call a >homemade function. I'm stuck.

+3  A: 

I'm assuming you're writing an LLVM transformation, and you want to add calls to external functions into transformed code. If this is not the case, edit your question and include more information.

Before you can call an external function from LLVM code, you need to insert a declaration for it. For example:

virtual bool runOnModule(Module &m) {
    Constant *log_func = m.getOrInsertFunction("log_func",
                                               Type::VoidTy,
                                               PointerType::getUnqual(Type::Int8Ty),
                                               Type::Int32Ty,
                                               Type::Int32Ty,
                                               NULL);
    ...
}

The code above declares a function log_func which returns void and takes three arguments: a byte pointer (string), and two 32-bit integers. getOrInsertFunction is a method of Module.

To actually call the function, you have to insert a CallInst. There are several static Create methods for this.

Jay Conrod
This is Exactly what I was just trying to figure out to do with llvm, thanks!
Dan
+2  A: 

Compile your LLVM assembly files normally with llvm-as:

llvm-as *.ll

Compile the bitcode files to .s assembly language files:

llc *.bc

GCC them in with the runtime library:

gcc *.s runtime.c -o executable

Substitute in real makefiles, shared libraries, etc. if necessary. You get the idea.

Jonathan Tang
+2  A: 

I'm interpreting your question as being "how do I implement a runtime library in C or C++ for my language that gets compiled to LLVM?"

One approach is, as detailed by Jonathan Tang, to transform the output of your compiler from LLVM IR to bitcode to assembly, and have vanilla gcc link the assembly against the runtime source (or object files).

An alternative, possibly more flexible approach is to use llvm-gcc to compile the runtime itself into LLVM bitcode, and then use llvm-ld to link the bitcode from your compiler with the bitcode of your runtime. This bitcode can then be re-optimized with opt, converted back to IR with llvm-dis, interpreted directly with lli (this will, afaik, only work if LLVM was built against libffi), or compiled to assembly with llc (and then to a native binary with vanilla gcc).

Ben Karel