[英]LLVM: how to assign an array element?
I'm struggling to figure out how to assign an array element using the LLVM c++ API.我正在努力弄清楚如何使用 LLVM c++ API 分配数组元素。 consider this C code:
考虑这个 C 代码:
int main()
{
int aa[68];
aa[56] = 7;
return 0;
}
using使用
clang -S -emit-llvm main.c
I get the following IR (attributes and other things are skipped for simplicity):我得到以下 IR(为简单起见,跳过了属性和其他内容):
define dso_local i32 @main() #0 {
%1 = alloca i32, align 4
%2 = alloca [68 x i32], align 16
store i32 0, i32* %1, align 4
%3 = getelementptr inbounds [68 x i32], [68 x i32]* %2, i64 0, i64 56
store i32 7, i32* %3, align 16
ret i32 0
}
I already know how to create an inbounds GEP, but when storing a value (7) to the array the type is a pointer to i32.我已经知道如何创建入站 GEP,但是当将值 (7) 存储到数组时,类型是指向 i32 的指针。
my language is very similar to C, that's why I'm using C as an example (so far it's just C but with a different syntax).我的语言与 C 非常相似,这就是为什么我使用 C 作为示例(到目前为止,它只是 C,但语法不同)。 generated IR for my language is:
为我的语言生成的 IR 是:
define i32 @main() {
%0 = alloca [2 x i32], align 4
%1 = getelementptr [2 x i32], [2 x i32]* %0, i32 1
store i32 1, [2 x i32]* %1, align 4
ret i32 0
}
how can I possibly turn [2 x i32]* into i32* when creating a store?创建商店时如何将 [2 x i32]* 转换为 i32*? this is how I create the store:
这就是我创建商店的方式:
llvm::AllocaInst *stored = symbol_table[arr_name];
llvm::Value *result = ir_builder->CreateGEP(stored->getAllocatedType(), stored, idx_vals);
// idx_vals contains the index
ir_builder->CreateStore(val, result); // here val is a value stored in a symbol table
// and it's type is llvm::Value *
how can I possibly turn [2 x i32]* into i32* when creating a store?
创建商店时如何将 [2 x i32]* 转换为 i32*?
This is exactly what the "get element pointer" instruction does.这正是“获取元素指针”指令所做的。 You have a pointer to an object like a struct or an array, and you want a pointer to one element.
您有一个指向 object 的指针,例如结构或数组,并且您想要一个指向一个元素的指针。
%1 = getelementptr [2 x i32], [2 x i32]* %0, i32 1
This isn't quite what you want.这不是你想要的。 Picture a C string in memory, you don't have a
[*number* x i8]*
you just have an i8*
.在 memory 中想象一个 C 字符串,你没有
[*number* x i8]*
你只有一个i8*
。 If you had a pointer to [*number* x i8]*
you'd be stepping into that array and getting a pointer to one of its elements, but with a C string you have a pointer to a single i8
element and you step over it, advancing your pointer by sizeof the pointee.如果您有一个指向
[*number* x i8]*
的指针,您将进入该数组并获取指向其中一个元素的指针,但是使用 C 字符串您有一个指向单个i8
元素的指针,然后您越过它,将指针推进指针的大小。
What your %1
is doing is stepping over one whole [2 x i32]
and pointing to another full [2 x i32]
after it.你的
%1
正在做的是跨过一个完整的[2 x i32]
并指向另一个完整的[2 x i32]
。 You don't want to step over at all, so your first index should be i32 0
.你根本不想跨过,所以你的第一个索引应该是
i32 0
。 Then you want to step into it and select the second i32
in your 2 x i32
?然后你想进入它并 select 你的
2 x i32
i32
Use i32 1
as your second index.使用
i32 1
作为您的第二个索引。
%1 = getelementptr [2 x i32], [2 x i32]* %0, i32, 0, i32 1
produces an i32*
.产生一个
i32*
。
See the LLVM GEP FAQ: https://www.llvm.org/docs/GetElementPtr.html请参阅 LLVM GEP 常见问题解答: https://www.llvm.org/docs/GetElementPtr.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.