LLVM IR 中的 getelementptr

getelementptr in LLVM IR

我不理解为 LLVM IR 编写的以下代码。希望你能给我一个提示。

%struct.foo_struct = type {[3 x i32], i16*, i32}

;struct foo_struct {
;  [3 x i32] f0;
;  i16*      f1;
;  i32       f2;
; };

define i32 @foo(%struct.foo_struct* %P) {
entry:
  ; &P[0].f1
  %tmp0 = getelementptr inbounds %struct.foo_struct, %struct.foo_struct* %P, i64 0, i32 1
  ; P[0].f1
  %tmp1 = load i16*, i16** %tmp0 
  ; &P[0].f1[0]
  %tmp2 = getelementptr inbounds i16, i16* %tmp1, i64 0 

具体来说,在条目的第一行代码中,我们在末尾有 i32 1。为什么是 i32?因为我们要跳转到下一个字段,即f1,所以我们必须跳过一个数组(f0),即3xi32。那么这个i32是什么?如果我们想要例如,那会是什么? &P[0].f2?

感谢您的帮助

Since we want to jump to the next field, namely f1, we have to jump over an array (f0), which 3xi32. So what is this i32?

1是成员在结构中的索引,i32是这个索引的类型。

我们跳过 3xi32 到达 f1 或者我们因此跳过 12 个字节的事实没有直接编码在指令中。我们指定的只是我们想要第二个成员(即索引 1 处的成员),以及如何将其转换为以字节为单位的偏移量,这是由 LLVM 根据所涉及的类型计算的。我们没有在说明中说明这一点。

What would be there if we want to have e.g. &P[0].f2?

i32 2

Why i32?

结构索引始终具有 i32 类型。由于结构索引必须始终是常量,因此实际上不需要允许不同的类型,并且 i32 足够大以用于所有实际目的(即,您不会拥有超过 2^32 个成员的结构)。