[英]How to provide an implementation of memcpy
I am trying to write some bare metal code with a memset
-style loop in it:我正在尝试编写一些带有
memset
样式循环的裸机代码:
for (int i = 0; i < N; ++i) {
arr[i] = 0;
}
It is compiled with GCC and GCC is smart enough to turn that into a call to memset()
.它是用 GCC 和 GCC 编译的,它足够聪明,可以将其转换为对
memset()
的调用。 Unfortunately because it's bare metal I have no memset()
(normally in libc) so I get a link error.不幸的是,因为它是裸机,所以我没有
memset()
(通常在 libc 中),所以我收到链接错误。
undefined reference to `memset'
It seems like the optimisation that does this transformation is -ftree-loop-distribute-patterns
:似乎进行这种转换的优化是
-ftree-loop-distribute-patterns
:
Perform loop distribution of patterns that can be code generated with calls to a library.
执行模式的循环分布,这些模式可以通过调用库来生成代码。 This flag is enabled by default at -O2 and higher, and by
-fprofile-use
and-fauto-profile
.默认情况下,此标志在 -O2 及更高版本以及
-fprofile-use
和-fauto-profile
。
So one person's solution was to just lower the optimisation level.所以一个人的解决方案是降低优化级别。 Not very satisfying.
不是很满意。
I also found this really helpful page that explains that -ffreestanding
is not enough to get GCC not to do this, and there's basically no option but to provide your own implementations of memcpy
, memmove
, memset
and memcmp
.我还发现这个非常有用的页面解释了
-ffreestanding
不足以让 GCC 不这样做,而且基本上别无选择,只能提供自己的memcpy
、 memmove
、 memset
和memcmp
实现。 I'm happy to do that, but how?我很高兴这样做,但是怎么做呢?
If I just write memset
the compiler will detect the loop inside it and transform it into a call to memset: In fact in the code provided by the CPU vendor I'm using I actually found this comment:如果我只是编写
memset
,编译器将检测其中的循环并将其转换为对 memset 的调用: 事实上,在我正在使用的 CPU 供应商提供的代码中,我实际上发现了以下注释:
/*
// This is commented out because the assembly code that the compiler generates appears to be
// wrong. The code would recursively call the memset function and eventually overruns the
// stack space.
void * memset(void *dest, int ch, size_t count)
...
So I assume that is the issue they ran into.所以我认为这是他们遇到的问题。
How do I supply a C implementation of memset
without the compiler optimising it to a call to itself and without disabling that optimisation?如何提供
memset
的 C 实现,而不需要编译器将其优化为对自身的调用并且不禁用该优化?
Aha I checked inthe glibc code and there's a inhibit_loop_to_libcall
modifier which sounds like it should do this.啊哈,我检查了 glibc 代码,并且有一个
inhibit_loop_to_libcall
修饰符,听起来它应该这样做。 It is defined like this :它是这样定义的:
/* Add the compiler optimization to inhibit loop transformation to library
calls. This is used to avoid recursive calls in memset and memmove
default implementations. */
#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
# define inhibit_loop_to_libcall \
__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
#else
# define inhibit_loop_to_libcall
#endif
You mention in your question:您在问题中提到:
It seems like the optimisation that does this transformation is
-ftree-loop-distribute-patterns
似乎进行这种转换的优化是
-ftree-loop-distribute-patterns
all you need to do to turn off this optimization is pass -fno-tree-loop-distribute-patterns
to the compiler.关闭此优化所需要做的就是将
-fno-tree-loop-distribute-patterns
传递给编译器。 This turns off the optimization globally.这将关闭全局优化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.