数组初始化优化
Array initialization optimization
编译以下代码片段时(clang x86-64 -O3
)
std::array<int, 5> test()
{
std::array<int, 5> values {{0, 1, 2, 3, 4}};
return values;
}
It produced 我期望的典型程序集
test(): # @test()
mov rax, rdi
mov ecx, dword ptr [rip + .L__const.test().values+16]
mov dword ptr [rdi + 16], ecx
movups xmm0, xmmword ptr [rip + .L__const.test().values]
movups xmmword ptr [rdi], xmm0
ret
.L__const.test().values:
.long 0 # 0x0
.long 1 # 0x1
.long 2 # 0x2
.long 3 # 0x3
.long 4 # 0x4
不过对于小数组,好像想出了一个窍门?
std::array<int, 3> test()
{
std::array<int, 3> values {{0, 1, 2}};
return values;
}
This是对应的程序集
test(): # @test()
movabs rax, 4294967296
mov edx, 2
ret
那个神奇的数字 (4294967296
) 是从哪里来的?这本质上是一个可以 reinterpret_cast
以某种方式返回到 int
数组的值吗?
A std::array<int, 3>
在您的实现中是 96 位宽。因此,ABI 声明它应该在 RAX + RDX(又名 EDX)的低 32 位中返回。
4294967296 是 232,十六进制是 '0000'0000
。所以movabs
在RAX的低32位存0,在RAX的高32位存1。 mov
在 EDX 中存储 2(这正是您想要的)。
编译以下代码片段时(clang x86-64 -O3
)
std::array<int, 5> test()
{
std::array<int, 5> values {{0, 1, 2, 3, 4}};
return values;
}
It produced 我期望的典型程序集
test(): # @test()
mov rax, rdi
mov ecx, dword ptr [rip + .L__const.test().values+16]
mov dword ptr [rdi + 16], ecx
movups xmm0, xmmword ptr [rip + .L__const.test().values]
movups xmmword ptr [rdi], xmm0
ret
.L__const.test().values:
.long 0 # 0x0
.long 1 # 0x1
.long 2 # 0x2
.long 3 # 0x3
.long 4 # 0x4
不过对于小数组,好像想出了一个窍门?
std::array<int, 3> test()
{
std::array<int, 3> values {{0, 1, 2}};
return values;
}
This是对应的程序集
test(): # @test()
movabs rax, 4294967296
mov edx, 2
ret
那个神奇的数字 (4294967296
) 是从哪里来的?这本质上是一个可以 reinterpret_cast
以某种方式返回到 int
数组的值吗?
A std::array<int, 3>
在您的实现中是 96 位宽。因此,ABI 声明它应该在 RAX + RDX(又名 EDX)的低 32 位中返回。
4294967296 是 232,十六进制是 '0000'0000
。所以movabs
在RAX的低32位存0,在RAX的高32位存1。 mov
在 EDX 中存储 2(这正是您想要的)。