我正在尝试使用LLVM C++ API编写编译器,并且正在尝试访问函数中的数组参数。
据我从clang的IR生成中得知,这两个代码具有不同的LLVM IR代码:
void foo(void) {
int a[2];
a[0] = 1;
// %1 = getelementptr inbounds [2 x i32], [2 x i32]* %0, i32 0, i32 0
// store i32 1, i32* %1
void bar(int a[]) {
a[0] = 1;
// store i32* %0, i32** %3, align 8
// %4 = load i32*, i32** %3, align 8
// %5 = getelementptr inbounds i32, i32* %4, i64 0
// store i32 1, i32* %5, align 4
如果将数组作为参数传递,则需要先使用
builder.CreateStore()
,然后使用llvm::GetElementPtrInst::CreateInBounds()
获取指向索引的指针。但是,在编写编译器时,我使用的是访问者模式,并将像
a[0] = 1
这样的代码视为assign expression
。当访问树节点assign_expression
时,我需要确定是否需要load
。有没有办法确定数组是局部定义的变量还是参数?
更新1:
例如,在C语言中,如果函数定义如下:
void test(int a[]) {
a[0] = 1;
}
a[0] = 1
的相应LLVM C++代码类似于:for(auto arg = theFunction->arg_begin(); arg != theFunction->arg_end(); arg ++) {
auto param = builder.CreateAlloca(llvm::Type::getInt32Ty(context)->getPointerTo());
builder.CreateStore(arg, param);
}
// a[0] = 1
auto loaded_tmp = builder.CreateLoad(param);
auto value = llvm::GetElementPtrInst::CreateInBounds(tmp, {Const(0), Const(0)}, "", the_basic_block);
但是,当数组在本地定义时,不需要代码
auto loaded_tmp = builder.CreateLoad(param);
。所以我的问题是:如何知道我是否需要CreateLoad
?更新2 :
由clang为以下C代码生成的LLVM IR:
int h(int a[]) {
a[0] = 1;
a[1] = 2;
}
是
define dso_local i32 @h(i32*) #0 {
%2 = alloca i32, align 4
%3 = alloca i32*, align 8
store i32* %0, i32** %3, align 8
%4 = load i32*, i32** %3, align 8
%5 = getelementptr inbounds i32, i32* %4, i64 0
store i32 1, i32* %5, align 4
%6 = load i32*, i32** %3, align 8
%7 = getelementptr inbounds i32, i32* %6, i64 1
store i32 2, i32* %7, align 4
%8 = load i32, i32* %2, align 4
ret i32 %8
}
在每个
load
之前都有一个store
指令
最佳答案
Is there a way to determine whether the array is a local defined variable or a parameter?
方法1:
像这样使用
isa<Argument>
:Analysis/BasicAliasAnalysis.cpp
167 if (isa<Argument>(V))
168 return true;
方法2:
组合使用
LLVMGetFirstParam
LLVMGetLastParam
和LLVMGetNextParam
来查找值是否为参数。看到:
https://github.com/llvm/llvm-project/blob/master/llvm/lib/IR/Core.cpp#L2456
关于c++ - LLVM:访问函数中的数组参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60222433/