結構いいコードが生成できるようになりました

基本ブロック内の変数畳み込みなどを実装しました。

def array3
  a = [1, 2, 3, 4, 5]
  i = 0
  i = i + 0
  a[i] = 2
  p i
  a[i] + a[1] + a[2]
end

がこんな感じに生成されます。pメソッドのの呼び出しのところでRubyでは変数iですが、0であることが静的に判る(本物のRubyではそうとも限らないのですが・・・)ので、llvmでのrb_pの呼び出しでは定数(RubyのFIXNUMフォーマットなので0が1になる)になっています。

define i32 @array3(i32) {
bb:
	%1 = alloca { i8*, i32, i32, i32, i32 }		; <{ i8*, i32, i32, i32, i32 }*> [#uses=5]
	%2 = getelementptr { i8*, i32, i32, i32, i32 }* %1, i32 0, i32 0		; <i8**> [#uses=0]
	%3 = getelementptr { i8*, i32, i32, i32, i32 }* %1, i32 0, i32 1		; <i32*> [#uses=0]
	%4 = getelementptr { i8*, i32, i32, i32, i32 }* %1, i32 0, i32 2		; <i32*> [#uses=1]
	%5 = getelementptr { i8*, i32, i32, i32, i32 }* %1, i32 0, i32 3		; <i32*> [#uses=2]
	%6 = getelementptr { i8*, i32, i32, i32, i32 }* %1, i32 0, i32 4		; <i32*> [#uses=1]
	store i32 %0, i32* %4
	br label %bb1

bb1:		; preds = %bb
	%7 = alloca i32, i32 5		; <i32*> [#uses=6]
	%8 = getelementptr i32* %7, i32 0		; <i32*> [#uses=1]
	store i32 3, i32* %8
	%9 = getelementptr i32* %7, i32 1		; <i32*> [#uses=1]
	store i32 5, i32* %9
	%10 = getelementptr i32* %7, i32 2		; <i32*> [#uses=1]
	store i32 7, i32* %10
	%11 = getelementptr i32* %7, i32 3		; <i32*> [#uses=1]
	store i32 9, i32* %11
	%12 = getelementptr i32* %7, i32 4		; <i32*> [#uses=1]
	store i32 11, i32* %12
	%13 = call i32 @rb_ary_new4(i32 5, i32* %7)		; <i32> [#uses=3]
	store i32 %13, i32* %6
	store i32 0, i32* %5
	store i32 0, i32* %5
	call void @rb_ary_store(i32 %13, i32 0, i32 5)
	call void @rb_p(i32 1)
	%14 = inttoptr i32 %13 to { { i32, i32 }, i32, i32, i32* }*		; <{ { i32, i32 }, i32, i32, i32* }*> [#uses=1]
	%15 = getelementptr { { i32, i32 }, i32, i32, i32* }* %14, i32 0, i32 3		; <i32**> [#uses=1]
	%16 = load i32** %15		; <i32*> [#uses=2]
	%17 = getelementptr i32* %16, i32 1		; <i32*> [#uses=1]
	%18 = load i32* %17		; <i32> [#uses=1]
	%19 = lshr i32 %18, 1		; <i32> [#uses=1]
	%20 = add i32 2, %19		; <i32> [#uses=1]
	%21 = getelementptr i32* %16, i32 2		; <i32*> [#uses=1]
	%22 = load i32* %21		; <i32> [#uses=1]
	%23 = lshr i32 %22, 1		; <i32> [#uses=1]
	%24 = add i32 %20, %23		; <i32> [#uses=1]
	ret i32 %24
}

define i32 @__stub_array3(i32) {
bb:
	%1 = call i32 @array3(i32 %0)		; <i32> [#uses=1]
	%2 = shl i32 %1, 1		; <i32> [#uses=1]
	%3 = or i32 1, %2		; <i32> [#uses=1]
	ret i32 %3
}