I am learning LLVM and trying to compile a simple function:
int sum(int a, int b) { return a+b; };
on the fly.
So, the code that I have so far:
#include <string> #include <vector> #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Verifier.h" using namespace llvm; static LLVMContext &Context = getGlobalContext(); static std::unique_ptr<Module> MyModule = make_unique<Module>("my compiler", Context); Function *createFunc(IRBuilder<> &Builder, std::string Name) { std::vector<Type*> Integers(2, Builder.getInt32Ty()); auto *funcType = FunctionType::get(Builder.getInt32Ty(), Integers, false); auto *fooFunc = Function::Create(funcType, Function::ExternalLinkage, Name, MyModule.get()); return fooFunc; }; int main(int argc, char* argv[]) { static IRBuilder<> Builder(Context); auto *fooFunc = createFunc(Builder, "sum"); auto *entry = BasicBlock::Create(Context, "entry", fooFunc); Builder.SetInsertPoint(entry); // Fill the function body auto args = fooFunc->arg_begin(); Value *arg1 = &(*args); args = std::next(args); Value *arg2 = &(*args); auto *sum = Builder.CreateAdd(arg1, arg2, "tmp"); Builder.CreateRet(sum); verifyFunction(*fooFunc); // TODO: compile and run it MyModule->dump(); return 0; }
This compiles, and when I run it, I get the expected output:
; ModuleID = 'my compiler' define i32 @sum(i32, i32) { entry: %tmp = add i32 %0, %1 ret i32 %tmp }
as in the textbook.
But now I want to compile this function and run it from C ++. I am looking for the easiest way to do something like this:
auto compiledStuff = ...; auto compiledFn = (int (*)(int, int))compiledStuff; auto result = compiledFn(3, 8);
I dug up the official kaleidoscope tutorial , but the JIT tutorial is really complex and seems to focus on optimization and laziness, while I still can't figure out how easy it is to compile the module and call the function from it.
Any help?