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 }