Unsafeの続き

Unsafeの開発は結構順調です。定数伝播処理が上手に効いて、一見配列やオブジェクトを作るような効率の悪そうなコードが、構造体へのアクセス命令だけで済んでいます。

def unsafe
  type = LLVM::struct([RubyHelpers::VALUE, RubyHelpers::VALUE])
  a = [:a]
  foo = YARV2LLVM::LLVMLIB::unsafe(a, type)
  foo[1]
  a
end

は、次のようなLLVMビットコードに変換されます。

; ModuleID = 'yarv2llvm'
	type { i8*, i32, i32, i32, %1*, i32, i32 }		; type %0
	type { i32, i32 }		; type %1
	type { i8*, i32, i32, i32 }		; type %2
internal constant [7 x i8] c"unsafe\00"		; <[7 x i8]*>:0 [#uses=1]

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

bb1:		; preds = %bb
	store i32 271925800, i32* %8
	store i32 271924420, i32* %7
	store %1* inttoptr (i32 271924420 to %1*), %1** %6
	%9 = load i32* getelementptr (%1* inttoptr (i32 271924420 to %1*), i32 0, i32 1)		; <i32> [#uses=0]
	ret i32 271924420
}