【问题标题】:The GEP Instruction: i32 vs i64GEP 指令:i32 与 i64
【发布时间】:2015-05-21 20:04:34
【问题描述】:

我一直在尝试理解 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 个整数数组的指针。这很清楚。我知道%MyVar 之后的参数是其中的索引,但我不明白为什么其中一些被声明为i64 而另一些被声明为i32

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

我还应该指出,这个例子说明了 GEP 的非法使用(必须取消引用结构中的指针才能索引到 40 个整数的数组),我试图很好地理解为什么会这样案例。

【问题讨论】:

    标签: llvm llvm-ir


    【解决方案1】:

    “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 在索引方面是相同的,它们都引用结构/数组中的第一个元素。您提到的常量17 也是如此。

    【讨论】:

    • 这太棒了!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-01-12
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多