Renesas Synergy™

FAQ 1008115 : 変数の生存範囲を小さくする記述例は?

回答

以下の例のように、スタック変数に値が代入されてからその値が実際に参照されるまでに “間”がある場合、その間、レジスタが占有されて他の変数がレジスタに割り付けられる機会が減ることになります。
Cコンパイラの最適化により値の代入が後ろへ移動することが多いですが、 例のように関数呼び出しを含む場合は、最適化されないこともあります。
このような場合には、実際に参照する直前に代入を行うように変更することにより、 他の変数のレジスタ割り付けの機会が増えてメモリ・アクセスが減り、 コード・サイズが小さくなります。

 

変更前   変更後 (8byte減 ※)
    int i = 0, j = 0, k = 0, m = 0;

    /* この間、関数呼び出しあり */
    /* これらの変数の使用はなし */

    while ((k & 0xFF) != 0xFF) {
        k = s1;
        if (k & MASK) {
            if (m != 1) {
                s2 += 2;
                m = 1;
                array[15+i+j] = 0xFF;
                j++;
            }
        }
    }
        ...
    int i, j, k, m;

        ...

    i = 0;
    j = 0;
    k = 0;
    m = 0;

    while ((k & 0xFF) != 0xFF) {
        k = s1;
        if (k & MASK) {
            if (m != 1) {
                s2 += 2;
                m = 1;
                array[15+i+j] = 0xFF;
                j++;
            }
        }
    }
         ...


※削減量は例に関するものであり、個々のケースにより異なります。



ソースを変更した結果、出力命令が減少し、高速化もされる場合があります。



ソース変更を行う際には、次のような点に注意してください。

  • ソース変更によりレジスタの使用状況が変わるため、意図しない箇所において、 それまで最適化されずに残っていたレジスタ転送が削除されたり、 逆に、最適化が効かなくなって冗長なレジスタ転送が残ったりする可能性があります。
  • テンポラリ変数を追加することにより、新たなレジスタ変数用レジスタが使用されるようになり、それに伴い、関数の入口/出口でそのレジスタの退避/復帰が追加されることがあります。この場合、退避/復帰のコード分(8バイト)だけコード・サイズが増加します。

 

 

適用製品

V850用コンパイラパッケージ [CA850]
他にご質問がございましたら、リクエストを送信してください