toge's diary

コンピュータ関連の趣味をつらつらと。

GCCの最適化

id:isshiki:20060822:p1 より触発されてやってみる。

"gcc -S"ではなく、shinichiro.hさんのrelocation @amd64で覚えた"objdump -Sr"を使ってみました。等幅フォントで見てね。

"gcc-3.3.6 -O2", "gcc-3.3.6 -O3", "gcc-3.4.6 -O2", "gcc-3.4.6 -O3"の結果は、多少アドレスの違いはあるものの本質的に一緒。

int loop_function_inc(void)
{
 8048450:       55                      push   %ebp
 8048451:       b8 db 41 0f 00          mov    $0xf41db,%eax
 8048456:       89 e5                   mov    %esp,%ebp
 8048458:       90                      nop
 8048459:       8d b4 26 00 00 00 00    lea    0x0(%esi),%esi
 8048460:       48                      dec    %eax
 8048461:       79 fd                   jns    8048460 <_Z17loop_function_incv+0x10>
    int i, ret = 0;

    for( i = loop_min; i < loop_max; i++){
        ret++;
    }

    return ret;
}
 8048463:       5d                      pop    %ebp
 8048464:       b8 dc 41 0f 00          mov    $0xf41dc,%eax
 8048469:       c3                      ret
 804846a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

int loop_function_dec(void)
{
 8048470:       55                      push   %ebp
    int i, ret = 0;

    for( i = loop_max; i > loop_min; i--){
 8048471:       b8 40 42 0f 00          mov    $0xf4240,%eax
 8048476:       89 e5                   mov    %esp,%ebp
 8048478:       90                      nop
 8048479:       8d b4 26 00 00 00 00    lea    0x0(%esi),%esi
 8048480:       48                      dec    %eax
 8048481:       83 f8 64                cmp    $0x64,%eax
 8048484:       7f fa                   jg     8048480 <_Z17loop_function_decv+0x10>
        ret++;
    }

    return ret;
}
 8048486:       5d                      pop    %ebp
 8048487:       b8 dc 41 0f 00          mov    $0xf41dc,%eax
 804848c:       c3                      ret
 804848d:       90                      nop
 804848e:       89 f6                   mov    %esi,%esi 

"gcc-4.0.3 -O2", "gcc-4.0.3 -O3"ではなんか微妙に退化しているように見える。

int loop_function_inc(void)
 8048440:       55                      push   %ebp
 8048441:       31 c0                   xor    %eax,%eax
 8048443:       89 e5                   mov    %esp,%ebp
 8048445:       8d 74 26 00             lea    0x0(%esi),%esi
 8048449:       8d bc 27 00 00 00 00    lea    0x0(%edi),%edi
{
    int i, ret = 0;

    for( i = loop_min; i < loop_max; i++){
        ret++;
 8048450:       40                      inc    %eax
 8048451:       3d dc 41 0f 00          cmp    $0xf41dc,%eax
 8048456:       75 f8                   jne    8048450 <_Z17loop_function_incv+0x10>
    }

    return ret;
}
 8048458:       5d                      pop    %ebp
 8048459:       c3                      ret
 804845a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

int loop_function_dec(void)
 8048460:       55                      push   %ebp
 8048461:       31 c0                   xor    %eax,%eax
 8048463:       89 e5                   mov    %esp,%ebp
 8048465:       8d 74 26 00             lea    0x0(%esi),%esi
 8048469:       8d bc 27 00 00 00 00    lea    0x0(%edi),%edi
{
    int i, ret = 0;

    for( i = loop_max; i > loop_min; i--){
        ret++;
 8048470:       40                      inc    %eax
 8048471:       3d dc 41 0f 00          cmp    $0xf41dc,%eax
 8048476:       75 f8                   jne    8048470 <_Z17loop_function_decv+0x10>
    }

    return ret;
}
 8048478:       5d                      pop    %ebp
 8048479:       c3                      ret
 804847a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi 

で、真打のgcc4.1.1ではやっとこさこっちの望んだ回答を得られる。

int loop_function_inc(void)
 8048440:       55                      push   %ebp
{
    int i, ret = 0;

    for( i = loop_min; i < loop_max; i++){
        ret++;
    }

    return ret;
}
 8048441:       b8 dc 41 0f 00          mov    $0xf41dc,%eax
 8048446:       89 e5                   mov    %esp,%ebp
 8048448:       5d                      pop    %ebp
 8048449:       c3                      ret
 804844a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

08048450 <_Z17loop_function_decv>:

int loop_function_dec(void)
 8048450:       55                      push   %ebp
{
    int i, ret = 0;

    for( i = loop_max; i > loop_min; i--){
        ret++;
    }

    return ret;
}
 8048451:       b8 dc 41 0f 00          mov    $0xf41dc,%eax
 8048456:       89 e5                   mov    %esp,%ebp
 8048458:       5d                      pop    %ebp
 8048459:       c3                      ret
 804845a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi 

ということでgcc-4.1.1万歳。
ただし、どのバージョンでも、"-O3"を指定するとmain関数の中にそれぞれの関数の戻り値が埋め込まれて、この関数達は呼ばれなくなり、何の意味もない最適化になっちゃうわけですけど。