clang bpf:属性always_inline不起作用

问题描述 投票:0回答:1

我编写了一个BPF目标文件,其中包括一个部分和一个静态内联函数,其定义如下:

static inline __attribute__((always_inline)) bpf_call_func(...);
__section("entry") bpf_func(...); // called bpf_call_func

效果很好,当我使用 llvm-objdump 时,它显示

bpf_call_func
已经被内联了。

但是当我在同一个目标文件中定义另一个部分并调用

bpf_call_func

static inline __attribute__((always_inline)) bpf_call_func(...);
__section("entry") bpf_func(...); // called bpf_call_func
__section("entry2") bpf_func2(...); // called bpf_call_func

llvm-objdump 显示

bpf_call_func
没有内联到
bpf_func
bpf_func2
中。它只是在
.text
部分定义,
bpf_func
bpf_func2
使用
call
指令来调用
bpf_call_func

bpf_call_func
大约有 600 条指令。
bpf_func
bpf_func
大约有 250 条指令。

我查看了 gcc 手册,它说:

请注意,函数定义中的某些用法可能使其不适合内联替换。这些用法包括:可变参数函数、alloca 的使用、计算 goto 的使用(请参阅作为值的标签)、非局部 goto 的使用、嵌套函数的使用、setjmp 的使用、__builtin_longjmp 的使用以及 __builtin_return 或 __builtin_apply_args 的使用。当无法替换标记为内联的函数时,使用 -Winline 会发出警告,并给出失败的原因。

但我不知道哪个条件符合我的情况。

我想知道为什么当两个部分调用它时

bpf_call_func
不内联? 和
bpf_call_func
的指令编号有关系吗?

compiler-construction clang inline ebpf
1个回答
2
投票

据我所知,没有办法真正强制 clang 内联函数,这是 clang 的always_inline 参考

内联启发法被禁用,并且无论优化级别如何,始终尝试内联。

不保证内联替换实际发生。

这似乎是一件铿锵的事情,因为GCC声明它将始终像属性建议的那样内联,或者抛出错误(对于单元内的调用):

始终内联

通常,除非指定优化,否则函数不会内联。对于声明为内联的函数,此属性内联函数独立于任何其他适用于内联的限制。未能内联此类函数将被诊断为错误。请注意,如果间接调用此类函数,编译器可能会或可能不会内联它,具体取决于优化级别,并且可能会或可能不会诊断内联间接调用的失败。

GCC 提供了一个

-Winline
标志,因此编译器会警告未内联的函数,但 clang 会忽略这一点:

-Winline

此诊断标志的存在是为了兼容 GCC,在 Clang 中没有任何作用。

因此,clang 似乎将always_inline 属性视为提示,并且很乐意在没有错误或警告的情况下不内联函数。在你的情况下,它可能决定你的内联函数太大。

公平地说,除非您需要支持低于 4.16 的内核,否则这并不重要,因为 eBPF 现在支持函数调用

© www.soinside.com 2019 - 2024. All rights reserved.