处理BitcastInst语句,首先总结其遇到的情况:
1、通过struct Value 遍历到该变量user为BitcastInst。
%35 = bitcast (%1) to i16*
//%1为struct Value的user
(1)当%1为struct全局或局部变量时
(1.1)当被memcpy语句使用时,通过memcpyToBitCast(memcpy_dest, bitcast_src, instr)函数处理
case:memcpy(i8* %2, i8* bitcast (%struct.str* @global to i8*), i64 28, i32 4, i1 false)
(1.2)当被store语句使用时,需要将store中的变量利用内存排布表拆开。
case:
%36 = bitcast %struct.MySize* %12 to i64*
store i64 %10, i64* %36, align 4
(1.3)当被load使用时,直接构建该变量的内存排布表。
case:
%43 = bitcast %struct.point* %42 to i16*
%44 = load i16, i16* %43, align 2
(2)当%1不为全局或局部变量时
(2.1)为GetElementPtrConstantExpr
case:
%1 = bitcast (%struct.point* getelementptr inbounds (%struct.str, %struct.str* @global, i64 0, i32 3) to i32*)
(2.2)为GetElementPtrInst时,
case:
%52 = getelementptr inbounds [2 x %struct.point], [2 x %struct.point]* %global_0, i64 0, i64 1
%53 = bitcast %struct.point* %52 to i16*
构建内存排布表算法:
1、出现struct 的user为’ bitcast struct to iN ’ instruction时,构建iN 的struct内存排布表。
2、遍历bitcastInst 的userlist,移位操作指令创建Table。
3、再遍历bitcastInst 的userlist,当其Table中只存有single variable时,指令替换。
4、替换完成,将所有Table delete。
当处理如下情况时:
structure value 作为CallInst参数
// 原始code
// %64 = bitcast %struct.MyPoint* %23 to i64*
// %65 = load i64, i64* %64, align 4
// %66 = call i32 @cascadeClassifier([320 x i32]* %62, [320 x i32]* %63, i64 %65)
//@cascadeClassifier(%10 is %65)
// %36 = bitcast %struct.MySize* %12 to i64*
// store i64 %10, i64* %36, align 4
// 解决思路:首先将拆解完的struct (iN x, iN y) 传递给Function,作为Functionde arguments, 如果Function使用的是x和y,直接替换为x,y,否则使用BitConcatenate()函数合并x,y输出并传递下去,直到找到使用x,y。
//-->> %66 = call i32 @cascadeClassifier([320 x i32]* %62, [320 x i32]* %63, i32 %x, i32 %y)
//-->> @cascadeClassifier([320 x i32]*, [320 x i32]*, i32, i32)
// i64 %10 = BitConcatenate(i32 %x,i32 %y);
// store i64 %10, i64* %36, align 4
// %13 = getelementptr inbounds %struct.MySize, %struct.MySize* %12, i32 0, i32 0
// %14 = getelementptr inbounds %struct.MySize, %struct.MySize* %12, i32 0, i32 1
// store i32 %2, i32* %13
// store i32 %3, i32* %14