-xipo オプションが内部手続き解析パスを呼び出すことでプログラムの一部の最適化を実行します。このオプションを指定すると、リンク手順でのすべてのオブジェクトファイル間の最適化を行い、しかもこれらの最適化は単にコンパイルコマンドのソースファイルにとどまりません。ただし、-xipo によるプログラム全体の最適化には、アセンブリ (.s) ソースファイルは含まれません。
-xipo オプションは、大量のファイルを使用してアプリケーションをコンパイルしてリンクするときに特に便利です。このフラグを指定してコンパイルされたオブジェクトファイルには、ソースプログラムファイルとコンパイル済みプログラムファイル間で内部手続き解析を有効にする解析情報が含まれています。ただし、解析と最適化は、-xipo を指定してコンパイルされたオブジェクトファイルに限定され、オブジェクトファイルまたはライブラリは対象外です。
-xipo オプションには次の値があります。
表 A–34 -xipo の値
値 |
意味 |
---|---|
0 |
内部手続きの最適化を実行しません |
1 |
内部手続きの最適化を実行します |
2 |
内部手続きの別名解析と、メモリーの割り当ておよび配置の最適化を実行し、キャッシュ性能を向上します |
-xipo を指定しないと、-xipo=0 が使用されます。
-xipoだけを指定すると、-xipo=1 が使用されます。
次の例では同じ手順でコンパイルしてリンクします。
example% CC -xipo -xO4 -o prog part1.cc part2.cc part3.cc |
オプティマイザは 3 つのすべてのソースファイル間でファイル間のインライン化を実行します。ソースファイルのコンパイルをすべて 1 回のコンパイルで実行しないで済むように、またいくつかの個別のコンパイル時にそれぞれ-xipo オプションを指定して行えるように最後のリンク手順でファイル間のインライン化を実行します。
次の例では別々の手順でコンパイルしてリンクします。
example% CC -xipo -xO4 -c part1.cc part2.cc example% CC -xipo -xO4 -c part3.cc example% CC -xipo -xO4 -o prog part1.o part2.o part3.o |
コンパイルステップで作成されるオブジェクトファイルは、それらのファイル内でコンパイルされる追加の分析情報を保持します。そのため、リンクステップにおいてファイル相互の最適化を実行できます。
-xipo オプションでは最低でも最適化レベル -x04 が必要です。
同じコンパイラコマンド行に -xipo オプションと -xcrossfile オプションの両方は使用できません。
コンパイルとリンクを個別に実行する場合、-xipo をコンパイルとリンクの両方で指定しなければなりません。
-xipo なしでコンパイルされたオブジェクトは、-xipo でコンパイルされたオブジェクトと自由にリンクできます。
ライブラリでは、次の例に示すように、-xipo を指定してコンパイルしている場合でもファイル間の内部手続き解析に関与しません。
example% CC -xipo -xO4 one.cc two.cc three.cc example% CC -xar -o mylib.a one.o two.o three.o ... example% CC -xipo -xO4 -o myprog main.cc four.cc mylib.a |
この例では、内部手続き最適化は one.cc、two.cc、および three.cc 間と main.cc と four.cc 間で実行されますが、main.cc または four.cc と mylib.a のルーチン間では実行されません。最初のコンパイルは未定義のシンボルに関する警告を生成する場合がありますが、内部手続きの最適化は、コンパイル手順でありしかもリンク手順であるために実行されます。
-xipo オプションは、ファイルを介して最適化を実行する際に必要な情報を追加するため、非常に大きなオブジェクトファイルを生成します。ただし、この補足情報は最終的な実行可能バイナリファイルの一部にはなりません。実行可能プログラムのサイズの増加は、そのほかに最適化を実行したことに起因します。
内部手続き解析では、コンパイラは、リンクステップでオブジェクトファイル群を操作しながら、プログラム全体の解析と最適化を試みます。このとき、コンパイラは、このオブジェクトファイル群に定義されているすべての foo() 関数 (またはサブルーチン) に関して次の 2 つのことを仮定します。
実行時、このオブジェクトファイル群の外部で定義されている別のルーチンによって foo() が明示的に呼び出されない。
オブジェクトファイル群内のルーチンからの foo() 呼び出しが、そのオブジェクトファイル群の外部に定義されている別のバージョンの foo() によって置き換えられることがない。
アプリケーションに対して仮定 1 が当てはまらない場合は、コンパイルで -xipo=2 を使わないでください。
仮定 2 が当てはまらない場合は、コンパイルで -xipo=1 および -xipo=2 を使わないでください。
1 例として、独自のバージョンの malloc() で関数 malloc() を置き換え、-xipo=2 でコンパイルするケースを考えます。その独自のコードとリンクされる malloc() を参照するライブラリのあらゆる関数は、-xipo=2 でコンパイルする必要があり、それらのオブジェクトファイルはリンクステップに所属する必要があります。システムライブラリでは、このことが不可能なことがあり、このため、独自のバージョンの malloc のコンパイルに -xipo=2 を使ってはいけません。
もう 1 つの例として、別々のソースファイルにある foo() および bar() という 2 つの外部呼び出しを含む共有ライブラリを構築するケースを考えてみましょう。また、bar() は foo() を呼び出すと仮定します。foo() が実行時に割り込みを受ける可能性がある場合、foo() および bar() のソースファイルを -xipo=1 や -xipo=2 でコンパイルしてはいけません。さもないと、foo() が bar() 内にインライン化され、不正な結果になる可能性があります。
-xjobs