ネイティブ・イメージのLLVMバックエンド
ネイティブ・イメージには、LLVM中間表現およびLLVMコンパイラを使用してネイティブ実行可能ファイルを生成する代替バックエンドが含まれています。これを使用するには、ネイティブ・イメージの呼出しに-H:CompilerBackend=llvm
オプションを追加します。
LLVMバックエンドを使用するには、GraalVMのLLVMツールチェーンがインストールされている必要があります(gu install llvm-toolchain
を使用)。
コード生成オプション
-H:+SpawnIsolates
: 分離を有効にします。分離は、LLVMバックエンドを使用する際にパフォーマンスの低下をもたらすため、デフォルトでは無効になっています。-H:+BitcodeOptimizations
: LLVMビットコード・レベルで積極的な最適化を有効にします。これは試験段階であり、バグを引き起こす可能性があります。
デバッグ・オプション
-H:TempDirectory=
: ネイティブ・イメージによって生成されたファイルの保存場所を指定します。LLVMファイルは、このフォルダのSVM-<timestamp>/llvm
に保存されます。-H:LLVMMaxFunctionsPerBatch=
: コンパイル・バッチの最大サイズを指定します*。1に設定すると、すべての関数が個別にコンパイルされ、0に設定すると、すべてが単一のバッチとしてコンパイルされます。-H:DumpLLVMStackMap=
: コンパイル済関数とそれに対応するビットコード・ファイルの名前の間のマッピングなど、デバッグ情報をダンプするファイルを指定します。
バッチについて: LLVMコンパイルは次の4つのフェーズで実行されます:
- 関数ごとにLLVMビットコード・ファイル(
f0.bc
、f1.bc
など)が作成されます。 - ビットコード・ファイルがバッチ(
b0.bc
、b1.bc
など)にリンクされます。-H:LLVMMaxFunctionsPerBatch=1
が指定されている場合、このフェーズはスキップされます。 - バッチが(
b0o.bc
、b1o.bc
などに)最適化され、(b0.o
、b1.o
などに)コンパイルされます。 - コンパイルされたバッチが単一のオブジェクト・ファイル(
llvm.o
)にリンクされ、そのファイルが最終実行可能ファイルにリンクされます。
LLVMバックエンドを使用したGraalVMへのターゲット・アーキテクチャの追加方法
LLVMバックエンドの興味深いユース・ケースは、ネイティブ・イメージ用にまったく新しいバックエンドを実装することなく、新しいアーキテクチャをターゲットにすることです。現時点でこれを実現するために必要なステップは次のとおりです。
ターゲット固有のLLVM設定
場合によっては、GraalVMコードでLLVMのターゲット非依存の性質よりも深い部分を処理することが必要になります。これらの代表例は、直接レジスタ・アクセスおよび直接レジスタ・ジャンプ(トランポリンの場合)と、LLVMによって発行されるコードのスタック・フレームの構造に関する精度を実装するための、インライン・アセンブリ・スニペットです。一般的に、このことは、十数個に満たない単純な値が新しいターゲットごとに設定されることを表します。将来的には、これが新しいターゲットをサポートするために唯一必要な追加になるようにすることが目標です。
LLVMステートポイントのサポート
LLVMバックエンドでは、LLVMの一般的で十分にサポートされている機能が使用されますが、ガベージ・コレクション・サポートでは、LLVMの試験段階の機能であるステートポイント組込み関数が暗黙的に使用されます。現在、この機能はx86_64でのみサポートされており、現在、コード・ベースにAArch64のGraalVM実装を追加するよう要求しているところです。つまり、LLVMコミュニティの多大な努力が実らないかぎり、新しいアーキテクチャをサポートするには、要求されたターゲットのLLVMにステートポイントを実装する必要があります。ほとんどのステートポイント・ロジックはビットコード・レベル、つまりターゲット非依存のステージで処理されることから、これには、ステートポイント組込み関数を弱める正しいタイプのコールの発行が大きく関係します。AArch64のステートポイント実装は100行未満のコードで構成されます。
オブジェクト・ファイルのサポート
GraalコンパイラのLLVMバックエンドで作成されたプログラムのデータ・セクションは、現在、LLVMによって処理されるコードから独立して発行されます。つまり、LLVMでコンパイルされたコードをGraalVMで生成されたデータ・セクションにリンクできるようにするには、Graalコンパイラでターゲット・アーキテクチャのオブジェクト・ファイルの再配置が認識されている必要があります。LLVMビットコードとしてコードを使用してデータ・セクションを発行することはLLVMバックエンドの次の優先事項であるため、これは将来のターゲットでは問題になりません。
(例はELFMachine$ELFAArch64Relocations
を参照)