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。

まだ「試しに動く」という段階っぽいので、今後の発展が楽しみ!