Reputation: 61
I would like to use the clang/llvm APIs to compile a c-function, defined in a string and immediately execute it. Something like:
void main() {
std::string codestr = "int foo(int bar) { return bar * 2; }"
clang::??? *code = clang::???.compile(codestr);
int result = code->call("foo", 5);
}
I am looking for tutorials, but what I found so far does not quite match my goal or does not work, because it refers to an outdated version of LLVM. Currently, I am using LLVM 3.5.
Does anyone have a good tutorial at hand?
Upvotes: 5
Views: 3261
Reputation: 329
I followed this blog post with good results. The clang API has changed, so you may have to make adjustments. With LLVM 3.6.1, I got good results with the following code:
llvm::Module* compile(const char* filename) {
clang::CompilerInstance compiler;
clang::CompilerInvocation* invocation = new clang::CompilerInvocation();
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
auto diagOptions = new clang::DiagnosticOptions();
clang::DiagnosticsEngine Diags(DiagID, diagOptions,
new clang::TextDiagnosticPrinter(llvm::errs(), diagOptions));
std::vector<const char *> arguments = {filename};
clang::CompilerInvocation::CreateFromArgs(*invocation,
&*arguments.begin(), &*arguments.end(),
Diags);
compiler.setInvocation(invocation);
compiler.setDiagnostics(new clang::DiagnosticsEngine(DiagID, diagOptions,
new clang::TextDiagnosticPrinter(llvm::errs(), diagOptions)));
std::unique_ptr<clang::CodeGenAction> action(new clang::EmitLLVMOnlyAction());
compiler.ExecuteAction(*action);
std::unique_ptr<llvm::Module> result = action->takeModule();
llvm::errs() << *result;
return result.release();
}
I was very careless with the pointers, so its very possible there's a memory leak or a double free (although it didn't crash).
I couldn't figure out how to take the source from a memory buffer, so I dumped it in a temporary file using mkstemp
.
I didn't get around to executing the result, but I think you can follow @michael-haidi's response, or check out the LLVM Kaleidoscope tutorial (This is the JIT chapter).
Upvotes: 4
Reputation: 5492
I recommend using MCJIT because the old JIT infrastructure will be removed in a further release. I can't point you to a full tutorial and cannot promise that the API hasn't changed since the blog post but here you'll find a guide how to use MCJIT with the Kaleidoscope example from LLVM and thats it. Examples and tutorials are hard to find for LLVM/Clang. However, I suggest trying it and maybe you can document your journey with a short example.
The Julia project also uses MCJIT for jit compilation of C++ code inside of the Julia lang. Maybe you can peek at the code and find out how the use MCJIT.
Good luck ;)
Upvotes: 1