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

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

インストールと使用方法 #

LLVMバックエンドは、ネイティブイメージの一部としてデフォルトでは含まれていません。使用する場合は、以下のmxコマンドを使用してソースからGraalVMをビルドする必要があります。

mx --dynamicimports /substratevm build
export JAVA_HOME=$(mx --dynamicimports /substratevm graalvm-home)

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

コード生成オプション #

  • -H:+BitcodeOptimizations:LLVMビットコードレベルで積極的な最適化を有効にします。これは実験的な機能であり、バグが発生する可能性があります。

デバッグオプション #

  • -H:TempDirectory=:ネイティブイメージによって生成されたファイルの保存場所を指定します。LLVMファイルは、このディレクトリのSVM-<timestamp>/llvmに保存されます。
  • -H:LLVMMaxFunctionsPerBatch=:コンパイルバッチの最大サイズを指定します*。1に設定すると、各関数が個別にコンパイルされ、0に設定するとすべてが単一のバッチとしてコンパイルされます。
  • -H:DumpLLVMStackMap=:デバッグ情報(コンパイルされた関数と対応するビットコードファイルの名前のマッピングを含む)をダンプするファイルを指定します。

バッチについて: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バックエンドの興味深いユースケースの1つは、ネイティブイメージ用のまったく新しいバックエンドを実装しなくても、新しいアーキテクチャをターゲットにすることです。現在、これを実現するための必要な手順を以下に示します。

ターゲット固有のLLVM設定 #

GraalVMコードがLLVMのターゲットに依存しない性質よりも深く入り込む必要があるいくつかのインスタンスがあります。これらは、特に、直接レジスタアクセスと直接レジスタジャンプ(トラップポリン用)を実装するためのインラインアセンブリスニペット、およびLLVMによって生成されたコードのスタックフレームの構造に関する精度です。これは、新しいターゲットごとに設定する必要がある1ダース未満の単純な値を表します。

(AArch64の値の完全なセット)

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

LLVMバックエンドは主にLLVMの一般的なよくサポートされている機能を使用していますが、ガベージコレクションのサポートは、LLVMの実験的機能であるステートポイントイントリンシックスの使用を意味します。つまり、新しいアーキテクチャをサポートするには、要求されたターゲットのLLVMでステートポイントを実装する必要があります。ステートポイントロジックの大部分はビットコードレベル(つまり、ターゲットに依存しないステージ)で処理されるため、これは主にステートポイントイントリンシックスを下げるための正しいタイプの呼び出しを生成することです。

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

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

GraalコンパイラのLLVMバックエンドで作成されたプログラムのデータセクションは、LLVMによって処理されるコードとは別に生成されます。つまり、Graalコンパイラは、LLVMコンパイルされたコードをGraalVM生成データセクションにリンクするために、ターゲットアーキテクチャのオブジェクトファイルのリロケーションを理解する必要があります。

(例としてELFMachine$ELFAArch64Relocationsを参照してください)

さらに読む #

お問い合わせ