第19回 GCC2.95から追加変更のあったオプションの補足と検証(その7)

岸 哲夫

 今回は,引き続きGCC2.95から追加変更のあったオプションの補足と検証を行います.重要な「最適化オプション」について扱います. (筆者)

space

-floop-optimize

 ループの最適化を実行します.ループ内部の定数式を移動させたり,出口テスト条件を単純化したり,演算子の強さの低減を行い,ループの展開を行います.

 オプションの指定の方法は次のとおりです.

  • 指定あり

  •   gcc test222.c -S -O3 -floop-optimize

  • 指定なし

  •   gcc test222.c -S -O3 -fno-loop-optimize

 ソースと生成されたコードをリスト1リスト3に示します.

 最適化の結果,最初のループは削除されず,空のループになり,2番目のループは削除されています.サイズも小さくなり,処理速度も速くなっています.

-fmerge-all-constants,-fmerge-constants

 同一の定数および同一の変数を合併することを試みます.二つのオプションの意味はほぼ同一です.-fmerge-all-constantsの場合,一定の初期化された配列や,浮動小数点型の変数に対しても試みます.

 オプションの指定の方法は次のとおりです.

  • -fmerge-all-constants指定あり

  •   gcc test223.c -o test223 -O2 -fmerge-
         all-constants -fomit-frame-pointer

  • -fmerge-all-constants指定なし

  •   gcc test223.c -o test223 -O2 -fmerge-
         constants -fomit-frame-pointer

 ソースと生成されたコードを,リスト4リスト6に示します.

 なお,オブジェクト・ダンプは,objdump -Dで取得しています.

 constで指定された定数であるf_d1,f_d2は値が同一のため,オプションとして-fmerge-all-constantsを付加するとf_d1だけの領域しか確保されません.同一の値の変数でも別の名前で定義することは,プログラムの可読性を高めるためには有用だと思います.メモリ領域を気にしないのならば,このオプションを使う必要はありません.

-fmove-all-movables

 ループ中の不変式計算すべてをループ外に移動します.

-freduce-all-givs

 ループ中の一般誘導変数を削減します.

 なお,-fmove-all-movables,および-freduce-all-givsのオプションについては,将来なくなることが決まっています.別のオプションが追加されるはずです.

 オプションの指定の方法は次のとおりです.

  • 指定あり

  •   gcc test224.c -S -O3 -fmove-all-movables
         -freduce-all-givs

  • 指定なし

  •   gcc test224.c -S -O3 -fno-move-all-movables
         -fno-reduce-all-givs

 ソースと生成されたコードをリスト7リスト9に示します.

 最適化の結果,コードの行数は増加しましたが,
  xx = xx1 * xx2;
の式をループの外に移動し,xx1が100,xx2が10なので,
  xx = 1000
に置き換えられています.

-fno-branch-count-reg

 カウント・レジスタを使ってブランチ命令や減算命令を行いません.しかし,その代わりにレジスタ減算命令のシーケンスを作成します.このオプションは,それが可能なCPU環境でサポートされます.

 GCC内部でアセンブラ・ソースを生成する時点で,CXレジスタ(カウント・レジスタ)をブランチ命令や,減算命令に割り当てないようなので,プログラム例は省略します.

-fno-cprop-registers

 レジスタ割り付けの前後の命令を分割します.その後,「コピーの伝搬」を行って命令文を減らします.

-fno-default-inline

 C++のメンバ関数に関する最適化オプションです.ここでは触れません.

-fno-defer-pop

 関数呼び出しのたび,つねにその関数から戻るとすぐ引き数をPOPします.関数呼び出しの後に引き数をPOPしなければならない機種では,GCCはたいてい複数の関数呼び出しについてスタックに引き数を蓄積し,それらをすべて一度にPOPします.

 これはハードウェアのアドレスを共有して実行するような場合や,そのオブジェクトの永続性が短い関数から戻った場合などに指定するべきオプションです.

 最適化レベル-O,-O2,-O3,-Osを指定している場合は,つねにこのオプションはオフになります.

-fno-function-cse

 関数のアドレスをレジスタに置かないようにします.ある関数を呼び出す命令は,それぞれ関数のアドレスを明示的に保持するようにします.

 このオプションは効率の低いコードを生成しますが,実行中にほかのアセンブラ出力ソースを書き換えるようなことを行う場合には,このオプションを使用しないと混乱してしまいます.

 次回も引き続き「最適化オプション」の補足を行います.


NEW記事内インデックス    連載インデックスはこちら   Interfaceのトップ
◆最適化オプション
リスト

Copyright 2004 岸 哲夫

Copyright 1997-2004 CQ Publishing Co.,Ltd.