Reputation: 21
I am trying to write a compiler using LLVM C++ API, and I am trying to access array parameter in a function.
As far as I can tell from clang's IR generation, those two codes has different LLVM IR codes:
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
If passing an array as a parameter, I need to use builder.CreateStore()
first, then use llvm::GetElementPtrInst::CreateInBounds()
to get the pointer to the index.
However, when writing the compiler, I am using the visitor pattern and see codes like a[0] = 1
as assign expression
. When visiting the tree node assign_expression
, I need to determine whether the load
is needed.
Is there a way to determine whether the array is a local defined variable or a parameter?
Update 1: for example, in C, if a function is defined like this:
void test(int a[]) {
a[0] = 1;
}
the corresponding LLVM C++ code for a[0] = 1
is like:
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);
However, when the array is defined local, the code auto loaded_tmp = builder.CreateLoad(param);
is not needed. So my question is: how do I get to know if I need the CreateLoad
?
Update 2: The LLVM IR generated by clang for the following C code :
int h(int a[]) {
a[0] = 1;
a[1] = 2;
}
is
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
}
which has a load
instruction before each store
Upvotes: 2
Views: 1296
Reputation: 38272
Is there a way to determine whether the array is a local defined variable or a parameter?
Method1:
Use isa<Argument>
like this:
Analysis/BasicAliasAnalysis.cpp
167 if (isa<Argument>(V))
168 return true;
Method2:
Use a combination of LLVMGetFirstParam
LLVMGetLastParam
and LLVMGetNextParam
to find if a value is a parameter.
See: https://github.com/llvm/llvm-project/blob/master/llvm/lib/IR/Core.cpp#L2456
Upvotes: 1