简体   繁体   English

LLVM:如何分配数组元素?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM