Skip to content

Instantly share code, notes, and snippets.

@tomas789
Created December 28, 2013 17:57
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tomas789/8162150 to your computer and use it in GitHub Desktop.
Save tomas789/8162150 to your computer and use it in GitHub Desktop.
LLVM JIT Example - Example of very simple JIT using LLVM. It compiles function with prototype `int64_t()` returning value `765`. Build: clang++ `llvm-config --cppflags --ldflags --libs core jit X86` jit.cpp
#include <iostream>
#include <cstdint>
#include <string>
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Analysis/Verifier.h"
using namespace llvm;
int main(int argc, char * argv[]) {
InitializeNativeTarget();
/* LLVM Global Context */
LLVMContext & ctx = getGlobalContext();
/* Module */
Module * module = new Module("MyModule", ctx);
/* IRBuilder */
IRBuilder<> builder(ctx);
/* Create execution engine */
std::string err_str;
ExecutionEngine * engine = EngineBuilder(module).setErrorStr(&err_str).create();
if (!engine) {
std::cerr << "Could not create ExecutionEngine:"
<< err_str << std::endl;
return 1;
}
/* Type of value I want to return - 64-bit integer */
IntegerType * int64_ty = Type::getInt64Ty(ctx);
/* Actual value to return */
int64_t value = 765;
/* LLVM Value */
Value * v = ConstantInt::get(int64_ty, value);
/* Create prototype of result function - int64_t() */
std::vector<Type *> arguments;
FunctionType * proto = FunctionType::get(int64_ty, arguments, false);
/* Create function body */
Function * fce = Function::Create(proto, Function::ExternalLinkage, "MyFunction", module);
BasicBlock * bb = BasicBlock::Create(ctx, "entry", fce);
/* Point builder to add instructions to function body */
builder.SetInsertPoint(bb);
/* Return value */
builder.CreateRet(v);
/* Function pass manager */
FunctionPassManager pass_manager(module);
/* Add data layout */
pass_manager.add(new DataLayout(*engine->getDataLayout()));
pass_manager.doInitialization();
/* Do optimizations */
pass_manager.run(*fce);
/* JIT it */
void * fce_ptr = engine->getPointerToFunction(fce);
int64_t (*fce_typed_ptr)() = (int64_t(*)())fce_ptr;
/* Excute JITed function */
std::cout << "Result: " << (*fce_typed_ptr)()
<< std::endl << std::endl;
/* Dump LLVM IR */
std::cout << "LLVM IR dump: " << std::endl;
module->dump();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment