Llvm GEP指令:i32 vs i64
我一直试图理解LLVM的GetElementPtr(GEP)指令,并偶然发现了以下文档: 这很有帮助,但有几件事我感到困惑。特别是在“GEP取消引用了什么?”()一节中,讨论了以下代码:Llvm GEP指令:i32 vs i64,llvm,llvm-ir,Llvm,Llvm Ir,我一直试图理解LLVM的GetElementPtr(GEP)指令,并偶然发现了以下文档: 这很有帮助,但有几件事我感到困惑。特别是在“GEP取消引用了什么?”()一节中,讨论了以下代码: %MyVar = uninitialized global { [40 x i32 ]* } ... %idx = getelementptr { [40 x i32]* }, { [40 x i32]* }* %MyVar, i64 0, i32 0, i64 0, i64 17 %MyVar是一个全局变
%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个整数的数组中,结构中的指针必须被取消引用),我试图很好地理解为什么会出现这种情况。问题“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 0
和i64 0
在索引方面是相同的,它们都引用结构/数组中的第一个元素。你提到的常数17
也是如此。这太棒了!非常感谢。