Everything

-O


最適化のレベル,または各最適化項目の詳細を指定します。

[指定形式]

-O[level]
-O[item[=value][,item[=value]]...]

 

-

省略時解釈

オブジェクト・サイズと実行速度の両方に効果のある最適化を行います(-Odefaultオプションの指定と同じです)。

[詳細説明]

-

最適化のレベル,または各最適化項目の詳細を指定します。

-

levelに指定可能なものを以下に示します。
これ以外のものを指定した場合は,エラーとなります。

default

デフォルト

オブジェクト・サイズと実行速度の両方に効果のある最適化を行います。

size

オブジェクト・サイズ優先の最適化

ROM/RAM容量の削減を重視して,一般的なプログラムに対して有効な最大限の最適化を行います。

speed

実行速度優先の最適化

実行速度の向上を重視して,一般的なプログラムに対して有効な最大限の最適化を行います。

nothing

デバッグ優先の最適化

デバッグのしやすさを重視し,デフォルトで実行する最適化を含むすべての最適化を抑止します。

 

-

level,およびitemを省略した場合は,sizeを指定したものとみなします。

-

item,およびvalueに指定可能なものを以下に示します。
これ以外のものを指定した場合は,エラーとなります。

最適化項目

item

パラメータ(value

説明

unroll

0~4294967295

(整数値)

ループ展開

ループ文(for,while,do-while)を展開します。

valueで,最大で何倍の展開を行うかを指定します。

valueの値0は 値1と同じ意味となります。

valueを省略した場合は,2を指定したものとみなします。

本機能は-Osize,-Ospeed, または-Odefault が指定された場合に有効です。

delete_static_func

on,またはoff

未使用static関数の削除

valueを省略した場合は,onを指定したものとみなします。

inline_level

0~3

(整数値)

関数のインライン展開

valueは,展開のレベルを表します。

0:#pragma inline指定した関数を含めて,すべてのインライン展開を抑止します。

1:#pragma inline指定した関数のみ展開します。

2:自動的に展開対象の関数を判別して展開します。

3:コード・サイズがなるべく増加しない範囲で,自動的に展開対象の関数を判別して展開します。

ただし,1~3を指定した場合でも,関数の内容やコンパイル状況により,#pragma inline指定した関数が展開されない場合があります。

valueを省略した場合は,2を指定したものとみなします。

本項目は,-Osize,-Ospeed,または-Odefaultオプションを指定した場合に有効です。

inline_size

0~65535

(整数値)

インライン展開サイズ

コード・サイズが何%増加するまでインライン展開を行うかを指定します。

100を指定した場合はコードサイズが100%増加するまでインライン展開します。

valueを省略した場合は,100を指定したものとみなします。

本項目は,-Oinline_level=2 オプションを指定した場合に有効です(-Ospeedオプションによる指定も含みます)。

pipeline

【V1.03以降】

on,またはoff

パイプライン最適化

valueを省略した場合は,onを指定したものとみなします。

本項目は,-Osize,-Ospeed,または-Odefaultを指定した場合に有効です。

tail_call

on,またはoff

関数末尾の関数呼び出しのbr命令置き換え

onを指定した場合,関数の末尾が関数呼び出しであり,かつ一定の条件を満たす場合に,その呼び出しに対してcall命令ではなくbr命令を生成してretコードを削除し,コード・サイズを削減します。

ただし,一部のデバッグ機能を使用することができなくなります。

valueを省略した場合は,onを指定したものとみなします。

merge_files

なし

複数ファイルをマージしてコンパイル

本オプションを省略した場合は,マージせずに入力ファイル単位でコンパイルします。

複数のCソース・ファイルをマージしてコンパイルを行い,1 ファイルで出力します。

出力ファイル名は-oを指定した場合は,指定した出力ファイル名となり,-oを指定しない場合は,最初に指定したCソース・ファイル名に対して-oの省略時解釈に従ったファイル名となります。

入力ファイルが1 ファイルの場合,および-Pと同時に指定した場合は,本オプションは無効となります。

-S,または-cと同時に指定した場合,2 番目以降に指定したCソース・ファイル名について,-oの省略時解釈に従ったファイル名の空ファイルを生成します。

-Oinline_level と同時に指定した場合,ファイル間インライン展開を行います。

本オプションを指定して生成したオブジェクト・ファイルをリンクする場合,リンカ・オプション-delete,-rename,または-replaceを同時に指定した場合の動作は保証しません。

intermodule

なし

大域最適化の実施

主な最適化内容は以下のとおりです。

-

手続き間別名解析を利用した最適化

-

パラメータ,戻り値の定数伝播

whole_program

なし

入力ファイルがプログラム全体であることを仮定した最適化の実施

本オプションを省略した場合は,コンパイル対象ファイルがプログラム全体であることを仮定しません。

以下の条件を満たすことを前提にコンパイルを行い,条件を満たさなかった場合の動作は保証されません。

-

コンパイル対象ファイル内で定義したextern変数の値およびアドレスが,コンパイル対象ファイル以外で変更および参照されない。

-

コンパイル対象ファイル内からコンパイル対象ファイル以外で定義した関数を呼び出している場合,その呼び出された関数からコンパイル対象ファイル内の関数が呼ばれることはない。

 

本オプションを指定した場合,-Ointermoduleオプションを指定したものとみなしてコンパイルを行います。

また,入力C ソース・ファイルが複数の場合,-Omerge_filesオプションを指定したものとみなしてコンパイルを行います。

alias

ansi,またはnoansi

ポインタ指示先型を考慮した最適化の指定

本オプションを省略した場合は,noansiを指定したものとみなします。

same_code 【V1.02以降】

on,またはoff

コンパイル単位の同一セクション内に存在する複数の同一命令列を統合し,関数化します。

valueを省略した場合は,onを指定したものとみなします。

本項目は,-Osize,-Ospeed,または-Odefaultオプションを指定した場合に有効です。

branch_chaining 【V1.10以降】

on, またはoff

分岐命令のコードサイズを削減する最適化の実施

コードサイズの小さな分岐命令を使用します。コードサイズの小さな分岐命令を使用するために,最終的な分岐先まで直接分岐するのではなくて,分岐先を,行き先が同じ他の分岐命令にすることがあります。

結果として,コードサイズが小さくなりますが,実行速度は低下します。

また,オプション-g_lineの指定なしで本最適化を利用すると,ステップ実行時の挙動に影響がでる場合がございますのでご注意ください。

valueを省略した場合は,onを指定したものとみなします。

本項目は,-Osizeまたは-Odefaultオプションを指定した場合に有効です。

align
【V1.10以降】

on, またはoff

整列条件の変更を伴う最適化の実施

たとえば構造体型の変数の中にある,連続した領域にアクセスする際に,変数の整列条件を変更した上で,複数のアクセスを1回に統合することで生成する命令数を少なくし,コードサイズ削減,実行速度の向上を図ります。

整列条件を変更する結果として,パディング・データの埋め込みが発生し,データを記憶する領域の使用量が増加する場合があります。

valueを省略した場合は,onを指定したものとみなします。

本項目は,-Osize,-Ospeedまたは-Odefaultオプションを指定した場合に有効です。

-stuffオプションを同時に指定した場合,本項目は無効になります。

 

-

同じitemについて,本オプションを複数指定した場合は,あとから指定したものが有効となります。

-

-Olevelの指定により,-Oitemには以下の値を設定します。

表中に存在しない-Oitemは,-Olevelの影響を受けません。

最適化レベル指定による最適化は下記の最適化項目と1対1に対応しているわけではありません。例えば-Odefaultを指定し,各最適化項目を-Osizeに合わせたとしても,-Osizeと同等の最適化を実施するわけではありません。

最適化項目(item

最適化レベル(level

-Osize

-Ospeed

-Odefault

-Onothing

unroll

1

2

1

1

delete_static_func

on

on

on

off

inline_level

3

2

3

-

inline_size

0

100

0

-

tail_call

on

on

on

off

pipeline

on

on

on

off

same_code

on

off

off

off

branch_chaining

on

off

on

off

align

on

on

off

off

[使用例]

-

オブジェクト・サイズ優先の最適化を行います。

>ccrl -Osize -cpu=S2 -dev=dr5f100pj.dvf main.c

 

-

大域最適化を実施します。

-

手続き間別名解析を利用した最適化

> ccrl -cpu=S2 im1.c -Odelete_static_func=off,intermodule

<Cソース>

extern long x[2];
extern int y[2];
static long func1(long *a, int *b) {
    *a=0;
    *b=1;
    return *a;
}
long func2(void) {
    return func1(&x[0], &y[1]);
}

<出力コード>

_func1@1:
    .STACK _func1@1 = 6
    movw de, ax
    push bc
    pop hl
    clrw ax
    movw [de+0x02], ax
    movw [de], ax
    onew ax
    movw [hl], ax
    clrw bc         ; aとbの指すアドレスが違うため0を直接代入
    clrw ax         ;
    ret

 

-

パラメータ,戻り値の定数伝播

> ccrl -cpu=S2 im2.c -Oinline_level=1,intermodule

<Cソース>

static __near int func(int x, int y, int z) {
    return z-x-y;
}
int func2(void) {
    return func(3,4,8);
}

<出力コード>

    .SECTION .text,TEXT
_func@1:
    .STACK _func@1 = 4
    onew ax         ; 1(=8-3-4)を直接代入
    ret
    .SECTION .textf,TEXTF
_func2:
    .STACK _func2 = 4
    movw de, #0x0008
    movw bc, #0x0004
    movw ax, #0x0003
    br !_func@1

 

-

ポインタ指示先の型を考慮した最適化を指定します。

> ccrl -cpu=S2 al1.c -Oalias=ansi

<Cソース>

long x, n;
void func(short *ps)
{
    n = 1;
    *ps = 2;
    x = n;
}

<出力コード>

*psとnは型が異なるため,*ps = 2;ではnの値は変化しないと判断し,(A)で,n = 1で代入に使用した値を再利用します。(*ps = 2;によってnの値が書き換わる場合,結果は変わります。)

_func:
    .STACK _func = 4
    movw de, ax
    clrw ax
    movw bc, ax
    movw !LOWW(_n+0x00002), ax
    onew ax
    movw hl, ax
    movw !LOWW(_n), ax
    onew ax
    incw ax
    movw [de], ax
    movw ax, bc     ; (A) n = 1で代入に使用した値を再利用する
    movw !LOWW(_x+0x00002), ax
    movw ax, hl     ; (A)
    movw !LOWW(_x), ax
    ret

[注意]

-

最適化を適用したオブジェクト・コードを使って,ソース・レベル・デバッグを実施する場合,次のような影響があるので注意してください。

-

最適化による式の変形(複写の伝播や共通部分式の認識など)によって,ソース・プログラム中の変数参照個所でその変数に対するリード/ライトが行われない場合があります。

-

文に対する最適化(共通化,削除,並び替えなど)によって,ステップ実行がソース・プログラムどおりに行われない場合があります。
また,特定の文に対してブレークポイントが設定できない場合があります。例えば,文の削除が起こった場合,その文にはブレークポイントを設定できません。

-

文や変数に対する最適化(文の並び替え,レジスタ割付など)によって,変数の生存範囲(プログラム中でその変数を参照可能な範囲)や変数の位置(レジスタやメモリ上の位置)が変更される可能性があります。

-

インライン展開が適用された文に対するステップ実行は,インライン展開部分でなく,インライン展開元の関数内で行なわれます。
インライン展開が適用された関数呼び出しは削除されるので,ブレークポイントは設定できません。

-

コンパイル時,デバッグ情報の処理でメモリを大量に消費するため,“out of memory”となる可能性があります。