2012-01-17 12 views
0

Cortex-R4で動作するCコードで最適化を行っています。 まず、コンディションチェックで "__builtin_expect"を指定したときに、アセンブリコードの出力に変更が見られませんでした。 コンパイラが不要なジャンプを生成するようです。__builtin_expectを使用したARMの静的分岐予測は機能しません。

マイ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コードのこの部分は、ループで実行されている場合であれば条件が渡されるため、各時間は、それが(ジャンプしなければならないと仮定 1回だけ)。 実際には、期待どおりにコードを生成する他のコンパイラ設定はありますか?

答えて

6

あなたが書いた:fooの任意の値のif(0)に相当するif(foo,0)に囲まれているため、中括弧内の

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

コードがは、あなたがしているものを組み込みに関係なく、実行されません使用しようとしている。 -O2で最適化を有効にすると、コンパイラは、デッドコードをジャンプするのではなく、完全に削除することがわかります。私はあなたがおそらく私がこれを行う場合、私は私が(clang -O1以上に)期待する正確前方分岐を得る

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

を書くためのものだと思います。

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 
関連する問題