LLVM-IRはIRでない、LLVMはVMでない
最近LLVM IRが一般的コンパイラIRに期待されている性質を満たしていないことに対する批判が高まっているので(主にNative Client方面で)、それらの批判に答えたスレッドが大盛り上がりになっている。
実際、通常の人間はC++コンパイラなんて書きたくないので、clangを通してLLVM-IRに変換することで、LLVM IRの世界だけでコンパイラを作れると期待しがちに思える。
というか、実際にそういうプロジェクトは多く :
- EmscriptenはLLVM-IRからJavaScriptに変換している。
- Portable Native ClientはLLVM-IRを共通バイトコードとして用いて、ARMとx86で同じバイナリを使えるNative Clientをつくろうとしている
- 今回のEuroミーティングであった"More Target Independent LLVM Bitcode"のような発表 - http://llvm.org/devmtg/2011-09-16/EuroLLVM2011-MoreTargetIndependentLLVMBitcode.pdf
Emscriptenはうまく行っているように見えるが、アレは偶然に過ぎないことに注意する。実際、ARM clang→C言語バックエンドでC言語に変換→gccでx86向けにコンパイル のようなことをしても、意外と(関数単位なら)動いてしまったりする。
これらを確実に動かすようにするには、Chris Lattnerが指摘している( http://permalink.gmane.org/gmane.comp.compilers.llvm.devel/43780 )ように、Cの言語仕様に何らかの制限を加える必要がある。(EFIはEBCと呼ばれるバイトコードを規定していて、IntelはEBC向けのCコンパイラやABIを提供している)
この手の問題はけっこう難しく、厳密にやろうとすればC言語ASTを使うしかない(そのC言語ASTも、ターゲットアーキテクチャを規定しないと普通の方法では作れない - 例えばターゲット毎にpredefineが異なるため)。逆に適当でよければEmscriptenのように適当にやってもうまくいくことは多いし、NestedVM( http://nestedvm.ibex.org/ )のようにMIPSのような現実のISAを中間言語として取り扱ってしまう方法もある。
もう一つ、LLVMがVMでないというのも中々のポイントになってきているように思える。LLVMをVMやJITCとして使うプロジェクトは(clangのようなコンパイラの勢いに比べると)低調に見える。LLVMのJITは現状低レイテンシ向けの考察を欠いているし、互換性も低いという問題もある。PyPyのようにLLVM backend自体をやめてしまうプロジェクトもある。