clang 忽略属性 noinline
Posted
技术标签:
【中文标题】clang 忽略属性 noinline【英文标题】:clang ignoring attribute noinline 【发布时间】:2019-02-01 14:50:53 【问题描述】:我希望 __attribute__((noinline))
在添加到函数时确保该函数被发出。这适用于 gcc,但 clang 似乎仍然内联它。
这里是一个例子,你也可以open on Godbolt:
namespace
__attribute__((noinline))
int inner_noinline()
return 3;
int inner_inline()
return 4;
int outer()
return inner_noinline() + inner_inline();
int main()
return outer();
使用-O3
构建时,gcc 会发出inner_noinline
,但不会发出inner_inline
:
(anonymous namespace)::inner_noinline():
mov eax, 3
ret
main:
call (anonymous namespace)::inner_noinline()
add eax, 4
ret
Clang 坚持内联它:
main: # @main
mov eax, 7
ret
如果向函数添加参数并让它们执行一些琐碎的工作,clang 尊重 noinline 属性:https://godbolt.org/z/NNSVab
noinline 不应该独立于函数的复杂程度吗?我错过了什么?
【问题讨论】:
clang 是否支持noinline
属性?
list of attributes中没有自己的分类,但是如果你在那里搜索noinline,你会发现它被多次提及。
另外,查看带有参数的版本,如果我在那里删除它,这两个函数都是内联的。所以 clang 似乎至少知道这一点。
相关:github.com/emscripten-core/emscripten/issues/3409
【参考方案1】:
__attribute__((noinline))
阻止编译器内联函数。它不会阻止它进行不断的折叠。在这种情况下,编译器能够识别出不需要调用inner_noinline
,无论是作为内联插入还是外联调用。它可以将函数调用替换为常量3
。
听起来您想改用optnone
属性,以防止编译器应用最明显的优化(就像这个优化一样)。
【讨论】:
这和@YSC 的评论是有道理的。有趣的是,clang 和 gcc 似乎对什么是内联有不同的看法。以上是关于clang 忽略属性 noinline的主要内容,如果未能解决你的问题,请参考以下文章