yarv2llvmの進捗

 結局、正月休みをyarv2llvmの開発に費やしてしまいました。結構進みました。

  • ruby yarv2llvm.rb Rubyプログラム の形で起動する形式で、bm_so_nbody.rbが大体動くようになりました。大体なのは、SOLAR_MASS = 4 * Math::PI**2 の行が型エラーになるので、4 -> 4.0にするのと、**がまだ実現できていないので、Math::PI * Math::PIに変更しました。
  • ruby yar2llvm.rb 形式でオプションを渡せるようになりました。
Usage: yarv2llvm [options]
    -O, --[no-]optimize              オプティマイザを起動する(デフォルトで起動)
        --[no-]disasm                生成したllvmコードをディスアセンブルして出力する
        --[no-]dump-yarv             YARVを出力する
        --write-bc[=File]            生成したllvmコード(bitコード)をファイルに出力する
        --[no-]func-signature        メソッドとローカル変数の型推論の結果を表示する
    -r FILE                          FILEに示すRubyプログラムをコンパイルに先立って実行する
  • ある程度ちゃんとしたプロファイラがサポートされます。プロファイラの起動は-rオプションを使い、-r y2llib/profile.rbで起動できます。yarv2llvmのライブラリを格納するのにy2llibディレクトリを追加しました。今のところprofile.rbだけしかないですが、いろいろ追加したいと思います。

サンプルセッション

ruby19 yarv2llvm.rb -r y2llib/profile.rb ../fib.rb
89
       766     1:  require 'yarv2llvm'
               2:  module YARV2LLVM
               3:    PROFILER_STATICS = [0.0]
               4:  end
               5:  
               6:  END {
               7:    src_content = {}
               8:    YARV2LLVM::TRACE_INFO.each do |n|
               9:      if /^(.*):(.*)/ =~ n[1][3]
              10:        fn = $1
              11:        ln = $2
              12:        src_content[fn] = File.readlines(fn)
              13:      end
              14:    end
              15:    
              16:    res = Hash.new(0)
              17:    YARV2LLVM::TRACE_INFO.each_with_index do |n, i|
              18:      res[n[1][3]] += YARV2LLVM::PROFILER_STATICS[i]
              19:    end
              20:    
              21:    src_content.each do |fn, cont|
              22:      cont.each_with_index do |srcln, ln|
              23:        re = res[fn + ":" + (ln + 1).to_s].to_i
              24:        if re != 0 then
              25:          printf("%10d %5d:  %s", re, ln + 1, srcln)
              26:        else
              27:          printf("           %5d:  %s", ln + 1, srcln)
              28:        end
              29:      end
              30:    end
              31:  }
              32:  
              33:  <<-EOS
              34:  module YARV2LLVM
              35:    def trace_func(event, no)
              36:      if event == 1 or event == 8 then # Line or funcdef
              37:        if $fst == 1 then
              38:          $fst = 0
              39:          $prev_no = 0
              40:          get_interval_cycle
              41:        end
              42:        interval = get_interval_cycle.to_f
              43:        PROFILER_STATICS[$prev_no] += interval
              44:        $prev_no = no
              45:  
              46:        # Profile process dont count
              47:        get_interval_cycle
              48:        nil
              49:      end
              50:    end
              51:  
              52:    $fst = 1
              53:    i = 0
              54:    TRACE_INFO.each do |n|
              55:      PROFILER_STATICS[i] = 0.0
              56:      i = i + 1
              57:    end
              58:  end
              59:  
              60:  EOS
    216952     1:  def fib(n)
    217593     2:   if n < 2 then
    129407     3:     1
               4:   else
    103550     5:     fib(n - 1) + fib(n - 2)
               6:   end
               7:  end
               8:  
               9:  p fib(10)