5

特定のC/C ++機能がどのようにアセンブリに変換されたかを調べたいと思い、次のファイルを作成しました。

struct foo {
    int x;
    char y[0];
};

char *bar(struct foo *f)
{
    return f->y;
}

次に、これをでコンパイルしましたgcc -S(そして、で試しました)が、アセンブリコードを見ると、最適化できるはずだg++ -Sと思っていたbar関数の些細な冗長性を見つけてがっかりしました。gcc

_bar:
Leh_func_begin1:
        pushq   %rbp
Ltmp0:
        movq    %rsp, %rbp
Ltmp1:
        movq    %rdi, -8(%rbp)
        movq    -8(%rbp), %rax
        movabsq $4, %rcx
        addq    %rcx, %rax
        movq    %rax, -24(%rbp)
        movq    -24(%rbp), %rax
        movq    %rax, -16(%rbp)
        movq    -16(%rbp), %rax
        popq    %rbp
        ret
Leh_func_end1:

とりわけ、ライン

        movq    %rax, -24(%rbp)
        movq    -24(%rbp), %rax
        movq    %rax, -16(%rbp)
        movq    -16(%rbp), %rax

無意味に冗長に見えます。gcc(およびおそらく他のコンパイラ)がこれを最適化できない/しない理由はありますか?

4

2 に答える 2

11

gcc は最適化できるはずだと思いました。

gccマニュアルから:

最適化オプションがない場合、コンパイラの目標は、コンパイルのコストを削減し、デバッグで期待される結果を生成することです。

つまり、要求しない限り最適化されません。フラグを使用して最適化を有効にすると-O3、gcc 4.4.6 はより効率的なコードを生成します。

bar:
.LFB0:
        .cfi_startproc
        leaq    4(%rdi), %rax
        ret
        .cfi_endproc

詳細については、マニュアルの最適化を制御するオプションを参照してください。

于 2012-05-19T06:49:44.760 に答える
8

コンパイラが最適化なしで生成するコードは、通常、命令ごとの単純な変換であり、命令はプログラムの命令ではなく、冗長性が導入された可能性のある中間表現の命令です。

そのような冗長な指示なしで組み立てることが期待される場合は、gcc -O -S

あなたが期待していた最適化の種類は、ピープホール最適化と呼ばれます。コンパイラには通常、これらがたくさんあります。これは、よりグローバルな最適化とは異なり、適用するのが安価であり、(一般に) 少なくともコンパイルの最後に適用された場合、コードを悪化させるリスクがないためです。

このブログ投稿では、ソース コードの整数型が 64 ビットであるが、結果の最下位 32 ビットのみが重要である場合に、GCC と Clang の両方がより短い 32 ビット命令を生成する可能性がある例を提供します。

于 2012-05-19T06:49:42.180 に答える