void Executor::executeGep(Instruction *i) { if (DisabledSymbolicExeCurRun) { return; } assert(i && "Expecting an instruction!"); GetElementPtrInst *gep = (GetElementPtrInst*) i; assert(gep->getNumIndices()<=2 && "Unsupported gep instruction"); if(AllocaInst *a = dyn_cast<AllocaInst>(gep->getPointerOperand())) { Type *ty = a->getAllocatedType(); if (ty->isIntegerTy()) { // Incompleteness: pointer dereferencement on symbolic value AllLocDefinite = false; return; } } unsigned idx = 0; Type *subTy = NULL; Type *ptrOpTy = gep->getPointerOperandType(); if (ptrOpTy && ptrOpTy->getNumContainedTypes()==1) { subTy = ptrOpTy->getContainedType(0); } if (subTy && subTy->getNumContainedTypes()>0) { idx = 1; } else { assert("Unsupported gep instruction!"); } Value *ptr = (Value*) i; if(gep->hasIndices()) { Value *index = gep->getOperand(idx+1); if (SMAP->contains(index)) { // P[v->sv] // sv is a new symbolic value // Value *a = gep->getPointerOperand(); // ptr = (a index) //SymbolPtr Sindex = SMAP->get(index); //PMAP->createGepOp(ptr, a, Sindex); // Incompleteness: pointer dereferencement on symbolic value AllLocDefinite = false; } else { // P = P - ptr PMAP->remove(ptr); } } // Global allocation /*else if(isa<GlobalVariable>(ptr)) { // ptr in domain(P) if (PMAP->contains(ptr)) { SymbolPtr Pptr = PMAP->get(ptr); // P' = P[ptr->S(val)] PMAP->update(ptr, Pptr); } else { // P = P - ptr PMAP->remove(ptr); } }*/ }
bool Aa::LowerGepPass::runOnFunction(Function &F) { const llvm::Type *ptr_int_type = TD->getIntPtrType(F.getContext()); for (Function::iterator bi = F.begin(), be = F.end(); bi != be; ++bi) { BasicBlock *bb = bi; BasicBlock::iterator ii = bb->begin(); while (ii != bb->end()) { GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(ii); BasicBlock::iterator gi = ii++; if (!gep) { continue; } for (llvm::Value::use_iterator ui = gep->use_begin(), ue = gep->use_end(); ui != ue; ++ui) { Use &u = ui.getUse(); IOCode ioc = get_io_code(u); if (ioc == NOT_IO) continue; u.set(CastInst::CreatePointerCast(gep->getPointerOperand() , gep->getType() , "", gep)); } assert(gep->hasIndices() && "GEP without indices??"); llvm::Value *ptr = gep->getPointerOperand(); const Type *ctype = ptr->getType(); // deal with the base pointer first llvm::Value *base = gep->getPointerOperand(); std::string base_name = gep->getNameStr() + ".base"; llvm::Value *address = new PtrToIntInst(base, ptr_int_type, base_name + ".cast", gi); unsigned i = 0; for (User::op_iterator oi = gep->idx_begin(), oe = gep->idx_end(); oi != oe; ++oi, ++i) { llvm::Value *index = *oi; llvm::Value *offset = NULL; std::stringstream index_name; index_name << gep->getNameStr() << ".idx." << i; if (const SequentialType *qtype = dyn_cast<SequentialType>(ctype)) { // multiply index by size of element unsigned element_size = getTypePaddedSize(TD, qtype->getElementType()); const llvm::IntegerType *index_type = cast<IntegerType>(index->getType()); ConstantInt *cint = ConstantInt::get(index_type, element_size); assert(cint && "uh oh!"); offset = BinaryOperator::Create(Instruction::Mul , cint , index , index_name.str() , gi); ctype = qtype->getElementType(); } else if (const StructType *stype = dyn_cast<StructType>(ctype)) { // calculate offset into the struct const StructLayout *layout = TD->getStructLayout(stype); unsigned idx = cast<ConstantInt>(index)->getValue().getZExtValue(); unsigned struct_offset = layout->getElementOffset(idx); offset = ConstantInt::get(ptr_int_type, struct_offset); ctype = stype->getElementType(idx); } else assert(false && "unhandled offset into composite type"); // add offset to the address assert(address && "uh oh!"); std::stringstream add_name; add_name << gep->getNameStr() << ".lvl." << i; if (offset->getType() != address->getType()) { offset = CastInst::CreateIntegerCast(offset, address->getType() , false, offset->getName() + ".resized" , gi); } address = BinaryOperator::Create(Instruction::Add , address, offset , add_name.str(), gi); } if (address->getType() != ptr_int_type) address = CastInst::CreateIntegerCast(address, ptr_int_type , false, address->getName() + ".final", gi); Instruction *new_ptr = new IntToPtrInst(address, gep->getType() , gep->getName() + ".cast"); ReplaceInstWithInst(bb->getInstList(), gi, new_ptr); } } return true; }