x86toLLVM?

by syoyo

V8 の吐くアセンブラは最適化されていないと書いたが(link)、ここで、第一回 LLVM 勉強会のときにもすこし話題に上がったけれども、x86 命令を LLVM IR に変換するディスアセンブラとかあるとおもしろいかもしれない.

それがあると、たとえば V8 に対して、

JS -> (V8 x86 backend) ->
x86(unoptimized) -> (x86 to LLVM backend) ->
LLVMIR -> (optimize & LLVM x86 backend) ->
x86(optimized)

という、最適化されていない x86 命令があら不思議、最適化された x86 命令に変換されてさらに V8 が高速化されました、ということができる. ただ LLVM はでかいしメモリを食うので、このような変換は組み込みデバイスでやるのは難しくて、デスクトップでの用途に限定となるが.

x86toLLVM があると、V8(JS) をさらに最適化、以外にもいろんな応用があると思う.

valgrind のようなパフォーマンス解析、セキュリティ解析とか,
(valgrind は VEX という x86 to 中間言語変換を行うモジュールを使っている)

ソースコードを修正するのがもはや大変で(でかい C++ プロジェクトとか、コンパイラ依存の機能を使っているとか)、バイナリの方から高速化するほうが楽だったり、プロプライエタリで提供されるプログラムを高速化したりとか,

x86 から LLVM IR を介して他のアーキティクチャ(ppc, arm とか)へ変換するとか.
(プログラム作成者は __X86__ とか __PPC__ とかソース段階でアーキティクチャごとに切り分けする必要がなくなる).

もちろん、入力ソースが x86 バイナリということは、デバッグ情報とか関数の情報とかうまく扱えたり復元できるかという問題があるので、どれくらい実現性があるかは作ってみないとわからない.
すくなくとも、バイナリ -> ソース復元をしてそこからユーザがなにかいじるという用途にはあまりつかえなさそうだ. JIT のようにバイナリ -> バイナリとユーザに見えないような使い方に限定だろう.

AVX 命令セット以前の x86 命令は変態なので、x86toLLVM は作成するならすべての x86 命令をサポートするのは難しい. v8 が吐くアセンブラ群だけに限定が現実的か.
もしくは V8 に限るなら、arm バックエンドがあるので、armToLLVM を作り、そこから x86 命令に変換するのがいいかもしれない.
(あとは V8 に codegen-llvm.cc を書くのもあり. 単に JS -> LLVM をやりたいならこっちのほうがいいかもしれない)

… と, 思いを馳せるだけではよくない気がするので、x86toLLVM をちょっと第二回 LLVM 勉強会での発表ネタとして前向きに考えてみよう.
(実装言語は Python で. 実行速度が気になるなら ShedSkin で変換すればいいし)

LadyVM

ちなみに、どれくらい早くなりそうかの判断として、
JIT つき JVM 実装を LLVM, GNU Classpath, Bohem GC を使ってお手軽に実装してみたというレポートが参考になる.

http://vmkit.llvm.org/ladyvm.html

作った JVM の名称は LadyVM で、その後 CLI もサポートして vmkit というプロジェクトになっている.

パフォーマンス比較を見てみると、単純な数値演算などは既存の JVM 実装より早くなるようだが、それ以外はとんとんから 2 倍くらい遅く、例外やオブジェクトアロケーションなどの JVM 向けの最適化が必要な場合(escape analysis とか object inlining が効果を出すようなプログラム)では LadyVM は 10 倍くらい遅い
(LLVM にはそのような最適化がない/向いてないから).

そんなわけで、x86toLLVM を作ったとしても、数値演算(静的に型が分かる場合)や for ループの内部が不変というような JS プログラムは高速化されるだろうけど, オブジェクト指向をバリバリ使っているような JS プログラムは最適化の恩恵を受けないと思う.

もちろん、LLVM にそのような特定の処理の最適化を行うパスを作れば話はまた変わってくるだろうけれども.
(llvm-dev のポストに, 最近 escape analysis を LLVM に書こうとしているひとがいる)

あ、あと、レポートの意義はパフォーマンスではなくて, 今や、既存のフレームワークを使えばなんとこんなにも簡単に JIT もついた JVM 実装が作れて(記述コード量は 2 万行ほど)、しかも industreal JVMs と同等のパフォーマンスをほぼ達成できるという, 費用対コストのすばらしさにある.
LLVM が出てきてからというもの、resource constrained な環境向けでなければ、実務的で高速なコンパイラ作成というものがどんどんと楽になってきていると思う.

おまけ

x86toLLVM があれば、PRMan の DSO シェーダを変換して lucille のシェーダに取り込み, 既存資産の容易な lucille への移行というのもでできる可能性があるわけ.

打倒 PRMan と PRMan の全面的な lucille での置き換えを狙っている身としては、このような一見回り道に見えるようなことも PRMan を業界から引きずり下ろすために必要な作業なのです 🙂

Advertisements