GEP指令:i32 vs i64

时间:2015-05-21 20:04:34

标签: llvm llvm-ir

我一直试图理解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个整数的数组)并且我试图很好地理解为什么这是案件。

1 个答案:

答案 0 :(得分:2)

问题的答案,“GEP取消引用了什么?”是没有。这意味着GEP永远不会取消引用指针:它只根据您传递它的指针计算新地址。它从不读取任何记忆。

看一下例子:

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

我们从%MyVar开始,它是一个{ [40 x i32]* }*,一个指向包含指向数组的指针的结构的指针。

使用i64 0建立索引后,我们引用了一个结构{ [40 x i32]* }%MyVar已经指出了这一点,不需要解除引用。

在使用第二个i32 0建立索引之后,我们现在引用结构的唯一成员[40 x i32]*。它与结构本身具有相同的内存位置,位于%MyVar

第三个索引i64 0现在将引用[40 x i32]数组本身。 这是非法的。 GEP需要取消引用上一步中获得的指针才能获得此内存地址。一般来说,GEP永远不能“通过”一个指针,明显的例外是你传递给它的初始值总是一个指针。

我还要指出i32 0i64 0在索引方面是相同的,都指向struct / array中的第一个元素。对于你提到的常数17也是如此。