Renesas Synergy™

FAQ 1008038 : switch 文の代わりに if-else 文を使う記述例は?

回答

CA850は switch 文に対して、caseラベルの個数が4個以上でかつラベルの値の下限と上限の差が case の数の3倍までであれば、テーブル分岐形式のコードを生成します。
この場合、case の数がおよそ16個以下 (ただし、この数はswitchの式の形式やラベルの値の分布によって異なる) ならば、 等価な if-else 文に変更し、比較命令と分岐命令のならびにした方が、 コード・サイズが小さくなります。
なお、switch の式が外部変数参照や複雑な式の場合は、いったんテンポラリに値を代入して、 if の式ではそのテンポラリを参照するように変更する必要があります。


※以下の例では x は auto 変数であるものとします。

 

変更前   変更後 (22byte減 ※)
    switch(x) {
        case VAL0:
            return(RETVAL0);
        case VAL1:
            return(RETVAL1);
        case VAL2:
            return(RETVAL2);
        case VAL3:
            return(RETVAL3);
        case VAL4:
            return(RETVAL4);
        case VAL5:
            return(RETVAL5);
    }
    if (x == VAL0)
        return(RETVAL0);
    else if (x == VAL1)
        return(RETVAL1);
    else if (x == VAL2)
        return(RETVAL2);
    else if (x == VAL3)
        return(RETVAL3);
    else if (x == VAL4)
        return(RETVAL4);
    else if (x == VAL5)
        return(RETVAL5);


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



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



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

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

CA850 V2.40以上では、-Xcaseオプションにより、switch文の展開コードを指定することが可能です。

-Xcase=ifelse case文のならびに沿ったif-else文と同じ形で出力します。
-Xcase=binary バイナリサーチ形式で出力します。
-Xcase=table テーブルジャンプ方式で出力します。

 

適用製品

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