在函数中,我想知道参数如何传递到函数体中,以便跟踪参数的流动。我尝试了一个简单的代码,发现每个参数似乎都有alloc
- store
模式,我想知道它是否真实?
演示代码
int add(int x, int y){
return x+y;
}
它产生的llvm是:
; Function Attrs: nounwind uwtable
define i32 @add(i32 %x, i32 %y) #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 %x, i32* %1, align 4
store i32 %y, i32* %2, align 4
%3 = load i32, i32* %1, align 4
%4 = load i32, i32* %2, align 4
%5 = add nsw i32 %3, %4
ret i32 %5
}
在示例中我们可以看到,
对于每个参数,Clang使用alloc
指令来定义a
局部变量
遵循alloc
指令,我会使用store
条指令
分配值?
我的问题是:
alloc
和store
模式生成?或者LLVM究竟对参数做了什么? parameters
的顺序由其使用的惯例决定?答案 0 :(得分:1)
我认为这种模式适用于没有编译时优化的代码;但是,如果您使用-O3(或任何应用mem2reg优化的代码)编译代码,则此模式已经过优化:
(clang -emit-llvm -S -O0 add.c)
define i32 @add(i32 %x, i32 %y) #0 {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
store i32 %x, i32* %1, align 4
store i32 %y, i32* %2, align 4
%3 = load i32, i32* %1, align 4
%4 = load i32, i32* %2, align 4
%5 = add nsw i32 %3, %4
ret i32 %5
}
(opt -mem2reg add.ll -o add_m.ll)
define i32 @add(i32 %x, i32 %y) #0 {
%1 = add nsw i32 %y, %x
ret i32 %1
}
因此,如果您正在控制所分析的所有代码,那么您可以依赖此模式。我建议您使用LLVM API来获取函数参数。下面的代码遍历函数F的参数,并在转换为值后打印它们。
for (auto AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI)
{
Value* v = &*AI;
errs() << *v << "\n";
}
上述样本中的值可以与IR中任何其他值相同的方式使用。