7
レジスタに渡されるのは、自明ではないコピー・ctorと重要でないdtorのない小さな構造体です。 ARM Procedural Call Standardを引用値で簡単な構造体を渡すときにgccが不要なメモリアクセスを発行するのはなぜですか?
:32ビットよりも大きい
基本タイプがパラメータとして渡される、または関数呼び出しの結果として返されてもよいです。 これらのタイプがコアレジスタにある場合、次のルールが適用されます。 ダブルワードサイズのタイプは、2つの連続するレジスタ(たとえばr0とr1、またはr2とr3)に渡されます。 の内容は、値が単一のLDM命令でメモリ表現からロードされたかのようです。
実際、これはclangで簡単に確認できます。 GCCは、しかし、そのような単純なコードスニペットのためのメモリ・ロードとストアの束を発する:
struct Trivial {
int i1;
int i2;
};
int foo(Trivial t)
{
return t.i1 + t.i2;
}
$ clang++ arm.cpp -O2 -mabi=aapcs -c -S && cat arm.s
add r0, r0, r1
bx lr
$ g++ arm.cpp -O2 -mabi=aapcs -c -S && cat arm.s
sub sp, sp, #8
add r3, sp, #8
stmdb r3, {r0, r1}
ldmia sp, {r0, r3}
add r0, r0, r3
add sp, sp, #8
bx lr
Iが実行中、ArchlinuxARMディストリビューションによって供給されるGCCと打ち鳴らすを使用していラズベリー・パイ2(gcc 5.2)でも、gccベースのクロス・コンパイラでも再現しました。
「-O3」でもう一度試してください –
gccの_missed optimization_ typeバグのようなものです。 @MM FYI、それは '-O3'と同じです – Jester
これは少し残念です...私はそれがそれよりもうまくいくと予想しました。 –