【问题标题】:Identify whether a function is inlined in the LLVM IR识别函数是否在 LLVM IR 中内联
【发布时间】:2021-03-08 18:02:36
【问题描述】:

我们基于 LLVM IR 在编译时检测源代码。在这个过程中,我们希望跳过已经内联的函数(例如,由于编译时优化)。

我们如何确定一个函数是否已在 LLVM 传递中内联?

【问题讨论】:

  • 我认为您的问题不够具体,无法回答。您是否有一些函数 foo() 并想知道它是否已将 bar() 内联到其中?或者您是否有兴趣查看 bar() 是否可内联或在源代码中具有类似 inline 的属性?

标签: llvm


【解决方案1】:

这似乎相当模糊,有多种解释......

查看foo() 是否内联到bar() 的一种方法是循环遍历bar() 中的指令,并查看其中是否有call %foo 或类似的指令。如果是这种情况,那么至少有一个调用没有内联,即使其他调用可能已经内联。

另一种方法是查看调试信息。假设foo() 源自 foo.c 的第 10 到 20 行。您可以查看bar() 中所有指令的调试信息,并检查是否有参考 foo.c 的第 10-20 行。如果有的话,那么至少有一个调用被内联了,即使其他的没有。

我至少还能想到另外两种方法,而且我敢肯定还有更多。 (编辑:我能想到三个,包括一个非常好的方法:在编译早期将一些独特的元数据附加到 foo() 中的说明中,然后查看在本机代码生成之前找到该元数据的位置。)

【讨论】:

  • 谢谢。但是,间接调用可能会导致函数没有直接调用者,但它不是内联的。我们检查了.ll 文件中的元数据,但没有发现与函数内联相关的内容。
  • 任何人都可以定义和添加元数据,包括您。
  • 还有一点——如果你的分析检测不到调用关系,那么内联的分析也检测不到,所以在这种情况下,调用肯定不是内联的。
【解决方案2】:

嗯,我们逐渐注意到,“内联”操作是针对具体的调用站点,而不是被调用函数。因此,一个函数可能没有“内联”属性。对于每个函数,它可能在某些调用点被内联,但在其他调用点正常调用,因此我们不应在仪器传递中跳过它们。

【讨论】:

    猜你喜欢
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多