2012-01-17 6 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 코드의이 조각은 루프에서 실행하는 경우 조건이 전달되는 경우 때문에, 다음은이 때마다 (점프 가정하자 한 번만). 다른 컴파일러 설정이 실제로 코드를 예상대로 생성합니까?

답변

6

당신이 쓴 : 그것은 상관없이 당신이있어 내장 무엇 foo의 값을 if(0)에 해당하지 if(foo,0)에 둘러싸여 있기 때문에

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

중괄호 안에있는 코드 것은 결코이 실행됩니다 사용하려고합니다. -O2을 사용하여 최적화를 켜면 컴파일러가 주위를 점프하는 대신 완전히 죽은 코드를 제거한다는 것을 알 수 있습니다. 내가 이렇게하면, 나는 (clang -O1 이상으로) 기대 정확히 앞으로 분기를 얻을 당신은 아마

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

를 작성하는 의미 생각합니다.

_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 
: 여기
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의 코드입니다
관련 문제