Fixing Llvm_executionengine OCaml bindings and broken LLVM Kaleidoscope OCaml JIT tutorial

The OCaml bindings for the Llvm_executionengine have been broken since LLVM 3.5.

See: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20141027/242152.html

I would be very interested in bringing back support for this so one could use LLVM to execute LLVM IR code generated by OCaml. (And I don’t want to downgrade to 3.5, I want to use LLVM 6 or 7).

Has there been any progress on this since 2014? Are there some good technical reasons making it very difficult, or is it just jack of interest/time that’s the main reason why it hasn’t happened yet?

I’m looking for someone who would be interested in getting paid to work on the open source MIT development necessary to make this happen. If you are interested, please contact me by replying here or by email, joel at compiler dot org.

When this work is done, I would also be willing to pay for someone to update the broken LLVM OCaml JIT tutorial:
https://llvm.org/docs/tutorial/OCamlLangImpl4.html

I’ve used Llvm_executionengine with ocaml-ctypes and LLVM7. It seemed to work as expected for my simple use-case. What issues are you having?

The commit you link precisely fixes Llvm_executionengine (by using ctypes). If it doesn’t work, you should raise issues.

As for the tutorial … I started reworking it, but never finished. The implementation is available in https://github.com/Drup/llvm/commit/3c43000f4e86af5b9b368f50721604957d403750 , but there is no associated text.

1 Like

The commit fixed the parts that could easily be fixed, but it looks to me like the functionality to actually run functions was removed, it says “runFunction is no longer available”.

The commit diff removes e.g. llvm_ee_run_function:

-/* llvalue -> GenericValue.t array -> ExecutionEngine.t -> GenericValue.t */
-CAMLprim value llvm_ee_run_function(LLVMValueRef F, value Args,
-                                    LLVMExecutionEngineRef EE) {

I cannot find any functions in bindings/ocaml/* with names that indicate they would actually run/execute code, there is PassManager.run_module and PassManager.run_function, but doesn’t “run” in that context mean running compiler passes, and not actually executing the machine code?

The code below is using ExecutionEngine.run_function, which to me it looks like doesn’t exist in the current bindings/ocaml/*

(* JIT the function, returning a function pointer. *)
        let result =
          ExecutionEngine.run_function anonym_fun [||]
            execution_engine

Ignoring the question of the broken execution engine, it is certainly the case that the LLVM tutorial in OCaml is old and obsolete. It shouldn’t be too hard to fix, though.

I think we’re now meant to use Llvm_executionengine.get_function_address, the doc indicates it compiles the module and returns a function pointer, which you can then neatly unpackage using Ctypes.

Thanks, that was exactly what I was looking for.

1 Like