qemu TCGの利用

というわけで、qemu TCGの利用を試してみた。moshには関数ポインタを呼び出すためのAPIや、実行可能なメモリをmapするためのAPIがまだ無いので、かなり適当な修正をして使っている。
当然この修正はmergeできないので、gitリポジトリ( http://delegate.uec.ac.jp:8081/club/mma/~oku/repos/mosh.git )からjitc-tcgブランチを取得し、cygwin上で、

autoreconf -ifv
./configure --enable-plugin CXXFLAGS=-DGC_THREADS CFLAGS=-DGC_THREADS

としてビルドし、ext/tcg上でwork.scmを実行する。必要なtcg.dllはbuildline.win32.shをMinGW上で実行すると得られる。

okuoku@okupcb ~/repos/mosh/ext/tcg
$ mosh work.scm
GC Warning: Repeated allocation of very large block (appr. size 417792):
        May lead to memory leak and poor performance.
code size : 21
#vu8(1 0 0 0 2 0 0 0) ;; 1 と 2
#vu8(3 0 0 0 2 0 0 0) ;; 3 = (1 + 2)

今のところi386にしか対応していない。
qemuTCGはまだきちんとqemuから分離されていないので、グローバル変数に格納されたコンテキストに依存した箇所が多々ある。生成されるコードがリエントラントでないように思える。(しかし、qemuはスレッド化されたエミュレーションをサポートしているので、何らかの形でこれを実現しているはず)
work.scm ( http://delegate.uec.ac.jp:8081/club/mma/~oku/cgit/cgit.cgi/mosh/tree/ext/tcg/work.scm?h=jitc-tcg )は、paramに格納された即値2つ(1 2)を加算して最初のロケーションに格納するコードを出力する。
FFI対応の過程でJITCを入れようとしているのは、演算処理の高速化というより、一種のシーケンサの出力を想定している。つまり、

等をおこなうために活用しようという魂胆。TCGはfloatをサポートしていないので、信号処理用途には使えない。
これら3つの用途と、信号処理を行うだけに十分なSchemeのサブセットを決めて、それをターゲットにしたコンパイラを書くことで、十分な効率性を持ったコンパイラを作ることが出来ると考えている。つまり、値域の推定や関数の特殊化、インライン化などの最適化は強力であるにもかかわらず、Schemeの言語機能を保持したままでは適用が難しいことに依る。

組み込みJITCとしてのTCG

  • ○ ちょっとした最適化パスを持つ
  • APIは揃っている
  • ○ 十分に小さい
  • × 最適化のために、ちょっと見通しの悪いコード
  • × まだqemuから分離されたわけではない

LLVMは非常に大きいので、たとえばTCCのような組み込みコンパイラの代替くらいに考える方が適切かも知れない。出力されるコードのパフォーマンスはこれからLLVMを組み込んでみて比較することにする。
もっとも、Schemeを使うなら、自前のアセンブラと最適化パスを組み込む方が多分簡単だろう。
ちなみにqemuLGPL/GPLだが、TCGの部分はBSDLで公開されている。