作者:sdfdsafgafsdf | 来源:互联网 | 2022-10-15 19:13
如何解决《HowdoIstopGCCfromoptimizingthisbyte-for-bytecopyintoamemcpycall?》经验,为你挑选了1个好方法。
I have this code for memcpy
as part of my implementation of the standard C library which copies memory from src
to dest
one byte at a time:
void *memcpy(void *restrict dest, const void *restrict src, size_t len)
{
char *dp = (char *restrict)dest;
const char *sp = (const char *restrict)src;
while( len-- )
{
*dp++ = *sp++;
}
return dest;
}
With gcc -O2
, the code generated is reasonable:
memcpy:
.LFB0:
movq %rdi, %rax
testq %rdx, %rdx
je .L2
xorl %ecx, %ecx
.L3:
movzbl (%rsi,%rcx), %r8d
movb %r8b, (%rax,%rcx)
addq $1, %rcx
cmpq %rdx, %rcx
jne .L3
.L2:
ret
.LFE0:
但是,在处gcc -O3
,GCC将此天真的逐字节副本优化为memcpy
调用:
memcpy:
.LFB0:
testq %rdx, %rdx
je .L7
subq $8, %rsp
call memcpy
addq $8, %rsp
ret
.L7:
movq %rdi, %rax
ret
.LFE0:
这将不起作用(memcpy
无条件调用自身),并且会导致段错误。
我尝试过传递-fno-builtin-memcpy
和-fno-loop-optimizations
,并且发生相同的事情。
我正在使用GCC版本8.3.0:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-cros-linux-gnu/8.3.0/lto-wrapper
Target: x86_64-cros-linux-gnu
Configured with: ../configure --prefix=/usr/local --libdir=/usr/local/lib64 --build=x86_64-cros-linux-gnu --host=x86_64-cros-linux-gnu --target=x86_64-cros-linux-gnu --enable-checking=release --disable-multilib --enable-threads=posix --disable-bootstrap --disable-werror --disable-libmpx --enable-static --enable-shared --program-suffix=-8.3.0 --with-arch-64=x86-64
Thread model: posix
gcc version 8.3.0 (GCC)
如何禁用使副本转换为memcpy
呼叫的优化?
1> Antti Haapal..:
在这里似乎一件事就足够了:不用使用-fno-builtin-memcpy
use -fno-builtin
来编译single的翻译单元memcpy
!
另一种选择是通过-fno-tree-loop-distribute-patterns
; 尽管这可能很脆弱,因为它禁止编译器先重新组织循环代码,然后再用对mem*
函数的调用来替换其中的一部分。
或者,由于您不能依赖C库中的任何内容,-ffreestanding
因此可以按顺序使用。