【发布时间】:2022-01-09 18:46:31
【问题描述】:
拿这个玩具代码(godbolt link):
int somefunc(const int&);
void nothing();
int f(int i) {
i = somefunc(i);
i++;
nothing();
i++;
nothing();
i++;
return i;
}
从链接的反汇编中可以看出,编译器从堆栈中重新加载i 3 次,递增并存储回来。
如果将somefunc 修改为按值接受int,则this doesn't happen。
(1) 优化器是否“害怕”因为somefunc 可以访问is 地址,它可以间接修改它?你能举一个定义明确的代码的例子吗? (记住 const_cast'ing 和修改是未定义的行为)。
(2) 即使这是真的,我希望用__attribute__((pure)) 装饰somefunc 会停止这种悲观情绪。 It doesn't。为什么?
这些 llvm 是否错过了优化?
编辑:如果somefunc 返回 void,__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'ing away实际上是 allowed 如果原始对象没有定义为 const -
如果你定义
somefuncinline 以便编译器看到它没有const_cast那么它将被优化。如果原始对象不是 const (不在您的示例中),该语言允许const_cast。如果不允许,则 const_cast 就不会出现在该语言中。 -
"(请记住 const_cast'ing 和修改是未定义的行为)" 这似乎是您问题的基础,它是不正确的。
const_cast存在于语言中,因为有有效的用途,可以在这里使用。 -
“转义分析”:
i通过somefunc转义(可以将其地址存储在全局变量中),因此可以被nothing使用(读/写)。该属性似乎对 gcc 有帮助,也许您可以向 llvm 报告错过的优化? -
@MarcGlisse 谢谢,我刚刚做了:github.com/llvm/llvm-project/issues/53102
标签: c++ clang llvm compiler-optimization