llvm 处理struct中getelementptr指向无用内存空间的case

IR中的
%.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
store volatile i16 %.sroa.3.0.copyload, i16* %.sroa.3, align 2
struct形式为

struct str3 {
   int x3[2];
   char y3[2];
};
struct str2 {
   struct str3 p3;
   short x2;
};
struct str1 {
   struct str2 p2;
   char x1;
};
struct str {
   struct str1 p1;
   int x;
};

内存排布

0  0  0  0  0  
Type list: i32
0  0  0  0  1  
Type list: i32
0  0  0  1  0  
Type list: i8
0  0  0  1  1  
Type list: i8
0  0  1  
Type list: i16
0  1  
Type list: i8
1  
Type list: i32

32  64  72  80  112  136  192

14*8 = 112后面是无用的内存空间,getelementptr无效
删除load指令,并将load的所有use全部替换为Value 0!

void RemoveStruct::BitCastGetelementPtr(Instruction* &instr) {
  SmallVector<Instruction*,128> *WorkListDel = new SmallVector<Instruction* ,128>();
  Instruction* getelement_inst = instr->getNextNode();
  assert(getelement_inst->getNumOperands() == 2);
  int bit_width = getelement_inst->getOperand(0)->getType()->getPointerElementType()->getIntegerBitWidth();
  Value* op_1 = getelement_inst->getOperand(1);
  ConstantInt* width;
  int byte_nums;
  if (isa<llvm::ConstantInt>(op_1)) {
    width = llvm::dyn_cast<llvm::ConstantInt>(op_1);
    byte_nums = width->getSExtValue();
  }
  //  byte_nums 就是14
  Value* val = instr->getOperand(0);
  Type* val_ty = val->getType()->getPointerElementType();
  vector<int> val_list;
  map<vector<int>, Type*> val_map;
  int align = 0;
  BitCastStruct(val_list, val_ty, val_map, align);
  map<vector<int>, Type*>::iterator iter;
  int bitcast_bitwidth = instr->getType()->getPointerElementType()->getIntegerBitWidth();
  int actual_width = bitcast_bitwidth * byte_nums;
  int val_width = 0;
  int step_width = 1;
  int use_width = 0;
  bool flag = false;
  vector<int> begin = val_map.begin()->first;
  int begin_size = begin.size();
  for (iter = val_map.begin(); iter != val_map.end(); iter++) {
    vector<int> vec_temp = iter->first;
    //  当vec_temp的size改变时,说明struct进行了嵌套,需要对其进行align补齐,其中补齐的bit
    // bit数就是 (align - (use_width % align)) 
    if (begin_size != vec_temp.size()) {
      begin_size = vec_temp.size();
      use_width = (align - (use_width % align)) + use_width;
    }
    val_width = iter->second->getIntegerBitWidth();
    while (use_width % val_width != 0) {
      use_width += step_width;
    }
    use_width += val_width;
    outs() << "  " << use_width;
    if (use_width - val_width == actual_width) { flag = true; }
  }
  outs() <<"\n";
  // flag标志是否getelementptr到错误内存
  if (flag == false) {
    for (Value::user_iterator UI = getelement_inst->user_begin(), E =getelement_inst->user_end(); UI != E; ++UI) {
      User *U = *UI;
      assert(isa<Instruction> (U));
      Instruction* CI = dyn_cast<Instruction> (U);
      if (CI->getOpcode() == llvm::Instruction::BitCast) {
        WorkListDel->push_back(CI);
        for (Value::user_iterator UI2 = CI->user_begin(), E2 =CI->user_end(); UI2 != E2; ++UI2) {
          User *U2 = *UI2;
          assert(isa<Instruction> (U2));
          Instruction* CI_2 = dyn_cast<Instruction> (U2);
          if (CI_2->getOpcode() == llvm::Instruction::Load) {
            Value* zero = ConstantInt::get(CI_2->getType(), 0);
            CI_2->replaceAllUsesWith(zero);
            WorkListDel->push_back(CI_2);
          } else if (CI_2->getOpcode() == llvm::Instruction::Store) {
            WorkListDel->push_back(CI_2);
          } else {
            assert(0);
          }
        }
      } else if (CI->getOpcode() == llvm::Instruction::Load) {
        Value* zero = ConstantInt::get(CI->getType(), 0);
        CI->replaceAllUsesWith(zero);
        WorkListDel->push_back(CI);
      } else if (CI->getOpcode() == llvm::Instruction::Store) {
        WorkListDel->push_back(CI);
      } else {
        assert(0);
      }
    }
    WorkListDel->push_back(instr);
    WorkListDel->push_back(instr->getNextNode());
  }
  while (!WorkListDel->empty()) {
    Instruction *instruction = WorkListDel->pop_back_val();
    instruction->eraseFromParent();
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值