0

Cortex-R4で実行されているCコードで最適化を行っています。まず、条件チェックで「__builtin_expect」を指定したとき、アセンブリ コードの出力に変化は見られませんでした。コンパイラが不要な Jump を生成しているようです。

私のCコード:

           bit ++; (Likely)

if(__builtin_expect(bit >= 32),0) 
{ 
  bit -=32; // unlikely code
  xxxxxx;   // unlikely code
  xxxxxx;   // unlikely code
  xxxxxx;   // unlikely code
} 

bit = bit*2 // something  (Likely)
return bit; 

---- 生成された ASM コード -------- (ビット => r0)

                      ADD   r2,r2,#1 
                      CMP   r0,#0x20 
                      BCC  NoDecrement 
                      SUB   r0,r0,#0x20 
                      XXXXXXXXX 
                      XXXXXXXXX 
                      XXXXXXXXX 
NoDecrement LSL   r0,r0,#1 
                          BX  lr 

---- 予想される ASM コード --------

                          ADD   r2,r2,#1 
                          CMP   r0,#0x20 
                          BHE   Decrement 
JumbBack       LSL   r0,r0,#1 
                          BX  lr 
Decrement      SUB   r0,r0,#0x20 
                          XXXXXXXXX 
                          XXXXXXXXX 
                          XXXXXXXXX 
                          B JumbBack

この C コードの一部がループで実行される場合、そのたびにジャンプする必要があるとします (if 条件が 1 回しか渡されないため)。実際に、期待どおりにコードを生成する他のコンパイラ設定はありますか..??

4

1 に答える 1

7

あなたが書いた:

if(__builtin_expect(bit >= 32),0)
{
    ...
}

中括弧内のコードは、使用しようとしている組み込み関数に関係なく、for の任意の値に相当する which で囲まれているため、決して実行されません。で最適化を有効にすると、コンパイラがデッド コードを飛び回るのではなく、完全に削除することがわかります。たぶん書きたかったんだと思うif(foo,0)if(0)foo-O2

if (__builtin_expect(bit >= 32, 0)) {
    bit -= 32;
}

これを行うと、期待どおりの前方分岐が得られます (clang -O1以上)。

extern void something();
int foo(int bit)
{
    ++bit;
    if (__builtin_expect(bit >= 32, 0)) {
        bit -= 32;  // "Decrement"
        something();
    }
    bit = bit*2;
    something();
    return bit;
}

からのコードは次のclang -arch armv7 -O2 -Sとおりです。

_foo:
@ BB#0:
push    {r4, r7, lr}
adds    r4, r0, #1
add r7, sp, #4
cmp r4, #32
bge LBB0_2           // a forward branch for the unlikely case
LBB0_1:
lsls    r4, r4, #1
blx _something
mov r0, r4
pop {r4, r7, pc}
LBB0_2:                      // "Decrement"
sub.w   r4, r0, #31
blx _something
b   LBB0_1
于 2012-08-31T21:25:24.313 に答える