别名 - clang 优化器害怕什么?
Aliasing - what is the clang optimizer afraid of?
拿这个玩具代码(godbolt link):
int somefunc(const int&);
void nothing();
int f(int i) {
i = somefunc(i);
i++;
nothing();
i++;
nothing();
i++;
return i;
}
正如在 link 处的反汇编中所见,编译器从堆栈中重新加载 i
3 次,递增并存储回。
如果somefunc
被修改为按值接受int
,this doesn't happen.
(1) 优化器'afraid'是否因为somefunc
可以访问i
的地址,所以它可以间接修改它?你能举一个定义明确的代码的例子吗? (请记住,const_cast'离开和修改是未定义的行为)。
(2) 即使那是真的,我希望用 __attribute__((pure))
装饰 somefunc
会停止这种悲观情绪。 It doesn't。为什么?
这些 llvm 是否遗漏了优化?
编辑:如果 somefunc
returns 无效,__attribute__((pure))
会按预期启动:
void somefunc(const int&) __attribute__((pure));
void nothing();
int f(int i) {
somefunc(i);
i++;
nothing();
i++;
nothing();
i++;
return i;
}
也许这个属性有点不成熟(在实践中很少见)。
如评论中所述,使用 const_cast
删除对定义为非常量的对象的引用的常量性是明确定义的。事实上,这是它唯一真正的用途。
至于__attribute__((pure))
:谁知道呢。 nothing()
电话是重现这种情况所必需的;如果那些被标记为 pure
那么适当的优化就完成了; somefunc
的调用对这种情况没有太大影响。基本上,除非代码块中的 everything 是纯的,否则编译器往往会非常保守。虽然可以说它应该能够推断出 nothing()
不会影响 i
,但这是一个非常“尽力而为”的优化领域,而不是正确优化代码应该依赖的东西。
拿这个玩具代码(godbolt link):
int somefunc(const int&);
void nothing();
int f(int i) {
i = somefunc(i);
i++;
nothing();
i++;
nothing();
i++;
return i;
}
正如在 link 处的反汇编中所见,编译器从堆栈中重新加载 i
3 次,递增并存储回。
如果somefunc
被修改为按值接受int
,this doesn't happen.
(1) 优化器'afraid'是否因为somefunc
可以访问i
的地址,所以它可以间接修改它?你能举一个定义明确的代码的例子吗? (请记住,const_cast'离开和修改是未定义的行为)。
(2) 即使那是真的,我希望用 __attribute__((pure))
装饰 somefunc
会停止这种悲观情绪。 It doesn't。为什么?
这些 llvm 是否遗漏了优化?
编辑:如果 somefunc
returns 无效,__attribute__((pure))
会按预期启动:
void somefunc(const int&) __attribute__((pure));
void nothing();
int f(int i) {
somefunc(i);
i++;
nothing();
i++;
nothing();
i++;
return i;
}
也许这个属性有点不成熟(在实践中很少见)。
如评论中所述,使用 const_cast
删除对定义为非常量的对象的引用的常量性是明确定义的。事实上,这是它唯一真正的用途。
至于__attribute__((pure))
:谁知道呢。 nothing()
电话是重现这种情况所必需的;如果那些被标记为 pure
那么适当的优化就完成了; somefunc
的调用对这种情况没有太大影响。基本上,除非代码块中的 everything 是纯的,否则编译器往往会非常保守。虽然可以说它应该能够推断出 nothing()
不会影响 i
,但这是一个非常“尽力而为”的优化领域,而不是正确优化代码应该依赖的东西。