GEP指令:i32与i64的区别

6
我一直在尝试理解LLVM的GetElementPtr(GEP)指令,并找到了这篇文档:http://llvm.org/docs/GetElementPtr.html。它非常有帮助,但有一些我觉得很困惑的地方。特别是在“GEP解引用的内容是什么?”部分(http://llvm.org/docs/GetElementPtr.html#id6),讨论了以下代码:
%MyVar = uninitialized global { [40 x i32 ]* }
...
%idx = getelementptr { [40 x i32]* }, { [40 x i32]* }* %MyVar, i64 0, i32 0, i64 0, i64 17

%MyVar是一个全局变量,它是指向一个包含指向40个int数组的指针的结构体的指针。这很清楚。我理解在%MyVar之后的参数是对它的索引,但我不明白为什么有些声明为i64,而其他一些声明为i32

我的理解是,这段代码是为64位机器编写的,并且假定指针的宽度为64位。由%MyVar指向的数组的内容宽度为32位。那么,为什么最后一个索引是i64 17而不是i32 17

我还应该指出,这个例子说明了GEP的非法使用(必须解除结构体中的指针引用才能索引到40个int数组),我正在努力深入理解为什么会这样。

1个回答

3

“GEP指令它解引用什么?”的答案是没有任何内容。这意味着GEP指令从不解引用指针:它仅根据您传递给它的指针计算新地址。它从不读取任何内存。

来看这个例子:

%idx = getelementptr { [40 x i32]* }, { [40 x i32]* }* %MyVar, i64 0, i32 0, i64 0, i64 17

我们首先有一个%MyVar,它是一个指向包含指向数组的指针的结构体的指针,类型为{ [40 x i32]* }*
索引后,我们得到了一个指向{ [40 x i32]* }结构体的引用。指针%MyVar已经指向了这个结构体,不需要进行解引用操作。
在第二个索引之后,我们现在引用了[40 x i32]*,即该结构体的唯一成员。它与结构体本身具有相同的内存位置,即在%MyVar处。
第三个索引现在将引用[40 x i32]数组本身。这是非法的。 GEP需要解引用在前一步骤中获取的指针以获取此内存地址。一般来说,GEP永远不能通过指针进行索引,明显的例外是您传递给它的初始值始终是指针。
我还要指出,在索引方面,和在目的上是相同的,都指向结构/数组中的第一个元素。对于您提到的常量17也是如此。

太棒了!谢谢你! - banach-space

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接