The ‘getelementptr‘ instruction is used to get the address of a subelement of an aggregate data structure. It performs address calculation only and does not access memory. The instruction can also be used to calculate a vector of such addresses.
getelementptr指令就是get the address of 结构体的子变量,只进行地址加计算,不涉及内存获取。
llvm没有取地址的操作
getelementptr是在对一个地址进行加操作
load与store是llvm中两个对地址与数据进行操作的指令
load是对一个地址进行取数据,store是对一个地址进行存数据。
struct munger_struct {
int f1;
int f2;
};
void munge(struct munger_struct *P) {
P[0].f1 = P[1].f1 + P[2].f2;
}
...
munger_struct Array[3];
...
munge(Array);
对应IR
void %munge(%struct.munger_struct* %P) {
entry:
%tmp = getelementptr %struct.munger_struct* %P, i32 1, i32 0
%tmp = load i32* %tmp
%tmp6 = getelementptr %struct.munger_struct* %P, i32 2, i32 1
%tmp7 = load i32* %tmp6
%tmp8 = add i32 %tmp7, %tmp
%tmp9 = getelementptr %struct.munger_struct* %P, i32 0, i32 0
store i32 %tmp8, i32* %tmp9
ret void
}
GetElementPtr指令其实是一条指针计算语句,本身并不进行任何数据的访问或修改,进行是计算指针,修改计算后指针的类型。
GetElementPtr至少有两个参数,第一个参数为要进行计算的原始指针,往往是一个结构体指针,或数组首地址指针。
第二个参数及以后的参数,都称为indices,表示要进行计算的参数,如结构体的第几个元素,数组的第几个元素。
P[0].f1
%tmp9 = getelementptr %struct.munger_struct* %P, i32 0, i32 0
P[1].f1
P[2].f2
%tmp = getelementptr %struct.munger_struct* %P, i32 1, i32 0
%tmp6 = getelementptr %struct.munger_struct* %P, i32 2, i32 1
仅有数组计算
如果仅有数组指针计算,那么就简单了许多,数组指针的移动只需要一个参数即可。
但如果是仅有结构体指针,那么还是必须两个参数才行
3d_rendering case:
Triangle_3D triangle_3ds[3192]
; <label>:11: ; preds = %4, %822
%12 = phi i64 [ 0, %4 ], [ %823, %822 ]
%13 = getelementptr inbounds %struct.Triangle_3D, %struct.Triangle_3D* %0, i64 %12
%14 = bitcast %struct.Triangle_3D* %13 to i64*
%15 = load i64, i64* %14, align 1
%16 = getelementptr inbounds %struct.Triangle_3D, %struct.Triangle_3D* %0, i64 %12, i32 8
%17 = load i8, i8* %16, align 1