ネイティブ・イメージのLLVMバックエンド

ネイティブ・イメージでは、LLVM中間表現およびLLVMコンパイラを使用してネイティブ実行可能ファイルを生成する代替バックエンドが提供されます。このLLVMバックエンドを使用すると、ユーザーは、GraalVMネイティブ・イメージで直接サポートされていない代替アーキテクチャをターゲットにすることができます。ただし、このアプローチではパフォーマンス・コストがいくらか発生します。

インストールおよび使用方法

LLVMバックエンドは、ネイティブ・イメージとは別のコンポーネントとして出荷され、GraalVM Updaterを使用してインストールできます:

gu install native-image-llvm-backend

LLVMバックエンドを有効にするには、-H:CompilerBackend=llvmオプションをnative-imageコマンドに渡します。

コード生成オプション

デバッグ・オプション

バッチについて: LLVMコンパイルは次の4つのフェーズで実行されます:

  1. 関数ごとにLLVMビットコード・ファイル(f0.bcf1.bcなど)が作成されます。
  2. ビットコード・ファイルがバッチ(b0.bcb1.bcなど)にリンクされます。-H:LLVMMaxFunctionsPerBatch=1が指定されている場合、このフェーズはスキップされます。
  3. バッチが(b0o.bcb1o.bcなどに)最適化され、(b0.ob1.oなどに)コンパイルされます。
  4. コンパイルされたバッチが単一のオブジェクト・ファイル(llvm.o)にリンクされ、そのファイルが最終実行可能ファイルにリンクされます。

LLVMバックエンドを使用したGraalVMへのターゲット・アーキテクチャの追加方法

LLVMバックエンドの興味深いユース・ケースは、ネイティブ・イメージ用にまったく新しいバックエンドを実装することなく、新しいアーキテクチャをターゲットにすることです。現時点でこれを実現するために必要なステップは次のとおりです。

ターゲット固有のLLVM設定

場合によっては、GraalVMコードでLLVMのターゲット非依存の性質よりも深い部分を処理することが必要になります。これらの代表例は、直接レジスタ・アクセスおよび直接レジスタ・ジャンプ(トランポリンの場合)と、LLVMによって発行されるコードのスタック・フレームの構造に関する精度を実装するための、インライン・アセンブリ・スニペットです。このことは、十数個に満たない単純な値が新しいターゲットごとに設定されることを表します。

(AArch64の完全な値セット)

LLVMステートポイントのサポート

LLVMバックエンドでは、LLVMの一般的で十分にサポートされている機能が使用されますが、ガベージ・コレクション・サポートでは、LLVMの試験段階の機能であるステートポイント組込み関数が暗黙的に使用されます。つまり、新しいアーキテクチャをサポートするには、要求されたターゲットのLLVMにステートポイントを実装する必要があります。ほとんどのステートポイント・ロジックはビットコード・レベル、つまりターゲット非依存のステージで処理されることから、これには、ステートポイント組込み関数を弱める正しいタイプのコールの発行が大きく関係します。

(AArch64のステートポイント実装)

オブジェクト・ファイルのサポート

GraalコンパイラのLLVMバックエンドで作成されたプログラムのデータ・セクションは、LLVMによって処理されるコードから独立して発行されます。つまり、LLVMでコンパイルされたコードをGraalVMで生成されたデータ・セクションにリンクできるようにするには、Graalコンパイラでターゲット・アーキテクチャのオブジェクト・ファイルの再配置が認識されている必要があります。

(例はELFMachine$ELFAArch64Relocationsを参照)

その他の情報