Pyston試してみた
Pystonに関しては以下のニュースを参照。
http://sourceforge.jp/magazine/14/04/08/153000
ビルド方法がしっかりとドキュメントに記載されているので、その通りにやれば問題なかった。ちなみにLinux Mint15 x64で動かしている。
とりあえず"Hello World"やな、ってことで下記を実行する。
print "Hello World"
出力結果が下記です。
$ ./pyston ~/main.py 715us to load stdlib 1.8ms for initCodegen 1.8ms for jit startup 25us parsing Parsed code; ast: print "Hello World" ============== JIT'ing module with signature () -> void at effort level 0 CFG: 1 blocks Block 0 'entry'; Predecessors: Successors: print "Hello World" return processing types for block 0 processing opt block 0 generated IR: define void @module_e0_0() { opt_block0: %0 = call i8* (...)* @_IO_printf(i8* inttoptr (i64 28776752 to i8*), i8* inttoptr (i64 28776592 to i8*)), !dbg !8 %1 = call i8* (...)* @_IO_printf(i8* inttoptr (i64 28776784 to i8*)), !dbg !8 ret void, !dbg !8 } 282us in compileFunction Compiling... Compiled function to (nil) 301us for _doCompile() 320us for compileModule() compiled module.main to machine code; running: 5us to interpret Hello World finished running 377us to run In teardownRuntime 23us joinRuntime Stats: OSR exits: 0 interpreted_runs: 1 num_compiles: 1 num_compiles_0_interpreted: 1 num_hidden_classes: 153 reopts: 0 us_compiling: 301 us_compiling_0_interpreted: 301 us_compiling_irgen: 282 us_interpreting: 6 us_parsing: 25 158us finishing up
おー、ちゃんとIRはいて実行してくれてる!
まだ開発段階でサポートしてない構文もあるみたいだが、ループくらいできるだろうと思って、一億回のループ回してみたら処理が返ってこなくなった。。。
100回だと返ってきたので、その結果も貼り付けておく。
a = 0 for i in range(100): a+=1
458us to load stdlib 1.3ms for initCodegen 1.3ms for jit startup 5.0ms parsing Parsed code; ast: a = 0 <for loop> ============== JIT'ing module with signature () -> void at effort level 0 CFG: 9 blocks Block 0 'entry'; Predecessors: Successors: 1 a = 0 !0x2ec69a0 = range(100) #iter_0x2ec6870 = !0x2ec69a0:__iter__() goto 1 Block 1; Predecessors: 0 Successors: 2 3 if #iter_0x2ec6870:__hasnext__() goto 2 else goto 3 Block 2; Predecessors: 1 Successors: 4 goto 4 Block 3; Predecessors: 1 Successors: 7 goto 7 Block 4; Predecessors: 2 5 Successors: 5 6 i = #iter_0x2ec6870:next() a+=1 if #iter_0x2ec6870:__hasnext__() goto 5 else goto 6 Block 5; Predecessors: 4 Successors: 4 goto 4 Block 6; Predecessors: 4 Successors: 7 goto 7 Block 7; Predecessors: 3 6 Successors: 8 goto 8 Block 8; Predecessors: 7 Successors: return processing types for block 0 processing types for block 1 processing types for block 2 processing types for block 3 processing types for block 4 processing types for block 7 processing types for block 5 processing types for block 6 processing types for block 8 processing types for block 4 processing types for block 7 processing types for block 8 processing opt block 0 processing opt block 1 processing opt block 2 processing opt block 3 processing opt block 4 processing opt block 7 processing opt block 5 processing opt block 6 processing opt block 8 generated IR: define void @module_e0_0() { opt_block0: %0 = call %"class.pyston::Box"* @boxInt(i64 0), !dbg !8 call void @setattr(%"class.pyston::Box"* inttoptr (i64 79188515504 to %"class.pyston::Box"*), i8* inttoptr (i64 49066800 to i8*), %"class.pyston::Box"* %0), !dbg !8 %1 = call %"class.pyston::Box"* @getGlobal(%"struct.pyston::BoxedModule"* inttoptr (i64 79188515504 to %"struct.pyston::BoxedModule"*), %"class.std::basic_string"* inttoptr (i64 49048152 to %"class.std::basic_string"*), i1 true), !dbg !9 %2 = call %"class.pyston::Box"* @boxInt(i64 100), !dbg !9 %3 = call %"class.pyston::Box"* @runtimeCall(%"class.pyston::Box"* %1, i64 1, %"class.pyston::Box"* %2), !dbg !9 %4 = call %"class.pyston::Box"* @callattr(%"class.pyston::Box"* %3, %"class.std::basic_string"* inttoptr (i64 49048384 to %"class.std::basic_string"*), i1 true, i64 0), !dbg !10 br label %opt_block1, !dbg !10 opt_block1: ; preds = %opt_block0 %5 = call %"class.pyston::Box"* @callattr(%"class.pyston::Box"* %4, %"class.std::basic_string"* inttoptr (i64 49048896 to %"class.std::basic_string"*), i1 true, i64 0), !dbg !10 %6 = call i1 @nonzero(%"class.pyston::Box"* %5), !dbg !10 br i1 %6, label %opt_block2, label %opt_block3, !dbg !10 opt_block2: ; preds = %opt_block1 br label %opt_block4 opt_block3: ; preds = %opt_block1 br label %opt_block7 opt_block4: ; preds = %opt_block5, %opt_block2 %"#iter_0x2ec6870" = phi %"class.pyston::Box"* [ %4, %opt_block2 ], [ %"#iter_0x2ec6870", %opt_block5 ] %7 = call %"class.pyston::Box"* @callattr(%"class.pyston::Box"* %"#iter_0x2ec6870", %"class.std::basic_string"* inttoptr (i64 49049088 to %"class.std::basic_string"*), i1 true, i64 0), !dbg !10 call void @setattr(%"class.pyston::Box"* inttoptr (i64 79188515504 to %"class.pyston::Box"*), i8* inttoptr (i64 49088640 to i8*), %"class.pyston::Box"* %7), !dbg !10 %8 = call %"class.pyston::Box"* @getGlobal(%"struct.pyston::BoxedModule"* inttoptr (i64 79188515504 to %"struct.pyston::BoxedModule"*), %"class.std::basic_string"* inttoptr (i64 49047848 to %"class.std::basic_string"*), i1 true), !dbg !11 %9 = call %"class.pyston::Box"* @boxInt(i64 1), !dbg !11 %10 = call %"class.pyston::Box"* @augassign(%"class.pyston::Box"* %8, %"class.pyston::Box"* %9, i32 69), !dbg !11 call void @setattr(%"class.pyston::Box"* inttoptr (i64 79188515504 to %"class.pyston::Box"*), i8* inttoptr (i64 49066800 to i8*), %"class.pyston::Box"* %10), !dbg !11 %11 = call %"class.pyston::Box"* @callattr(%"class.pyston::Box"* %"#iter_0x2ec6870", %"class.std::basic_string"* inttoptr (i64 49048896 to %"class.std::basic_string"*), i1 true, i64 0), !dbg !10 %12 = call i1 @nonzero(%"class.pyston::Box"* %11), !dbg !10 br i1 %12, label %opt_block5, label %opt_block6, !dbg !10 opt_block5: ; preds = %opt_block4 %13 = load i64* @edgecount %14 = add i64 %13, 1 store i64 %14, i64* @edgecount %15 = icmp sgt i64 %14, 100 br i1 %15, label %onramp, label %opt_block4, !prof !12 opt_block6: ; preds = %opt_block4 br label %opt_block7 opt_block7: ; preds = %opt_block6, %opt_block3 br label %opt_block8 opt_block8: ; preds = %opt_block7 ret void onramp: ; preds = %opt_block5 %16 = call i8* @"pyston::compilePartialFunc(pyston::OSRExit*)"(i8* inttoptr (i64 49094656 to i8*)) %17 = bitcast i8* %16 to void (%"class.pyston::Box"*)* call void %17(%"class.pyston::Box"* %"#iter_0x2ec6870") ret void } 1.5ms in compileFunction Compiling... Compiled function to (nil) 1.5ms for _doCompile() 1.6ms for compileModule() compiled module.main to machine code; running: 5us to interpret finished running 6.9ms to run In teardownRuntime 52us joinRuntime Stats: OSR exits: 0 getglobal_builtins: 1 interpreted_runs: 1 nopatch_getglobal: 101 num_compiles: 1 num_compiles_0_interpreted: 1 num_hidden_classes: 155 reopts: 0 rewriter_nopatch: 706 slowpath_binop: 100 slowpath_callattr: 202 slowpath_getglobal: 101 slowpath_nonzero: 0 slowpath_resolveclfunc: 303 slowpath_runtimecall: 1 slowpath_setattr: 201 us_compiling: 1536 us_compiling_0_interpreted: 1536 us_compiling_irgen: 1520 us_interpreting: 127 us_parsing: 5020 154us finishing up
実行結果は6.9msec。
まだ「試しに動く」という段階っぽいので、今後の発展が楽しみ!