Skip to content

Repository files navigation

llvm-ocaml-tutorial

Introduction

The tutorial is Kaleidoscope on OCaml. It's not intended as a fully translation of LLVM Kaleidoscope tutorial, but a demonstration of basic LLVM APIs in OCaml.

The tutorial is tested with combinations of

  1. opam llvm.16+nnp and OCaml 5.1.0 (should be released soon).
  2. opam llvm.14.0.6 and OCaml 4.14.1.

In opam packages, llvm.16+nnp uses Opaque Pointers and llvm.14.0.6 uses Typed pointers. In official LLVM, Opaque Pointers are enabled by default from LLVM 15 and Typed pointers are not supported from LLVM 17. See LLVM Opaque Pointers for details.

Build

Since the changes in LLVM is breakable but tiny in their APIs until now, for better or for worse, there is some duplicate code in the repo. Combination 1 uses bin/kaleidoscope.ml and lib. Combination 2 uses bin/kaleidoscope.ml_14.ml and lib-14. The rest are shared.

# Install the dependenciesopam install base ctypes-foreign llvm menhir ppx_jane
# Build the shared librarydune build stubs/libbindings.so
# Add the shared library to pathexport LD_LIBRARY_PATH=_build/default/stubs

Run (Hurry)

# with llvm 14.0.6dune exec bin/kaleidoscope_14.exe < example/mandel.kal
# with llvm 16+nnp or beyonddune exec bin/kaleidoscope.exe < example/mandel.kal

Run (Step-wise)

See Makefile.

# with llvm 14.0.6make build-14make link-14make demo-14make run-14
# with llvm 16+nnp or beyondmake buildmake linkmake demomake run

Meta

Currently, the difference between two version of code is tiny.

The result of diff bin/kaleidoscope.ml bin/kaleidoscope_14

7c7< Kaleidoscope_lib.Toplevel.main !dest---> Kaleidoscope_lib_14.Toplevel.main !dest

The result of diff lib lib-14

diff '--color=auto' lib/codegen.ml lib-14/codegen.ml57c57< | Some v -> Llvm.build_load double_type v name builder)---> | Some v -> Llvm.build_load v name builder)96,99c96< let fnty =< Llvm.function_type double_type (Array.of_list [ double_type; double_type ])< in< Llvm.build_call fnty callee [| lhs_val; rhs_val |] "binop" builder)---> Llvm.build_call callee [| lhs_val; rhs_val |] "binop" builder)112,114c109< let arg_typs = Array.map args ~f:(Fn.const double_type) in< let fnty = Llvm.function_type double_type arg_typs in< Llvm.build_call fnty callee args "calltmp" builder---> Llvm.build_call callee args "calltmp" builder211c206< let cur_var = Llvm.build_load double_type alloca var_name builder in---> let cur_var = Llvm.build_load alloca var_name builder in237,238c232< let fnty = Llvm.function_type double_type (Array.of_list [ double_type ]) in< Llvm.build_call fnty callee [| operand |] "unop" builder---> Llvm.build_call callee [| operand |] "unop" builderdiff '--color=auto' lib/dune lib-14/dune2c2< (name kaleidoscope_lib)---> (name kaleidoscope_lib_14)

Thank to @Kakadu's PR.

The project is originally forked from https://github.com/adamrk/llvm-ocaml-tutorial.

Todo

  • Redo testing.
  • Use vanilla library instead of Base.
  • Update the missing part of the official Kaleidoscope tutorial.
  • Rewrite the tutorial in OCaml.

About

The LLVM tutorial using OCaml

Resources

Stars

38 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages