创建一个GetElementPtrInst
GetElementPtrInst:an instruction for type-safe pointer arithmetic to access elements of arrays and structs。
目的从一个getElement Expr提取相应value再在其上插入一个instruction
%global.sroa.4.0.copyload = load i64, i64* getelementptr inbounds (%struct.str, %struct.str* @global, i64 0, i32 1), align 8, !dbg !30
生成目标bc
%j = getelementptr %struct.str, %struct.str* @global, i64 0, i32 1
%global.sroa.4.0.copyload = load i64, i64* getelementptr inbounds (%struct.str, %struct.str* @global, i64 0, i32 1), align 8, !dbg !30
step one:定位到指定instruction
step two:提取相关参数
step three:创建ArrayRef,list的第一个元素是0,用于解地址,第二个是offset
step four:create instruction(PointeeType 不同于Pointer,直接使用vir_op->type()也是返回type*,但是此时为指向struct *的指针,需要将其转为dyn_cast<PointerType>(vir_op->getType())->getElementType()
这样返回的才是指向struct的指针,PointeeType 意思就位指向目标对象的指针类型。)
GetElementPtrInst::Create(Type *PointeeType, Value *Ptr,
ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd)
Example Code
llvm::Instruction* instr = &*i;
for(int i = 0; i < instr->getNumOperands(); i++){
llvm::Value* ptr = instr->getOperand(i);
if (llvm::isa<llvm::ConstantExpr>(ptr)) {
llvm::ConstantExpr* constExpr = llvm::dyn_cast<llvm::ConstantExpr>(ptr);
assert(constExpr->getOpcode() == llvm::Instruction::GetElementPtr);
outs() << "ConstantExpr "<< "\n";
// if (llvm::isa<llvm::GetElementPtrConstantExpr>(constExpr)){
// outs() << "GetElementPtrConstantExpr "<< "\n";}
llvm::Value* vir_op = constExpr->getOperand(0);
outs() << " Type is " << *vir_op->getType()<< " Value is " << getLabel(vir_op) << "\n";
llvm::Value* vir_op_2 = constExpr->getOperand(1);
outs() << " Type is " << *vir_op_2->getType()<< " Value is " << getLabel(vir_op_2) << "\n";
llvm::Value* vir_op_3 = constExpr->getOperand(2);
outs() << " Type is " << *vir_op_3->getType()<< " Value is " << getLabel(vir_op_3) << "\n";
//Value* IdxList[1] = {ConstantInt::get(vir_op_3->getType(),1),};
Value* IdxList[2] = {ConstantInt::get(vir_op_2->getType(),0), vir_op_3};
ArrayRef<Value*> list(IdxList, 2);
GetElementPtrInst * ptrInst_new = GetElementPtrInst::Create(dyn_cast<PointerType>(vir_op->getType())->getElementType(),vir_op,
list, "j", instr);
// module_->dump();
}
}
我参考的Stack overflow上写的,由于这个博主使用版本llvm很早的版本,函数参数都不一样,但值得借鉴参考
链接:Inserting GetElementpointer Instruction in LLVM IR