プロシージャー間の最適化 (IPO) はマルチステップの自動処理で、コンパイラーがコードを解析してどの最適化が有効であるかを判断できるようにします。
コンパイラーは、次のような最適化を適用します。
アドレスの解析
配列次元のパディング
エイリアス解析
配列の自動転置
メモリープールの自動生成
C++ クラス階層解析
共通ブロック変数の統合
共通ブロックの分割
定数の伝播
不要な呼び出しの検出
不要な仮引数の排除
不要な関数の排除
仮引数のアライメント解析
前方代入
間接呼び出し変換
インライン展開
mod/ref 解析
不要な呼び出しの部分的に排除
レジスターに引数を渡して呼び出しとレジスターの使用を最適化
ポインター解析
ルーチンのキー属性の伝播
専用化
スタックフレームのアライメント
構造体分割とフィールドの並べ替え
シンボル・テーブル・データの促進
未参照変数の削除
プログラム全体の解析
IPO は単一ファイルのコンパイルと複数ファイルのコンパイルの 2 つのコンパイルモデルをサポートしています。
コンパイラーは、デフォルトの最適化レベル O2 でいくつかの単一ファイルの IPO を行います。また、O1 最適化レベルで、インラインプラグマまたは属性 (GNU* C および C++) が表記されている関数、およびクラスの宣言に関数本体が含まれている C++ クラスメンバー関数などのインライン展開を行うこともあります。
複数ファイルのコンパイルでは [Q]ipo オプションを使用し、通常のオブジェクト・ファイルではなく 1 つまたは複数の擬似オブジェクト・ファイルを生成します。(擬似オブジェクト・ファイルについての詳細は、下の「コンパイル」セクションを参照してください。) また、コンパイラーは、プログラムを構成する個々のソースファイルからの情報を収集します。コンパイラーはこの情報を使用して、異なるソースファイルの関数とプロシージャーを最適化します。
IPO を使用して各ソースファイルがコンパイルされるたびに、コンパイラーはソースコードの中間表現 (IR) を擬似オブジェクト・ファイルに格納します。擬似オブジェクト・ファイルには、通常のオブジェクト・ファイルの代わりに IR が含まれます。擬似オブジェクト・ファイルは、通常のオブジェクト・ファイルのサイズよりも 10 倍以上の大きさになることがあります。
IPO コンパイルフェーズでは、擬似オブジェクト・ファイルのみが表示されます。
[Q]ipo コンパイラー・オプションを使用してリンクすると、コンパイラーはリンカーの直前に起動されます。コンパイラーは、すべての擬似オブジェクト・ファイルを対象に IPO を実行します。インテル® コンパイラーまたはインテルのリンクツールを使用して、擬似オブジェクトをリンクする必要があります。IPO によるリンク中に、コンパイラーと他のリンクツールは、擬似オブジェクト・ファイルをコンパイルし、ユーザー・プラットフォームで提供されるオブジェクト・ファイル・リンカーを呼び出します。
コンパイラーは、プログラム全体の条件が満たされると適用できる IPO 最適化、または効率性が大幅に向上する多くの IPO 最適化をサポートしています。
解析処理中、コンパイラーは擬似ファイル、オブジェクト・ファイル、ライブラリー・ファイルにあるすべての中間表現 (IR) を読み取り、すべての参照が解決されているか、またはシンボルが擬似オブジェクト・ファイルに定義されているかどうかを判断します。データと関数の両方の擬似オブジェクト・ファイルにある IR に含まれているシンボルは、プログラム全体の解析の結果に基づいた操作を行う候補です。
プログラム全体の解析には、オブジェクト・リーダー・メソッドとテーブルメソッドの 2 種類があります。いずれかの解析でプログラム全体の条件が満たされいてると判断された場合には、ほとんどの最適化が適用できます。ただし、最適化によっては、オブジェクト・リーダー・メソッドにより生成される結果が必要なものと、テーブルメソッドにより生成された結果が必要なものとがあります。
オブジェクト・リーダー・メソッド
オブジェクト・リーダー・メソッドでは、オブジェクト・リーダーによりネイティブリンカーの動作をエミュレートし、アプリケーションのシンボルを解決しようとします。すべてのシンボルが解決されると、プログラム全体の条件が満たされたことになります。このプログラム全体の解析では、プログラム全体の条件が検出される可能性が高くなります。
テーブルメソッド
テーブルメソッドでは、コンパイラーが擬似オブジェクト・ファイルを解析して、コールグラフを作成します。
コンパイラーには libc などのすべての重要な言語固有のライブラリー関数についての詳細なテーブルが含まれています。この 2 番目のメソッドでは、コンパイラーはアプリケーションのコールグラフを作成します。それから、コンパイラーは関数テーブルとアプリケーションのコールグラフを比較します。コールグラフ中の未解決の各シンボルについて、コンパイラーは、コンパイラー・テーブルにある未解決の関数を検索することで、そのような呼び出しを解決しようとします。コンパイラーが関数を解決できた場合にプログラム全体の条件が整います。