-pm オプションを -O3 オプションと組み合わせて使用すると、プログラムレベルの 最適化を指定できます。プログラムレベルの最適化では、すべてのソース・ファイ ルがモジュールと呼ばれる 1 つの中間ファイルにコンパイルされます。このモ ジュールが、コンパイラの最適化パスとコード生成パスに移動します。コンパイラ はプログラム全体を参照できるので、ファイルレベルの最適化ではほとんど適用さ れない次のような最適化を実行します。
❏ 関数内の特定の引数が常に同じ値をとる場合、コンパイラはその引数を値に置き 換え、引数の代わりに値を渡します。
❏ 関数の戻り値が一度も使用されない場合、コンパイラはその関数内の戻りコード を削除します。
❏ 関数が main から直接または間接に呼び出されない場合、コンパイラはその関数 を除去します。
コンパイラが適用しているプログラムレベルの最適化を知るには、-on2 オプション を使用して情報ファイルを作成します。詳細は、3.2.2 項「最適化情報ファイルの作 成方法(-on オプション)」(3-5 ページ)を参照してください。
3.3.1 プログラムレベルの最適化の制御(-opn オプション)
-pm -O3 を指定して起動するプログラムレベルの最適化は、-op オプションを使用す ることにより制御できます。具体的には -op オプションは、他のモジュール内の関 数があるモジュールの外部関数を呼び出せるか、またはあるモジュールの外部変数 を変更できるかを指定します。-op に続く番号は、呼び出しや変更を許可しようとし ているモジュールに設定するレベルを指定します。-O3 オプションは、この情報を 独自のファイルレベル解析と組み合わせて、そのモジュールの外部関数と変数の定 義を、静的に宣言された場合と同じ扱いにするかどうかを決定します。表 3-4 を使 用して、-op オプションに指定する適切なレベルを選択してください。
プログラムレベルの最適化の実行(-pm および -O3 オプション)
表 3-4. -op オプションのレベルの選択方法
特定の環境では、コンパイラは、指定された -op レベルとは異なるレベルに戻した り、プログラムレベルの最適化をすべて使用不可にしたりする場合があります。表 3-5 に、コンパイラが別の -op レベルに戻す原因となる条件と -op レベルの組み合わ せを示します。
表 3-5. -op オプションを使用する場合の特別な注意事項
モジュールの状況 使用するオプション
他のモジュールから呼び出される関数と、他のモジュール 内で変更されるグローバル変数がある。
-op0
他のモジュールから呼び出される関数はないが、他のモ ジュール内で変更されるグローバル変数がある。
-op1
他のモジュールから呼び出される関数も、他のモジュール 内で変更されるグローバル変数もない。
-op2
他のモジュールから呼び出される関数はあるが、他のモ ジュール内で変更されるグローバル変数がない。
-op3
-op の指定 条件 -op レベル
指定なし -O3 の最適化レベルが指定された。 デフォルトの -op2 になる。
指定なし コンパイラが -O3 最適化レベルにある外 部関数の呼び出しを検出した。
-op0 に戻る
指定なし main が定義されていない。 -op0 に戻る
-op1 または -op2 エントリ・ポイントとして定義されて
いる main をもつ関数がなく、かつ FUNC_EXT_CALLED プラグマによって 特定されている関数がない。
-op0 に戻る
プログラムレベルの最適化の実行(-pm および -O3 オプション)
3.3.2 C/C++ とアセンブリを組み合わせた場合の最適化に関する注意事項
プログラム内でアセンブリ関数が使用されている場合は、-pm オプションを指定す るときに注意が必要です。コンパイラは C/C++ ソース・コードだけを認識し、アセ ンブリ・コードが指定されていても認識できません。コンパイラではアセンブリ・
コードによる C/C++ 関数の呼び出しや C/C++ 関数に対する変数の変更が認識されな いので、-pm オプションを指定するとこのような C/C++ 関数は最適化の対象外にな ります。それらの関数に最適化を実行するには、それらの関数の宣言や参照の前に
FUNC_EXT_CALLED プラグマ(6.8.4 項「FUNC_EXT_CALLED プラグマ」(6-30 ペー
ジ)を参照)を配置します。
プログラムの中にアセンブリ関数が指定されている場合に使用できる別の方法は、
-op オプションを -pm オプションおよび -O3 オプションと組み合わせて使用するこ とです(3.3.1 項「プログラムレベルの最適化の制御(-opn オプション)」(3-6 ペー ジ)を参照)。
一般に、FUNC_EXT_CALLED プラグマを -pm -O3 および -op1 または -op2 と組み合
わせて適切に使用することにより、最良の結果を得ることができます。
アプリケーションに以下のいずれかの状況が当てはまる場合は、ここに示す解決策 を使用してください。
状況 アプリケーションは、アセンブリ関数を呼び出す C/C++ ソース・コー ドで構成されています。それらのアセンブリ関数は、C/C++ 関数の呼
び出しも C/C++ 変数の変更も行いません。
解決策 コンパイルするときに -pm -O3 -op2 を指定し、外部関数が C/C++ 関数 の呼び出しも C/C++ 変数の変更も行わないことをコンパイラに指示し
ます。-op2 オプションについては、3.3.1 項を参照してください。
-pm -O3 オプションだけを指定してコンパイルすると、コンパイラの最
適化レベルがデフォルトの -op2 から -op0 に戻ります。コンパイラで
-op0 を使用する理由は、C/C++ で定義されているアセンブリ言語関数
の呼び出しにより、他の C/C++ 関数を呼び出したり C/C++ 変数を変更 したりする可能性があることを想定しているからです。
状況 アプリケーションは、アセンブリ関数を呼び出す C/C++ ソース・コー ドで構成されています。それらのアセンブリ言語関数は C/C++ 関数を 呼び出しませんが、C/C++ 変数を変更します。
解決策 次の 2 つの解決策を試して、ご使用のコードでうまく機能する方を選 択してください。
プログラムレベルの最適化の実行(-pm および -O3 オプション)
状況 アプリケーションは、C ソース・コードおよびアセンブリ・ソース・
コードで構成されています。アセンブリ関数は、C 関数を呼び出す割 り込みサービス・ルーチンです。アセンブリ関数から呼び出される C 関数が C から呼び出されることはありません。これらの C 関数は main のように動作します。それらの関数は C へのエントリ・ポイントとし て機能します。
解決策 割り込みによって変更される可能性がある C/C++ 変数に volatile キー ワードを付加します。その後、次のどちらかの方法でコードの最適化 を実行します。
■ 最良の最適化を達成するには、アセンブリ言語割り込みから呼び 出されるすべてのエントリ・ポイント関数に FUNC_EXT_CALLED プラグマを適用してから、-pm -O3 -op2 を指定してコンパイルしま す。必ずすべてのエントリ・ポイント関数とともにプラグマを使 います。そうしないと、コンパイラは先頭に FUNC_EXT_CALL プ ラグマを指定していないエントリ・ポイント関数を除去します。
■ -pm -O3 -op3 を指定してコンパイルします。FUNC_EXT_CALL プ
ラグマを指定しないので、-op3 オプションを使用しなければなり ません。このオプションは -op2 ほど強力ではなく、最適化があま り効率的でない場合もあります。
追加オプションを指定せずに -pm -O3 を使用すると、アセンブリ関数か ら呼び出される C/C++ 関数が除去されることを忘れないでください。
それらの関数を残しておくには、FUNC_EXT_CALLED プラグマを指定 します。
FUNC_EXT_CALLED についての詳細は 6.8.4 項(6-30 ページ)を、-op
オプションについては 3.3.1 項を参照してください。
オプティマイザを使用する場合の特別な注意事項