tail calls, baby!
posted on September 26, 2009 - 05:51 PM PDT by Erick Tryzelaar
Check this out! I just got the standard felix optimizations working.
type int = "%i32";
typedef bool = 2;
fun add : int*int -> int = "%add";
fun sub : int*int -> int = "%sub";
fun eq : int*int -> bool = "%eq";
fun lnot : bool -> bool = "%lnot";
proc exit : int = "exit";
fun foo (x:int) = {
if x == 0 do
return 10;
done;
return foo (x - 1);
}
exit $ foo 2;
Which compiles down to this code:
declare void @exit(i32)
define i32 @foo(i32 %x) {
entry:
%foo.x = alloca i32 ; <i32*> [#uses=4]
store i32 %x, i32* %foo.x
br label %start_21
start_21: ; preds = %_ifdoend_1, %entry
%0 = load i32* %foo.x ; <i32> [#uses=1]
%1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
%2 = icmp eq i1 %1, false ; <i1> [#uses=1]
br i1 %2, label %_ifdoend_1, label %else
_ifdoend_1: ; preds = %start_21
%3 = load i32* %foo.x ; <i32> [#uses=1]
%4 = sub i32 %3, 1 ; <i32> [#uses=1]
store i32 %4, i32* %foo.x
br label %start_21
else: ; preds = %start_21
ret i32 10
}
define void @0() {
entry:
%0 = call i32 @foo(i32 2) ; <i32> [#uses=1]
call void @exit(i32 %0)
ret void
}