2014年11月22日土曜日

LLVM Backend ("Fastcomp")

This is the translation to Japanese at 2014-11-21.
The original document is here:
Home » Building Emscripten from Source
» LLVM Backend (“Fastcomp”)

Translator: Usagi Ito usagi@WonderRabbitProject.net (JA, EN)

LLVM Backend (“Fastcomp”)

この記事では Fastcomp と Emscripten の LLVM + Clang 実装について記す。ここでは如何にしてこれらの新しいツールを、 原初の翻訳器コア と置き換えるか、或いは必要があれば Fastcomp を無効化するかについての知識を得られるだろう。もし、 Fastcomp について問題が生じたならば、記事の末尾の FAQ も参照されたい。

Fastcomp の概要

Fastcomp とは Emscripten のデフォールトの翻訳器コアである。これは LLVM backend により実装されており、その役割は LLVM-IR を介して Clang (C または C++) から JavaScript への変換である。

Fastcomp には次の特徴がある:

  • LLVM (LLVM-backend)と統合されている
  • asm.js 向けのコード生成に特化し、最良の結果を齎す
  • 以前の旧型の翻訳器に比べ4倍以上も速く、メモリー消費も少なく、かつ良好なコードを生成する

Fastcomp は次の2つのリポジトリーにより保守されている:

Fastcomp を始める

Fastcomp (Clang)は Emscripten SDK の一部であり、必要なバイナリー群は自動的に導入される(但し例外として GNU/Linux においては、簡単な導入用の事前構築済みのバイナリー群を用意してはいないので SDK を君自身の手によって構築する必要がある)。

ソースから構築する必要があれば次のようにする:

(!) 警告
バックエンドは LLVM upstream リポジトリーに追加されたばかりで、多くの GNU/Linux ディストリビューションのパッケージ版では Fastcomp をまだ含んでおらず、それらを使って構築しようとしても Emscripten はエラーを発する事になるでしょう。

原初の翻訳器コア (非推奨)

原初の翻訳器は多くのコード生成の為のモード(配列の型付けの有無、 asm.js非asm.js、ほかたくさん!)を持っており、それはあまり効率が良いものとは言えなかった。そしてやがて、原初の翻訳器は保守も難しくなり、予測不能な翻訳速度の低下も発生した。

そこで Fastcomp を Emscripten-1.12.1 からのデフォールトとして採用し、原初の翻訳器は”非推奨”とした。

(!) 備考
お勧めしないが、手作業で Fastcomp を無効化し、ソースから原初の翻訳器を構築する事もできないことはない。

Fastcomp により生じた変化

原初の翻訳器が問題を抱えてしまった結果として、我々はより良好な翻訳器として Fastcomp を開発した:

  • 原初の翻訳器を合理化し、 asm.js 向けに最適化されたコード生成に特化した。
  • 原初の翻訳器に比べ翻訳速度をはるかに(4倍以上!)に高速化した。
  • 原初の翻訳器よりも省メモリーで動作するようにした。
  • 原初の翻訳器よりもLLVMとの統合性を向上し、より良好なコードを得られるようにした。

Fastcomp により生じた欠点について

主な欠点として Emscripten の構築には LLVM が必須となり、 構築済みの LLVM のストックを長くは使えなくなった事を挙げられる。

それから、原初の翻訳器にはあったが Fastcomp には存在しない機能が幾つかある(詳細は次の節へ)。

(!) 備考
我々は新しい Emscripten のバックエンドがやがて LLVM の upstream に取り込まれ、構築をストック可能になる事を願っている。

Fastcomp では提供されていない機能群

原初の翻訳器にはあった幾つかの機能が Fastcomp には取り込まれていない:

  • setting.js のオプションの幾つか(FORCE_ALIGNMENT, HEAP_INIT, ほか)が非推奨となった。万一これらのサポートされなくなったオプションを使用しようとした場合、君は翻訳時エラーを見ることになるだろう。
  • asm.js の共有モジュールとしてのリンクも提供されない。これは特に非推奨と謂う訳では無いので再検討する必要はあるかもしれないと考えている。
(!) 備考
通常の静的リンクの使用は概ねのプロジェクトにおいては良好に動作する。この為のオプション群 `MAIN_MODULE` と `SIDE_MODULE` が現時点では動作しない。

Fastcomp を無効化する方法

(!) 警告
Fastcomp を無効化しないのが懸命だ。以下について本当に許容しうるかよく考えるべきだ:
  • 構築速度は非常に遅くなり、より多くのメモリーも消費し、かつ結果は最適化しきれていないコードとなる。
  • 旧い翻訳器はテストも不足しており、恐らくバグも増える。

原初の翻訳器はまだ使える状態ではある。 Fastcomp に取り込まれていない機能を使いたい場合があればやむを得ない。とは言え、そのような機能は非常に少ないし、凡そ殆どは非推奨の機能か、あるいは移植を待っている状態だ。

しかしながら、それでもなお旧型の翻訳器を使いたいと言うのならば、 Fastcomp を無効化する設定EMCC_FAST_COMPILER=0 を構築時に施す:

EMCC_FAST_COMPILER=0 emcc [..]

これで Fastcomp を無効化し、 Fastcomp リポジトリー または 構築済みの LLVM のストックの 何れも 使用できる状態になる。後者については試験不足ではあるものの原理的には動作する。 Fastcomp を無効化した場合には Fastcomp リポジトリーのあらゆるもの(新型のバックエンドも新型のターゲットトリプルも)が使用されなくなる。

Fastcomp が有効かどうかはデバッグ出力を見れば分かる。例えば、 EMCC_DEBUG=1 emcc tests/hello_workd.c を実行し、もしも Fastcomp が有効ならば次の出力が得られる:

    DEBUG    root: emscript: llvm backend: ...
    DEBUG    root:   emscript: llvm backend took

このデバッグ出力から LLVM バックエンドの使用が分かる。一方は処理時間を表示するためのものだ。対して、 Fastcomp が無効で旧型の翻訳器が使われていれば、次の出力が得られる:

    DEBUG    root: emscript: ll=>js
    DEBUG    root:   emscript: scan took ...
    ...
    DEBUG    root: emcc step "emscript (llvm=>js)" took ...

この出力では旧型の翻訳器(ll=>js)が呼び出されている事が分かる。またこの段階の処理時間の表示に加えて、所要した総時間も表示される。念の為、もう一度言うが、これは 旧型 の翻訳器の出力である。誰もこの表示を見る事が無くなる日が訪れる事を祈る!

FAQ

WARNING: Linking two modules of different target triples [..] asmjs-unknown-emscripten それと le32-unknown-nacl とか出たんだけどどうしたら良い?

旧型の翻訳器(あるいは旧版の Fastcomp)で翻訳したビットコードファイルと新型の翻訳器で翻訳したビットコードをリンクしようとしただろう。これは場合によっては上手く行く事もあるのだが、危険なので可能な限り回避すべし。新型の翻訳器で全てのビットコードを再翻訳すると良い。

0 件のコメント:

コメントを投稿