Profilerを作っています

Profilerを作っています。Quantifyみたいなのがいいなって考えています(http://bmrc.berkeley.edu/purify/docs/html/installing_and_gettingstarted/4-quantify.html)。Quantifyのすごいのはサンプリングではなく、プログラム中に計測コードを埋め込んでクロック単位で正確な結果を出すことです。
yarv2llvmでは、trace_funcで必要な場所に計測コードを埋め込めるので、後はクロック単位で時間計測することです。無理かなって思ったらLLVMに機能がありました。(http://llvm.org/docs/LangRef.html#int_readcyclecounter) llvm.readcyclecounterを使うと、X86ではRDTSC命令が生成されます。

こんな感じで順調だったのですが、思わぬところでつまずいています。時刻ではなくある区間の時間を計るためには前のllvm.readcyclecounterの結果を(関数間で)覚えておく必要があるのですが、グローバル変数を実現する方法が現状のllvmrubyでは無い様なのです。
もちろん、LLVMにはあるのですが、llvmrubyにはまだ実装されていないようです。現状ではllvmruby本体はほとんど開発が止まっているようなので、すぐに入るのはちょっと考えにくいです。自分で入れてもいいのですが、llvmrubyのサンプルプログラムという目的もあるので、できればオリジナルのllvmrubyで動くようにしておきたいです。現状でも、インスタンス変数なんかには入れられるのですがオーバヘッドが大きすぎるのでちょっと嫌です。そういう感じで困っています。今のところ定数(グローバル定数はなぜかある)に無理やり書き込んで実現しています。オプティマイズを掛けると動かなくなります。
最終的にはllvmrubyを拡張してpullリクエストを出すつもりです。

追記
結局、llvmrubyを改造してpullリクエストを出しました。昨日の苦労がうそみたいにスムーズに動くようにできました。

話は変わって、

Profilerを作っていて面白いことに気づきました。AOTよりJITのほうが速くなりうるという話です。
yarv2llvmはprintメソッドを使うとこんな感じのコードが出ます。

	%17 = call i32 @rb_io_print(i32 1, i32* %4, i32 268616780)		; <i32> [#uses=0]

rb_io_printはRubyのprintメソッドのCでの実装なのですが、3つ目の引数の268616780というのはSTDOUTオブジェクトのアドレスです。AOTだとコンパイル時にはオブジェクトのアドレスは一切わからないのですが、JITではシステムで提供されるオブジェクトのアドレスの多くがわかるわけです。そのため、printメソッドの例みたいにオブジェクトのアドレスを直接書くことができ、メモリアクセスが減られると思います。もちろん、GCでオブジェクトのアドレスが変わると面倒なのですが、CRubyならOKです。
多分私は、CRubyに世代別やコンパクションを導入されないことを世界で一番願っている人間じゃないかなと思います。