Ocaml JIT example

Hi all,

Here’s an example of how to LLVM’s JIT compiler/interpreter from Ocaml.

$ cat jithelloworld.ml
(* jithelloworld.ml *)

open Llvm
open Llvm_executionengine

let execute_function f m =
(* Set up the JIT. *)
let jit = ExecutionEngine.create (ModuleProvider.create m) in
ExecutionEngine.run_static_ctors jit;

(* Execute the function. *)
ignore (ExecutionEngine.run_function f [| |] jit);

(* Tear down the JIT. *)
ExecutionEngine.run_static_dtors jit;
ExecutionEngine.dispose jit

let build_module =
let m = create_module “jithelloworld” in

(* @greeting = global [14 x i8] c"Hello, world!\00" *)
let greeting = define_global “greeting” (const_stringz “Hello, world!”) m in

(* declare i32 @puts(i8* ) *)
let puts = declare_function “puts”
(function_type i32_type [| pointer_type i8_type |]) m in

(* define i32 @main() {
entry: *)
let main = define_function “main” (function_type i32_type [| |]) m in
let at_entry = builder_at_end (entry_block main) in

(* %tmp = getelementptr [14 x i8]* @greeting, i32 0, i32 0 *)
let zero = const_int i32_type 0 in
let str = build_gep greeting [| zero; zero |] “tmp” at_entry in

(* call i32 @puts( i8* %tmp ) *)
ignore (build_call puts [| str |] “” at_entry);

(* ret void *)
ignore (build_ret (const_null i32_type) at_entry);

(main, m)

let _ =
let (f, m) = build_module in
execute_function f m

$ ocamlopt -cc g++ llvm.cmxa llvm_executionengine.cmxa -o jithelloworld jithelloworld.ml
$ ./jithelloworld
Hello, world!

— Gordon