有没有办法在Clang / LLVM中强制使用内联函数?
AFAIK,以下只是对编译器的提示,但它可以忽略该请求。
__attribute__((always_inline))
我不介意如果无法内联函数,编译将失败。
答案 0 :(得分:11)
如果使用C99进行编译是一个很好的解决方案,这是Clang的默认设置。 它只是使用内联属性。
inline void foo() {}
在Clang's compatibility page中写得很好:
默认情况下,Clang根据C99标准构建C代码,该标准为内联关键字提供与GCC默认行为不同的语义...
在C99中,内联意味着函数的定义仅用于内联,并且程序中的其他位置还有另一个定义(没有内联)。这意味着这个程序是不完整的,因为如果add没有内联(例如,在没有优化的情况下进行编译时),那么main将有一个未解析的对该另一个定义的引用。因此,我们会得到(正确的)链接时错误...
GCC将其视为扩展,并将其视为优化器的提示。
所以为了保证函数内联:
答案 1 :(得分:5)
我将把你的问题视为要求Clang / LLVM框架内的任何工具。以下是我的建议:将代码编译为LLVM bitcode,然后运行Always inline pass。
例如:
> clang <other CFLAGS> -emit-llvm -c -o foo.bc foo.c
> opt -always-inline foo.bc -o foo_inline.bc
> clang -c -o foo.o foo_inline.bc
我之前使用过此序列,并且内联了所有标记为&#34; always_inline&#34;的函数。在我的情况下,我已经在bitcode上做了其他的分析和转换,所以我只需要添加标志来选择。
答案 2 :(得分:2)
您可以从尝试开始: clang -mllvm -inline-threshold = n
参数n越大,内联越激烈。 默认值为225,因此将其设置为更大的值。期待大代码和 编译时间长,内联非常激进。当你击中 收益递减点,您可以尝试分析代码并查找 对于频繁调用但未内联的函数,并尝试使用它们进行标记 属性((always_inline))用于更多内联。
如果您有标记为“内联”的功能,您也可以进行试验 -inlinehint-threshold大于-inline-threshold,看看是否这样 改变一切。
另外,您是否正在使用链接时优化进行编译?没有他们 内联仅限于个别编译单元。
答案 3 :(得分:0)
只是一些可能有用的评论。
对于OP的评论:
static inline
定义是一个警告,因为在更改其中一个定义时,它可能会导致多个不同的函数,这些函数可能导致大量的头部划伤,尤其是在内联启动时实际的呼叫会蒸发到不同的陈述序列。可以找到有用的讨论和建议here。 对C99的建议总结如下:
在标题文件中定义以下内容并将其包含在需要的位置:
inline void foo() { /*...*/ }
在单个源文件中使用extern
声明它以生成外部符号:
extern inline foo();
至于所提出的LLVM IR方法,它可以工作,但是你会通过源语言域并遵守一组不同的规则(高度依赖于工具)。 可以找到简要的指示性讨论here。
答案 4 :(得分:-2)
蛮力方法只是把它变成一个宏。