Crystal LLVM IR API
Thu, Apr 28, 2016
Using crystals llvm bindings to create an LLVM IR for the simple addition example.
require "llvm"
LLVM.init_x86
LLVM::Module.new("main").tap do | main_module | # ; ModuleID = 'main'
main_module.functions.add( # define i32 @main() {
"main",
Array.new(0, LLVM::Int32),
LLVM::Int32
).basic_blocks.append "entry" do |builder| # entry:
a = builder.alloca(LLVM::Int32,"a") # %a = alloca i32
b = builder.alloca(LLVM::Int32,"b") # %b = alloca i32
builder.store(LLVM.int(LLVM::Int32, 40), a) # store i32 40, i32* %a
builder.store(LLVM.int(LLVM::Int32, 6), b) # store i32 6, i32* %b
bval = builder.load(a, "val_a") # %val_a = load i32* %a
aval = builder.load(b, "val_b") # %val_b = load i32* %b
result = builder.add(aval, bval, "ab_val") # %ab_val = add i32 %val_b, %val_a
builder.ret result # ret i32 %ab_val
end # }
end.tap(&.dump).tap(&.verify).tap do | main_module |
# execute in llvm
engine = LLVM::JITCompiler.new( main_module)
result = engine.run_function(
main_module.functions["main"],
[] of LLVM::GenericValue
)
pp result.to_i
end.tap do | main_module |
# generate bit code
LibLLVM.write_bitcode_to_file(
main_module, "./out.bc"
)
`llc-3.6 -filetype=obj out.bc`
`gcc -o out out.o`
puts "wrote program to out\n\n"
puts "run with: './out'\n\n"
puts "doesn't have a print command\n\n"
puts "see result with: 'echo $?'\n\n"
end