富士通

FRファミリー一覧ページへ

開発にあたってのノウハウ

6. Cコンパイラのオプティマイズについて

Softune C Compilerの最適化レベル毎に実施する内容です。


最適化レベル0

最適化されません。-Oを指定しないのと等価です。


最適化レベル1

プログラムの流れを詳細に解析して最適化が行われます。

  • 直後への分岐の削除
  • 連続した分岐の削除
  • if文外実行言のthen-elseへの吸収
    if 文の then 節または、else 節のどちらか一方でのみ定義のあるデータがある場合、if 文外にそのデータの定義文があれば、その文を、定義の無い節に移動する。
    また、if 文に else 節がない場合は、else 節に相当する処理単位を作り、その処理単位に文を移動する。
[最適化前] [最適化後]
A=x; (削除)
if (...) { if (...) {
A=y; A=y;
} else { } else {
B=z; B=z; A=x;
} }
  • 共通式の除去
[最適化前] [最適化後]
t1=a+b; t1=a+b;
t2=a+b; t2=t1;
  • 定数計算 (定数の畳み込み)
    計算可能な定数計算をコンパイル時に行なう。
  • 定数の伝播
    定数が代入された変数の使用を定数で置き換える。
[最適化前] [最適化後]
a=b; (削除) /*以降でaが使用されない*/
=a; =0; /*aの参照を0で置き換える*/
  • 非実行文の削除
    if 文、while 文などの条件式の真偽判定ができる時や、無条件分岐などで、実行されない文がある時は、それらのコードを生成しない。
  • ループ内不変式の移動
    ループ内で値が変化しない式をループの外に移動する。
  • 複写の伝播
[最適化前] [最適化後]
a=b; (削除) /*以降でaが使用されない*/
/*この間にa,bの定義がない*/
=a; =b; /*aの参照をbで置き換える*/
  • 死変数の除去
[最適化前] [最適化後]
a=b; (削除)
/*以降でaが使用されない*/
  • 単純代入の除去
[最適化前] [最適化後]
a=b; a=b;
b=a; (削除)
  • 強さの縮小
    2のべき乗の定数による乗算をシフト化するなど、より高速な演算に置き換える。
[最適化前] [最適化後]
a=b*2; a=b<<2;
  • 関数のインライン展開(-x func の指定と同じ)
  • switch-case のテーブル分岐化
  • 命令スケジューリングの実施(-Kschedule の指定と同じ)
    • 遅延分岐命令の有効活用
    • LD 命令のインターロックの回避
    • アセンブラレベルの命令最適化
  • レジスタ割り付け

最適化レベル2

最適化レベル1 に加えて、次に示す最適化が行われます。

  • ループアンローリング
    ループアンローリングとは、ループ回数が検出可能であるときに、ループ回数を減らすことにより実行速度の向上をはかるものですが、オブジェクトサイズ が増加する傾向があります。したがって、オブジェクトサイズを重視する場合は、この最適化を実施すべきではありません。

(アンローリング前)
for(i=0;i<3;i++){ a[i]=0;}

(アンローリング後)
a[0]=0;
a[1]=0;
a[2]=0;


最適化レベル3

最適化レベル2 に加えて、以下の最適化が行なわれます。

  • 出口が2つあるループに対するループアンローリング
  • if 文による分岐があるループに対するループアンローリング
  • 最適化機能の繰り返し実施
    最適化機能の繰返し実施は、ループ・アンローリングを除く最適化機能を、最適化の余地がなくなるまで繰り返して実施します。翻訳時間が増加します。

最適化レベル4

最適化レベル3 に加えて、以下の最適化が行なわれます。

  • 演算の評価方法の変更(-Keopt の指定と同じ)
  • 標準関数呼出しの変更(-Klib の指定と同じ)
    Cの標準関数(strcpy、strcmp、strlen、memcpy、memset関数)のインライン展開を行ないます。標準関数のインライン展開が実施されるため、コードサイズが大きくなる可能性があります。