叮当忽略属性内联

clang ignoring attribute noinline

本文关键字:属性 叮当      更新时间:2023-10-16

我希望__attribute__((noinline))添加到函数时,确保该函数被发出。这适用于 gcc,但 clang 似乎仍然内联它。

这里有一个例子,你也可以在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 不应该独立于函数的复杂程度吗?我错过了什么?

__attribute__((noinline))阻止编译器内联函数。它不会阻止它不断折叠。在这种情况下,编译器能够认识到没有必要调用inner_noinline,无论是作为内联插入还是外联调用。它可以用常量3替换函数调用。

听起来您想改用 optnone 属性,以防止编译器应用最明显的优化(就像这个一样)。