Compilation 强制函数在Clang/LLVM中内联

Compilation 强制函数在Clang/LLVM中内联,compilation,clang,llvm,inline,Compilation,Clang,Llvm,Inline,有没有办法在Clang/LLVM中强制使用内联函数 好吧,下面只是对编译器的一个提示,但它可以忽略请求 __attribute__((always_inline)) 如果编译不能内联函数,我不介意编译会失败。我将把你的问题看作是在Clang/LLVM框架中询问任何工具。我的建议是:将代码编译为LLVM位代码,然后运行 例如: > clang <other CFLAGS> -emit-llvm -c -o foo.bc foo.c > opt -always-inline

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

好吧,下面只是对编译器的一个提示,但它可以忽略请求

__attribute__((always_inline))

如果编译不能内联函数,我不介意编译会失败。

我将把你的问题看作是在Clang/LLVM框架中询问任何工具。我的建议是:将代码编译为LLVM位代码,然后运行

例如:

> 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
>clang-emit llvm-c-o foo.bc foo.c
>opt-始终内联foo.bc-o foo_inline.bc
>clang-c-o foo.o foo_inline.bc

我以前使用过这个序列,它已经内联了所有标记为“always_inline”的函数。在我的例子中,我已经在对比特码进行其他分析和转换,所以我只需将标志添加到opt。

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

inline void foo() {} 
这本书写得很好:

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

在C99中,内联意味着函数的定义仅用于内联,并且在程序中的其他地方还有另一个定义(没有内联)。这意味着这个程序是不完整的,因为如果add不是内联的(例如,在没有优化的情况下编译时),那么main将有一个对其他定义的未解析引用。因此,我们将得到一个(正确的)链接时间错误

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

因此,为了保证函数是内联的:

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

  • 蛮力方法只是把它变成一个宏。

    只是一些可能有用的注释

    关于OP的评论:

  • 多个
    静态内联
    定义是一个警告,因为在更改其中一个定义时,它可能会导致多个不同的函数,这些函数可能会引起很多麻烦,特别是当内联开始时,实际调用会蒸发到不同的语句序列中
  • 这可能具有与1类似的效果
  • 内联是一种优化,您可以查看编译器手册,查看它何时开始使用(例如)。通常,它是在第一级。另见答案
  • 可以找到有用的讨论和建议。 C99的建议总结如下:

  • 在头文件中定义以下内容,并将其包含在需要的任何位置:

    inline void foo(){/*…*/}

  • 在单个源文件中,使用
    extern
    声明它以生成外部符号:

    extern inline foo()

  • 至于所提出的LLVM IR方法,它可以工作,但随后您将被传递到源语言域,并受制于一组不同的规则(高度依赖于该工具)。
    可以找到一个简短的指示性讨论。

    您可以从尝试以下内容开始: 叮当声-mllvm-内联阈值=n

    参数n越大,内联的强度就越大。 默认值为225,因此将其设置为更大的值。希望代码大,并且 编译时间长,内联非常复杂。当你击中目标时 您可以尝试分析代码并查看 对于经常调用但未联机的函数,请尝试使用 属性((始终为内联))以获得更多内联

    如果您有标记为“inline”的函数,您还可以使用 -inlinehint阈值大于-inline阈值,并查看 改变一切

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


    **取自

    它与always_inline属性有何不同?将此标志与opt一起使用时是否保证内联?或者这只是一个提示?opt命令告诉它在LLVM IR上运行始终内联的转换过程。此过程将遍历IR并找到所有具有always_inline属性的函数并将其内联。查看源代码-,注释表明它应该内联所有标记为always_inline并且可以这样做的内容。您可以编写一个pass,如果它发现对标记为“always_inline”的函数的任何调用,它将失败。不要使用
    静态inline
    ?我猜这样你会得到clang中的链接错误(因为它的默认行为是c99),如果它不能内联(并且函数没有声明为静态),它可能会链接失败。但这就是我在问题中所写的意图:“如果不能内联函数,我不介意编译会失败”;你完全回答了你的问题。然而,您的需求有点奇怪:-)这并不奇怪,我想确定它是内联的(出于某些安全原因)。如果不能,我想知道。好了,没有其他方法可以做到这一点。当被否决时,我希望得到一些建设性的反馈/建议等。如果你真的需要跨平台兼容性,这可能是唯一可行的方法。