Created
October 31, 2017 15:22
-
-
Save Papierkorb/ca61edbd543c4eb13f2aa1284c9cb4bf to your computer and use it in GitHub Desktop.
LLVM JIT example in Crystal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "llvm" | |
# Initialize LLVM. There's also `LLVM.init_arm` if that's what you use. | |
LLVM.init_x86 | |
# The context of everything we'll do. Main book-keeping structure. | |
ctx = LLVM::Context.new | |
# Code can be separated in different modules. A module can't directly interact | |
# with another module. If you'd do that, you'd have to link them. | |
mod = ctx.new_module("main_mod") # Names are generally for your eyes | |
# Build this prototype: `func sum(a : Int32, b : Int32) : Int32` | |
func = mod.functions.add("sum", [ ctx.int32, ctx.int32 ], ctx.int32) | |
# And now we have to add the logic of our function: | |
func.basic_blocks.append("entrypoint") do |b| | |
l = func.params[0] # Grab first parameter passed to us | |
r = func.params[1] # Second one too | |
# Do `l + r`. We call this variable `lr`. Again, this name is for us, LLVM | |
# doesn't care much about it. Choose something well-readable! | |
lr = b.add(l, r, "lr") | |
# And now the return statement | |
b.ret(lr) | |
end | |
# Dump the module to the screen. | |
mod.dump | |
# What we've all been waiting for: The actual JIT compiler! | |
jit = LLVM::JITCompiler.new(mod) | |
# The JIT will resolve symbols (and compile them) as needed. Just ask it for | |
# the pointer to our function we just created: | |
func_ptr = jit.get_pointer_to_global(func) | |
# And now, turn it into a Proc. For C people, this is like casting to `int(*)(int, int)`. | |
func_proc = Proc(Int32, Int32, Int32).new(func_ptr, Pointer(Void).null) | |
# ^ Arguments ^ Return type ^ Context. We don't have one! | |
# ^ The function pointer | |
# And now just call it like you'd call any other Proc: | |
pp func_proc.call(4, 5) # => 9 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment