如何知道是否可以在LLVM中间接调用函数?

时间:2020-07-07 15:52:28

标签: llvm llvm-ir

函数是否有一个属性,指示它们不会被间接调用?

我正在进行过程间分析,如果我知道仅直接调用哪些函数(我将静态知道它们从何处调用以及在何处返回),则可以大大改善。到目前为止,我还不知道如何获取该信息,因此我不得不将每个函数都当作可以从任何地方调用的方式对待(就优化而言,这真是令人毛骨悚然!)。

我认为LLVM已经具有这种机制,但是如果没有,我可以计算出来吗?我了解,通常无法知道是否将间接调用函数。但是,有没有我可以找到的功能?我想大多数地方职能都属于这个家庭。我还可以想象LLVM在内联函数时已经执行了此操作,然后删除了它的定义。


我发现unnamed_addr似乎相关。但据我所知,仅说函数的地址并不重要,但仍可以使用别名,在运行时将其传递给其他函数并间接调用。这是正确的读物吗?


我正在研究LLVM 9.0,以防万一,但是我仍然对其他版本中的解决方案感兴趣。

2 个答案:

答案 0 :(得分:1)

您可以信任通过internal链接对函数进行的分析。为了改善性能,您可以将通行证插入LTO管道,并与启用LTO的链接器一起使用。这样会将您从翻译单元通过的“可见性”扩展到整个生成的二进制文件。

答案 1 :(得分:1)

由于您尚未指定要在其上运行分析的程序的语言,因此我假设您正在使用C。

否,LLVM没有这样的功能。确切确定仅直接调用函数foo()的唯一方法是执行流敏感分析。生成的调用图指出了所有间接调用的函数。这样,您可以将这些功能从相应的llvm::Module对象的所有功能集中排除。

但是,您可能知道是否要进行过程间分析,所以对流量敏感的分析并不容易,并且无法很好地应用于大型项目。如果您的主要重点是查找精确匹配,那么您可以采用流敏感算法。

如果要近似可以直接调用的函数,则可以在不使用流敏感算法的情况下(即仅使用上下文敏感或在某些情况下 field-sensitive 方法。这些方法的实现较为简单,但存在更多的误差。

但是,仅依靠LLVM的功能属性并不能帮助您解决问题,至少不是对于所有程序而言。