GetElementPtrInstProcess()算法处理

GetElementPtrInst定义说明

get一条GetElementPtrInst,将instr->getOperand(0)分struct和ArrayStruct处理。


void RemoveStruct::GetElementPtrInstProcess(Instruction *instr) {
  assert(isa<GetElementPtrInst>(instr));
  //确保处理的是structvalue
  if (!hasStructType(instr->getOperand(0)->getType())) {
    outs()<<"GetElementPtrInst Process(): instr->getOperand(0) is not structType!"<<"\n";
    assert(0);
  }
  //先判断getelementptrInst的返回值是否为i8*,如果是的话,看getelementptrInst的user是不是memcpy,是的话,则不能分解该getelementptrInst,因为它只是取首地址的作用。
  //If the GetElementPtrInst used to have the address for memcpy
  //we cannot resloved it
  Type *ptr = instr->getType()->getPointerElementType();
  if (ptr->isIntegerTy() && ptr->getIntegerBitWidth()==8) {
    GetElementPtrInstWithMemcpy(instr);
  }
  // GetElementPtrInst *getelementptr = dyn_cast<GetElementPtrInst>(instr);
  // Type *src = getelementptr->getSourceElementType();
  // Type *dest = getelementptr->getResultElementType();
  // instr->getOperand(0) is the basis type value
  Value *inst_op_0 = instr->getOperand(0);
  //resloved the structure value
  if (IsStructVal(inst_op_0->getType())) {
    GetelementptrStructProcess(instr);
  } else {
    assert(IsArrayStructVal(inst_op_0->getType()));
    vector<int> val_num;
    val_num.clear();
    bool flag = ArrayVarNums(inst_op_0->getType(), val_num);
    GetelementptrArrayProcess(instr, val_num.size());
  }
}

小结,仍需推敲

getelementptr的解决方案:
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. The remaining arguments are indices。
第一个元素op_0是basis type value,说明计算地址的基础类型,第一个元素必须保留,该元素说明了该地址的几倍开始。
第二个元素op_1是the base address to start from,如果是array就是array[op_1]开始,那么这个index就必须保留,如果是struct,就是struct[op_1]开始,那么此时op_1是分解的位置。

完善getelementptr的处理函数:GetElementPtrInstProcess(Instruction *inst)
(1)inst的src和dest的structType类型一致时,仅保留getelementptr的list,不处理
(1.1)当inst的user为getelementptr inst2
(1.1.1)if(inst2的dest的structType != inst的srcstructType)加入(1)的list,分解inst的src的sub struct value,inst2的op_1assert为constant 0舍弃
(1.1.2)else assert(0),list just have a vector pointer,
(1.2)当接下来是callInst时,需要将array的信息传递下去
(2)当两者类型不一致时,则直接将其分解。

提取inst的op_0
(1)op_0为struct时,保留op_1,此时只保留op_1,万一op_2为pointer,
(2)op_0为Array struct时,分情况处理

情况一:getelementptrInst中第二个operand不是constantInt 0,则必须保留。

%46 = getelementptr inbounds %struct.CandidatePixel, %struct.CandidatePixel* %0, i64 %44, i32 0

情况二:instr->getNumOperands() <= array_layers + 2
后面是bitcast

 %120 = getelementptr inbounds [2 x [2 x %struct.point]], [2 x [2 x %struct.point]]* @global_8, i64 0, i64 1
 %121 = bitcast [2 x %struct.point]* %120 to i16*
    
 %52 = getelementptr inbounds [2 x %struct.point], [2 x %struct.point]* %global_0, i64 0, i64 1
%53 = bitcast %struct.point* %52 to i16*

后面是callInst

%3 = getelementptr inbounds [2 x %struct.str], [2 x %struct.str]* %1, i64 0, i64 0
%4 = call fastcc i32 @sum(%struct.str* nonnull %3) #4

后面是getelementptrInst

%47 = getelementptr inbounds %struct.str, %struct.str* %0, i64 0, i32 8
%48 = getelementptr inbounds [2 x %struct.point], [2 x %struct.point]* %47, i64 0, i64 0, i32 0

情况二:instr->getNumOperands() > array_layers + 2 ,直接分解处理。

%6 = getelementptr inbounds [2 x [2 x %struct.str]], [2 x [2 x %struct.str]]* @global, i64 0, i64 0, i64 0, i32 0
%124 = getelementptr inbounds [2 x %struct.str], [2 x %struct.str]* @global, i64 0, i64 1, i32 1, i64 1, i32 0

情况三:getelementptrInst的operand_0从argument而来

define i32 @zculling.1(i32, %struct.CandidatePixel*, i32, %struct.Pixel*, i8*, i8*, i8*) #0 
  %56 = getelementptr inbounds %struct.Pixel, %struct.Pixel* %3, i64 %55
  %57 = getelementptr inbounds %struct.Pixel, %struct.Pixel* %56, i32 0, i32 0

情况四:当getelementptrInst的返回address为i8*时,遍历instr的user是否存在memcpy,此时需要特殊处理。
当memcpy的len为一个i8时,正常处理;
当不是一个i8时,说明给了一个首地址,所以传递下去的getelementptr list只有op_0。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>