强制函数在Clang/LLVM中内联

Dav*_*idS 14 compilation inline llvm clang

有没有办法在Clang/LLVM中强制使用内联函数?

AFAIK,以下只是对编译器的一个提示,但它可以忽略该请求.

__attribute__((always_inline))
Run Code Online (Sandbox Code Playgroud)

我不介意如果它不能内联函数,编译将失败.

Dav*_*idS 14

如果使用C99进行编译是一个很好的解决方案,这是Clang的默认设置.它只是使用内联属性.

inline void foo() {} 
Run Code Online (Sandbox Code Playgroud)

它在Clang的兼容性页面中写得很好:

默认情况下,Clang根据C99标准构建C代码,该标准为内联关键字提供与GCC默认行为不同的语义...

在C99中,内联意味着函数的定义仅提供给内联,并且程序中的其他位置还有另一个定义(没有内联).这意味着该程序不完整,因为如果没有内联添加(例如,在没有优化的情况下进行编译),那么main将具有对该其他定义的未解析引用.因此,我们会得到(正确的)链接时错误...

GCC将其视为扩展,并将其视为优化器的提示.

所以为了保证函数内联:

  1. 不要使用静态内联.
  2. 不要为没有内联属性的函数添加其他实现.
  3. 您必须使用优化.但即使没有优化,编译也会失败,这是好的.
  4. 确保不要使用GNU89进行编译.

  • 它并不奇怪,我想知道它是内联的(出于某些安全原因).如果不能,我想知道.AFAIK,没有其他办法可以做到这一点. (3认同)

Bri*_*ian 6

我将把你的问题视为在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
Run Code Online (Sandbox Code Playgroud)

我之前使用过这个序列,它内联了所有标记为"always_inline"的函数.在我的情况下,我已经在bitcode上做了其他的分析和转换,所以我只需要添加标志来选择.


yeh*_*ahs 5

您可以从试验开始:clang -mllvm -inline-threshold=n

参数 n 越大,内联就越激进。默认值为 225,因此将其设置为更大的值。使用非常积极的内联,预计代码量大,编译时间长。当您达到收益递减点时,您可以尝试分析代码并查找经常调用但未内联的函数,并尝试使用属性((always_inline))标记它们以 进行更多内联。

如果您有标记为“内联”的函数,您还可以尝试使用比 -inline-threshold 大的 -inlinehint-threshold 并查看这是否会改变任何内容。

另外,您是否使用链接时优化进行编译?如果没有它们,内联仅限于单个编译单元。

**取自groups.google.com 论坛