FatLTO

はじめに

FatLTOオブジェクトは、複数のターゲットアーキテクチャのオブジェクトコードを含む代わりに、生成されたオブジェクトコードに加えてLTO互換IRを含む特別なタイプのファットオブジェクトファイルです。これにより、ユーザーはLTOを使用するかどうかをリンク時に決定することを遅延させることができます。これは、GCCのような他のコンパイラでは以前から利用可能な機能です。

FatLTOでは、コンパイラは.textセクションにマシンコードと.llvm.ltoセクションにLLVMビットコードの両方を含む標準オブジェクトファイルを生成できます。

概要

LLVMでは、FatLTOはFatLTODefaultPipelineを選択することでサポートされます。このパイプラインは

  1. 現在のモジュールでプリリンク(Thin)LTOパイプラインを実行します。

  2. プリリンクビットコードを特別な.llvm.ltoセクションに埋め込みます。

  3. ModuleOptimizationパイプラインを使用してモジュールの最適化を完了します。

  4. 新しい.llvm.ltoセクションを含むオブジェクトファイルを生成します。

内部的には、.llvm.ltoセクションは、ThinLTOPreLinkDefaultPipelineの後にEmbedBitcodePassを実行することで作成されます。このパスは、.llvm.ltoセクションの生成を担当します。その後、ThinLTODefaultPipelineが実行され、コンパイラはファットオブジェクトファイルを生成できます。

制限事項

リンカ

現在、LLVMファットLTOオブジェクトを使用したLTOは、LLDとLLVM goldプラグインを介したGNUリンカによってサポートされています。これは将来的に変更される可能性がありますが、他のリンカへのサポート拡張は今のところ計画されていません。

サポートされているファイル形式

現在の実装では、ELFファイルのみがサポートされています。COFFMach-Oのような他のオブジェクトファイル形式をサポートすることが有用かどうかは、執筆時点では不明です。

使用方法

Clangユーザーは、-fltoまたは-flto=thinと共に-ffat-lto-objectsを指定できます。-fltoオプションがない場合、-ffat-lto-objectsは無効です。

FatLTOを使用してオブジェクトファイルをコンパイルする

$ clang -flto -ffat-lto-objects example.c -c -o example.o

LTOを使用せずに、ファットオブジェクトのオブジェクトコードを使用してリンクします。 -fno-ltoが指定されている場合、これは-ffat-lto-objectsを無操作にします

$ clang -fno-lto -ffat-lto-objects -fuse-ld=lld example.o

あるいは、ファットオブジェクトでLTOへの参照をすべて省略し、標準のリンカの動作を維持することもできます

$ clang -fuse-ld=lld example.o

フルLTOでファットオブジェクトのLLVMビットコードを使用してリンクする

$ clang -flto -ffat-lto-objects -fuse-ld=lld example.o  # clang will pass --lto=full --fat-lto-objects to ld.lld

シンLTOでファットオブジェクトのLLVMビットコードを使用してリンクする

$ clang -flto=thin -ffat-lto-objects -fuse-ld=lld example.o  # clang will pass --lto=thin --fat-lto-objects to ld.lld