リンク時最適化(LTO)

Note

SOLID 3.3.0以降で使用できます。

概要

LTOでは、リンク時に最適化を行うことで、プログラム全体を対象とした最適化を実行できます。これによりコンパイル単位(ソースファイル単位)に限定された解析に基づくコンパイル時最適化と比較し、パフォーマンスの向上やコードサイズの減少が期待できます。

LTOで可能となる最適化は、原理的には、プログラムを構成する全てのソースコードを一つのファイルにまとめ、全てのグローバル変数と関数に static を付けた時に可能な最適化と等しくなります。従来はコンパイラが行っていた中間表現を最適化して機械語生成を行うという工程をリンカが行うことになります。(そのためコンパイル時間は減少し、リンク時間が大幅に増加します。)

最もわかりやすいのは、コンパイル時最適化では不可能な、コンパイル単位をまたいだインライン展開がLTOによって可能となります。ただし、LTO自体は不要となった関数や変数を削除しないので、そのような不要コードを削減したい場合はリンカオプションに -Wl,--gc-sections を指定してください。その際には -ffunction-sections-fdata-sections オプションを併用すると、より効果的な不要コードの削除が期待できます。

一般的に、大規模なソフトウェアに対してリンク時最適化を行う場合、非常に多くのメモリ資源と時間を消費する傾向があるため、 開発PCのスペックによっては、メモリ不足やビルド時間の大幅な増加が問題となる可能性があります。この問題を緩和するため、 LLVM/Clangでは、ThinLTO と呼ばれるリンク時最適化の手法をサポートしており、メモリや計算リソース消費の増加を抑えながらパフォーマンスの向上が期待できます。

SOLIDのツールチェーンでは、この ThinLTO を推奨しており、LTOのデフォルトに設定しています。
ThinLTO の詳細は、 ThinLTO: Scalable and Incremental LTO を参照してください。

注意

コンパイラの最適化を抑制するために変数や関数を別ファイルに分割するという手法が、LTO有効時には期待通り動作しなくなります。(ファイルを分けても、インライン展開などが発生し、不要と判断された関数呼び出しや変数へのアクセスが削除されてしまう可能性があります。) そのような場合には volatile 修飾子やLTOを無効にするコンパイラオプション( -fno-lto )などを適切に使用するように修正してください。


使い方

プロジェクトのプロパティ ‣ プログラムの最適化 ‣ リンク時最適化 から選択してください。推奨は ThinLTO です。

Note

リンク時最適化を有効にすると、自動的にlldリンカが使用されるようになります。

注意

exeClang s008から全てのライブラリが ThinLTO 設定でビルドされるようになったため、-flto=thin 以外を指定した場合、正常動作しません。また、オブジェクトファイルは fat LTO オブジェクト形式 なので、コンパイルとリンク時にClangに -ffat-lto-objects オプションを指定する必要があります。指定しない場合、LTOは行われず、fat LTOオブジェクト内の機械語がそのままリンクされます。

exeClangでLTOを使用する場合に必要なオプション

コンパイラオプション(Clang)

リンカオプション(LLVM lld)

--ffat-lto-objects

Clang から渡す場合 -Wl,--ffat-lto-objects

(カンマの後にスペースを入れてはいけません。)


制限事項

アプリケーション プロジェクト内のコードは最適化されません。