flxc can now JIT the most useless program ever!
posted on September 15, 2009 - 02:27 AM PDT by Erick Tryzelaar
I finally got the llvm jit working with felix. Here's the proof. With this input:
type int = "%i32";
typedef array[t,n] = t ^ n;
fun add : int*int -> int = "%add";
fun subscript[t,n] : array[t,n] * int -> t = "%subscript";
proc exit : int = "exit";
var x = 5, 6;
var y = x.[1] + 1;
y = y + 3;
val z = x.[0], y;
exit (z.[0] + z.[1]);
Generates this llvm module and executes each numbered function at a time:
@x = weak_odr global [2 x i32] undef ; <[2 x i32]*> [#uses=2]
@y = weak_odr global i32 undef ; <i32*> [#uses=4]
@z = weak_odr global [2 x i32] undef ; <[2 x i32]*> [#uses=2]
declare void @exit(i32)
define void @0() {
entry:
store i32 5, i32* getelementptr inbounds ([2 x i32]* @x, i32 0, i32 0)
store i32 6, i32* getelementptr inbounds ([2 x i32]* @x, i32 0, i32 1)
ret void
}
define void @1() {
entry:
%0 = load i32* getelementptr inbounds ([2 x i32]* @x, i32 0, i32 1) ; <i32> [#uses=1]
%1 = add i32 %0, 1 ; <i32> [#uses=1]
store i32 %1, i32* @y
ret void
}
define void @2() {
entry:
%y = load i32* @y ; <i32> [#uses=1]
%0 = add i32 %y, 3 ; <i32> [#uses=1]
store i32 %0, i32* @y
ret void
}
define void @3() {
entry:
%0 = load i32* getelementptr inbounds ([2 x i32]* @x, i32 0, i32 0) ; <i32> [#uses=1]
store i32 %0, i32* getelementptr inbounds ([2 x i32]* @z, i32 0, i32 0)
%y = load i32* @y ; <i32> [#uses=1]
store i32 %y, i32* getelementptr inbounds ([2 x i32]* @z, i32 0, i32 1)
ret void
}
define void @4() {
entry:
%0 = load i32* getelementptr inbounds ([2 x i32]* @z, i32 0, i32 0) ; <i32> [#uses=1]
%1 = load i32* getelementptr inbounds ([2 x i32]* @z, i32 0, i32 1) ; <i32> [#uses=1]
%2 = add i32 %1, %0 ; <i32> [#uses=1]
call void @exit(i32 %2)
ret void
}
If everything works out, the program should exit with the returncode 15. You'll need a properly configured and built llvm from svn to get this to work though.