JIT用の道具を揃える

諸般の事情で、FFIに追い出しているネイティブコードをScheme側で閉じて生成する必要が生じた(主にいちいちコンパイルするのが面倒な環境が有るため)。というわけで、専用のILをC言語なりGLSLなりに変換して実行する処理系が必要になったので検討している。

中間言語としてC言語を使うJIT

意外と有りそうだけどなかなか採用されていない。コレ用のCコンパイラとして著名なのはqemuの人によるTiny C Compiler ( http://bellard.org/tcc/ )で、これはCソースを事実上1対1対応するアセンブラで出力する(tccは1-passコンパイラなので、昔のTurboPascalのように殆ど最適化を提供しない cf. http://www.pcengines.ch/tp3.htm - Turbo Pascal 3.0 Compiler / Code Generation Internals)。
tccはCMakeで一発でビルドできるので、プロジェクトへの組み込みは容易。
tccの最適化がイマイチなのはあまり問題にならない可能性が高い。最適化が必要ならScheme側で行える(どうせtccがサポートしていない環境ではfallbackとしてScheme上のインタプリタを使うので、最適化はどうしてもScheme側にも必要になる)。
逆に、より"重い"backendを期待して、最適化にあまりコストを掛けないアプローチも考えられる。最近はgccJITバックエンド化( http://gcc.gnu.org/ml/gcc-patches/2013-10/msg00228.html - これはまだfull-setのCを入力出来ない )やLLVM/Clangが有る。
C言語以外の"readable" IRを検討するのは意味が有るかもしれない。asm.jsやLLVM IRは実行環境にまだ難が有るが、検討するのは良さそう。GCCのGIMPLE Frontend( http://gcc.gnu.org/viewcvs/gcc/branches/gimple-front-end/ )は最近動きがないが、GIMPLE中間表現のテキストを受けるフロントエンドで、JIT化できるなら魅力的かも。

ILのデザイン

ILのデザインはなかなか微妙で、まだ着地していない。
型付ILで、Schemeオブジェクトは見せない。唯一の例外は、typed vectorsとbignumで、これらはアクセス用のルーチンをpFFI経由でエクスポートする。JITされた関数はpFFIで呼ぶ必要があるため、必然的にFFI safeな型への変換が必要になる。このJITは基本的にOpenGLとかネットワークスタックのような、pFFI経由でアクセスする関数にデータを供給するコードを生成するために使うので、S式を直接取り扱える必要は無い。S式のトラバースはbytecode VMで十分に早い。
コードはGC safeでないスレッドからも実行できる。 = Schemeオブジェクトを新規に確保することは基本的には出来ない。例えば、リアルタイム性の必要な処理を別スレッドに逃し、GC pauseの影響を受けないようにする等の用途がある。
pFFI関数を直接呼び出すことが出来る。pFFIの仕組みをScheme側と共有する。関数アドレスの解決等はScheme側で世話する。この仕組は、JITされたコードからScheme側をcallbackするのにも使われる。(Scheme側をcallbackするには、当然VMスレッドから直接実行される必要がある)
モジュール化する。GLSLのジェネレータ等、他のC-like language生成ライブラリと、基本語彙を共有する。SIMD操作等を通常のスカラ演算にlowerしてエミュレーション実行できるように配慮する。
structured。いわゆる、labelとgotoによるflat構造ではなく、if-then-elseやswitch-caseのような制御構造、forのようなループ構造を持たせる。これはIL上の最適化を制約するが、人間に書きやすいことも重要な要素なので。。
パックされた構造体の処理/bitfield。構造体を型として宣言でき、かつ、bitfieldとして取り扱えること。ただし、構造体の要素は基本型(8/16/32/64 bits)に限る。

missing part: 短いSIMDのためのコード生成

短いSIMDのためのコードをポータブルに生成する良い方法がない。
いわゆるSoA(Structure of Array - 配列の構造体)なデータ構造でまとめたデータを処理するためには、Oil runtime compilerのような専用のコード生成器が使える可能性があるが、短い、packされた整数やfloatを扱うコードのための汎用的なコード生成ライブラリはなかなか無い。
もちろんLLVM IR等は、まさにそれ用の機能を提供するが、デカい。