IR出现的待解决的复杂case:
%.sroa.3.0.copyload = load volatile i16, i16* bitcast (i8* getelementptr inbounds (i8, i8* bitcast (%struct.str* @global to i8*), i64 14) to i16*), align 2
Getelementptr Instruction
一、Overview:
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指令
1、为了得到复合数据结构子元素的地址。
2、仅仅执行地址计算,不访问内存。
3、还可用于计算地址的向量。
二、Arguments
The first argument is always a type used as the basis for the calculations.
第一个参数始终是用作计算基础的类型。(内存读取的基础类型,读取步长长度=基础类型大小)
The second argument is always a pointer or a vector of pointers, and is the base address to start from.
第二个参数始终是指针或指针向量,并且是从中开始的基址。 (开始的基址是内存读取的开始地址。)
问题太多,太博大精深了,遇到再写吧!!
llvm官网详解
‘bitcast … to’ Instruction
<result> = bitcast <ty> <value> to <ty2> ; yields ty2
The ‘bitcast’ instruction converts value to type ty2 without changing any bits.
读取value的内存方式通过ty2基础类型,步长为ty2
直接解决问题吧!
解读case:
bitcast (%struct.str* @global to i8*)
global类型为Struct,对应的内存空间是一块Struct,经过bitcast转换之后,读取global的内存空间通过指针i8*,i8步长读取,(注意:只有复合结构需要解地址i64 0 的存在,当为基本类型时,不需要解地址)
getelementptr inbounds (i8, i8* bitcast (%struct.str* @global to i8*), i64 14
i64 14为偏移地址,此时i8的指针,步长为i8,getelementptr将得到地址为i8*14的子元素。
bitcast (i8* getelementptr inbounds (i8, i8* bitcast (%struct.str* @global to i8*), i64 14) to i16*)
在地址为i8*14处,步长改为i16
ps:bitcast 关于指针(变量的地址)的选择,因为i8使得它更通用作为字节可寻址的存储区域,为了生成内部调用,我们需要一个内存字节地址和sizeof(T)的字节数。这就是我们需要将i32 *转换为i8 *的原因。