最適化

とりあえず
こんなコードをコンパイルして:

fun foo( a, b )
{
	a+b
}

if( 1 ) { foo(1,2) } else { foo(3,4) }


こんなコードを出力して:

; ModuleID = 'test'
@format0 = internal constant [4 x i8] c"%d\0A\00"

declare i32 @printf(i8*, ...)

define internal void @puti(i32 %arg0) {
    %format0_address = getelementptr [4 x i8]* @format0, i32 0, i32 0
    call i32 (i8*, ...)* @printf( i8* %format0_address, i32 %arg0 )
    ret void
}

define i32 @main() {
EntryBlock:
    %cond = icmp ne i32 0, 1
    %ifresult = alloca i32
    br i1 %cond, label %IFTrueBlock, label %IFFalseBlock

IFTrueBlock:
    %ret27 = call i32 @foo( i32 1, i32 2 )
    store i32 %ret27, i32* %ifresult
    br label %IFResultBlock

IFFalseBlock:
    %ret38 = call i32 @foo( i32 3, i32 4 )
    store i32 %ret38, i32* %ifresult
    br label %IFResultBlock

IFResultBlock:
    %ifvalue = load i32* %ifresult
    call void @puti( i32 %ifvalue )
    ret i32 0
}

define internal i32 @foo(i32 %arg_a, i32 %arg_b) {
EntryBlock:
    %reg12 = add i32 %arg_a, %arg_b
    ret i32 %reg12
}


それを最適化してみた(opt -std-compile-opts t.bc -f -o t2.bc; llvm-dis t2.bc -o -)。

; ModuleID = 't2.bc'
@format0 = internal constant [4 x i8] c"%d\0A\00"

declare i32 @printf(i8*, ...)

define i32 @main() {
EntryBlock:
    tail call i32 (i8*, ...)* @printf(略)
    ret i32 0
}

余裕で畳み込んだ。
細かいことを考えるのはよそう。