函数参数的 LLVM 过程间分析

LLVM Inter-procedural Analysis on function arguments

嗨,我有一些关于 LLVM 中的过程间分析的问题。

比如有一段代码如下:

void f1(int *a, int *b, int *c) {...}
void f2(int *a, int *b, int *c) {...}

int main() {
  int *a = malloc (...);
  int *b = malloc (...);
  int *c = malloc (...);
  int *d = malloc (...);
  int *e = malloc (...);

  f1(a, b, c);
  f2(c, d, e);

  return 0;
}

我想在属性或元数据中提供信息,即 f1 的第三个参数与 f2 的第一个参数相同。

但我不确定解决这个问题的方法。

我认为 Alias Analysis 可以为我指明方向,但它似乎与我正在尝试做的有点不同。

最简单的方法就是迭代函数参数并收集信息,但似乎一点也不安全。

任何建议都会有所帮助。

谢谢, 杰克

由于 LLVM IR 是一种 SSA 语言,这变得更简单。

你想要的是(在类 C 语言中)知道 c1b2f1(a1, b1, c2); f2(a2, b2, c3); 中是否相同,对吗?当您将其转换为 SSA 形式时,在 LLVM IR 中,这将是两个 call 指令,可能是 call @f1, %a1, %b1, %c1call @f2, %a2, %b2, %c2。与类 C 源代码不同,%c1%b2 不是变量,它们是值。它们只被初始化一次(SSA 表示静态单一赋值),因此检查 %a3%b2 是否相等只需要查看两个定义并测试是否相等。如果是,您调用 a3.replaceAllUsesWith(b2) 就完成了。

不过,测试相等性可能比听起来更棘手。例如,如果源语言中的两个值是 (unsigned int)(4+3)(signed int)(2+3+2),则 IR 看起来很相似,但大多数编译器不会生成完全相同的 IR。在您的上下文中,两种不同类型的值是否相等?如果值是 (signed byte)(127+127+2)(unsigned int)(256) 怎么办?

你是理智的还是多线程的——如果一个值被写入内存并立即读回(但可能在正确的纳秒内被另一个线程更改)怎么办?平等测试为迂腐提供了很多机会。

您会在 ConstantFolding.h 中找到一些有用的辅助函数,根据源语言的不同,在分析之前要求 mem2reg 传递是 运行 可能会有所帮助。祝你好运。