AnA*_*ons 8 c optimization assembly gcc clang
我已经尝试用Clang和GCC编译这段代码:
struct s { int _[50]; };
void (*pF)(const struct s), (*pF1)(struct s), (*pF2)(struct s *);
main()
{
struct s a;
pF2(&a);
pF(a), pF1(a);
}
Run Code Online (Sandbox Code Playgroud)
结果是一样的.虽然pF不允许调用来修改其唯一的参数,但是a为第二次调用复制了该对象pF1.为什么是这样?
这是装配输出(来自GCC):
; main
push rbx
sub rsp, 0D0h
mov rbx, rsp
mov rdi, rsp
call cs:pF2
;create argument for pF1 call (as there the argument is modified)
;and copy the local a into it
;although it seems not needed because the local isn't futher read anyway
sub rsp, 0D0h
mov rsi, rbx
mov ecx, 19h
mov rdi, rsp
;
rep movsq
call cs:pF
;copy the local a into the argument created once again
;though the argument cannot be modified by the function pointed by pF
mov rdi, rsp
mov rsi, rbx
mov ecx, 19h
rep movsq
;
call cs:pF1
add rsp, 1A0h
xor eax, eax
pop rbx
retn
Run Code Online (Sandbox Code Playgroud)
优化器无法看到,因为指向的函数pF无法修改其参数(因为它已声明const),因此省略了上次复制操作?另外,最近我看到,由于a代码中没有进一步读取变量,它可以将其存储用于函数参数.
相同的代码可以写成:
; main
push rbx
sub rsp, 0D0h
mov rdi, rsp
call cs:pF2
call cs:pF
call cs:pF1
add rsp, 0D0h
xor eax, eax
pop rbx
retn
Run Code Online (Sandbox Code Playgroud)
我正在用-O3旗帜编译.我错过了什么吗?
即使我没有调用UB(默认情况下是函数指针NULL),它也是一样的,而我将它们初始化为:
#include <stdio.h>
struct s { int _[50]; };
extern void f2(struct s *a);
void (*pF)(const struct s), (*pF1)(struct s), (*pF2)(struct s *) = f2;
extern void f1(struct s a)
{
a._[2] = 90;
}
extern void f(const struct s a)
{
for(size_t i = 0; i < sizeof(a._)/sizeof(a._[0]); ++i)
printf("%d\n", a._[i]);
}
extern void f2(struct s *a)
{
a->_[6] = 90;
pF1 = f1, pF = f;
}
Run Code Online (Sandbox Code Playgroud)
我不认为这种优化是合法的。您忽略的是带有 const 参数的函数类型与带有非常量参数的函数类型兼容,因此改变其参数的函数可能会被分配给指针pF。
这是一个示例程序:
struct s {
int x;
};
/* Black hole so that DCE doesn't eat everything */
void observe(void *);
void (*pF)(const struct s);
void test(struct s arg) {
arg.x = 0;
observe(&arg);
}
void assignment(void) {
pF = test;
}
Run Code Online (Sandbox Code Playgroud)
最重要的是,参数的 const 注释无法为编译器提供有关参数存储是否被被调用者改变的可靠信息。执行此优化似乎要求 ABI 要求参数存储不被改变(或某种整体程序分析,但不用介意)。
| 归档时间: |
|
| 查看次数: |
191 次 |
| 最近记录: |