LTO を完全に機能させるには、コンパイル段階と同じ情報と最適化アルゴリズムをリンク段階で利用できるようにする必要があります。GNU ツールはこれを行うことができず、これが実際に LLVM/Clang を作成する動機の 1 つになったと私は信じています。
違いを詳細に調べたい場合は、オプションごとに Map ファイル ( ld
option -Map <filename>
) を生成し、インライン化されていない関数やより大きな関数があるかどうかを確認することをお勧めします。関数の定義をヘッダーファイルに移動し、それextern inline
を効果的にマクロに変換するように定義することにより、これらの関数を強制的にインライン化することにより、インライン化の欠如を手動で解決できます (これは GNU 拡張です)。
より大きな関数は、一定の伝播の影響を受けない可能性が高く、それについてできることは何もないと思います。const
、、、、などの関数属性を慎重に宣言することで、いくつかの改善を行うことがleaf
できます。これらは、単一のコンパイル単位を使用している場合にコンパイラが検出する可能性のある特定の方法で関数が動作し、追加の最適化を可能にすることを効果的に約束します。noreturn
pure
returns_nonnull
対照的に、Clang はオブジェクト コードを特別な種類のバイトコードにコンパイルし (LLVM は Low Level Virtual Machine の略で、JVM は Java Virtual Machine のように、バイトコードを実行します)、このバイトコードの最適化をリンク時に実行できます (または、実際にはクールなランタイム)。このバイトコードは、LTO を使用するかどうかに関係なく最適化されるものであり、最適化アルゴリズムはコンパイラとリンカーの間で共通であるため、理論的には、LTO を使用するかどうかにかかわらず、Clang/LLVM はまったく同じ結果を返すはずです。
残念ながら、C バックエンドが LLVM から削除されたので、ターゲットにしているカスタム CPU に LLVM LTO 機能を使用する方法がわかりません。