0

GCC バージョン 4.2.4 を使用しています。以下で説明する問題は Gcc 4.6.x では再現できず、私がテストしたのはこれら 2 つのバージョンだけです。

列挙を定義するヘッダー ファイルがあります。ヘッダー: abc.h

enum test
{
    VALUE_1 = 1,
    VALUE_2 = 2,

    VALUE_MAX = 0xFFFF,
};

このヘッダーはいくつかのソース ファイルに含まれており、各ソース ファイルはコンパイル時にオブジェクト (.o) を作成します。また、abc.h の列挙を参照していないソース ファイルはほとんどありません。

私が見ている問題は、abc.h に新しい定数 (VALUE_3) を追加すると、列挙を使用しないオブジェクトのバイナリ md5sum も変更されることです。これは、最適化を適用した場合にのみ発生し、それ以外の場合はコンパイル時に発生しません。

最適化で有効になるフラグ -ftree-vrp および -ftree-dominator-opts と関係があると思われます。これらのフラグを -fno とともに使用すると、一部のオブジェクトが変更されますが、他のいくつかは変更されません (これらのフラグで変更されます)。

もう 1 つの興味深い観察結果は、偶数または奇数の列挙で md5sum が同じになることです。

バックエンドで何が起こっているのか、その特定のオブジェクトに実際のコード変更がない場合にバイナリ変更を回避して md5sum を維持する方法があることを誰かが理解できるようにしてください。

前もって感謝します。

編集:

1 つのオブジェクトの差分は次のとおりです。他のオブジェクトについては、他にもいくつかの変更があります (mov などの命令)。ご覧のとおり、一部の命令ではオペランド レジスタのみがスワップされています。その理由と、最適化でそれを回避する方法を理解したいです。

# diff test.o.1 test.o.2
1548,1549c1548,1549
<     cmpl    %eax, %ecx
<     jg      .L442
---
>     cmpl    %ecx, %eax
>     jl      .L442
4

1 に答える 1

1

バイナリ変更を回避する方法はありますか

Jonathon Reinhart の「分岐予測に関係している可能性がある」という疑いを確認するには、オプションを試すことができます-fno-guess-branch-probability

于 2015-02-18T10:51:13.567 に答える