/// \brief Find the operand of the GEP that should be checked for consecutive /// stores. This ignores trailing indices that have no effect on the final /// pointer. unsigned llvm::getGEPInductionOperand(const GetElementPtrInst *Gep) { const DataLayout &DL = Gep->getModule()->getDataLayout(); unsigned LastOperand = Gep->getNumOperands() - 1; unsigned GEPAllocSize = DL.getTypeAllocSize( cast<PointerType>(Gep->getType()->getScalarType())->getElementType()); // Walk backwards and try to peel off zeros. while (LastOperand > 1 && match(Gep->getOperand(LastOperand), llvm::PatternMatch::m_Zero())) { // Find the type we're currently indexing into. gep_type_iterator GEPTI = gep_type_begin(Gep); std::advance(GEPTI, LastOperand - 1); // If it's a type with the same allocation size as the result of the GEP we // can peel off the zero index. if (DL.getTypeAllocSize(*GEPTI) != GEPAllocSize) break; --LastOperand; } return LastOperand; }
ref<ConstantExpr> Executor::evalConstantExpr(const llvm::ConstantExpr *ce) { LLVM_TYPE_Q llvm::Type *type = ce->getType(); ref<ConstantExpr> op1(0), op2(0), op3(0); int numOperands = ce->getNumOperands(); if (numOperands > 0) op1 = evalConstant(ce->getOperand(0)); if (numOperands > 1) op2 = evalConstant(ce->getOperand(1)); if (numOperands > 2) op3 = evalConstant(ce->getOperand(2)); switch (ce->getOpcode()) { default : ce->dump(); std::cerr << "error: unknown ConstantExpr type\n" << "opcode: " << ce->getOpcode() << "\n"; abort(); case Instruction::Trunc: return op1->Extract(0, getWidthForLLVMType(type)); case Instruction::ZExt: return op1->ZExt(getWidthForLLVMType(type)); case Instruction::SExt: return op1->SExt(getWidthForLLVMType(type)); case Instruction::Add: return op1->Add(op2); case Instruction::Sub: return op1->Sub(op2); case Instruction::Mul: return op1->Mul(op2); case Instruction::SDiv: return op1->SDiv(op2); case Instruction::UDiv: return op1->UDiv(op2); case Instruction::SRem: return op1->SRem(op2); case Instruction::URem: return op1->URem(op2); case Instruction::And: return op1->And(op2); case Instruction::Or: return op1->Or(op2); case Instruction::Xor: return op1->Xor(op2); case Instruction::Shl: return op1->Shl(op2); case Instruction::LShr: return op1->LShr(op2); case Instruction::AShr: return op1->AShr(op2); case Instruction::BitCast: return op1; case Instruction::IntToPtr: return op1->ZExt(getWidthForLLVMType(type)); case Instruction::PtrToInt: return op1->ZExt(getWidthForLLVMType(type)); case Instruction::GetElementPtr: { ref<ConstantExpr> base = op1->ZExt(Context::get().getPointerWidth()); for (gep_type_iterator ii = gep_type_begin(ce), ie = gep_type_end(ce); ii != ie; ++ii) { ref<ConstantExpr> addend = ConstantExpr::alloc(0, Context::get().getPointerWidth()); if (LLVM_TYPE_Q StructType *st = dyn_cast<StructType>(*ii)) { const StructLayout *sl = kmodule->targetData->getStructLayout(st); const ConstantInt *ci = cast<ConstantInt>(ii.getOperand()); addend = ConstantExpr::alloc(sl->getElementOffset((unsigned) ci->getZExtValue()), Context::get().getPointerWidth()); } else { const SequentialType *set = cast<SequentialType>(*ii); ref<ConstantExpr> index = evalConstant(cast<Constant>(ii.getOperand())); unsigned elementSize = kmodule->targetData->getTypeStoreSize(set->getElementType()); index = index->ZExt(Context::get().getPointerWidth()); addend = index->Mul(ConstantExpr::alloc(elementSize, Context::get().getPointerWidth())); } base = base->Add(addend); } return base; } case Instruction::ICmp: { switch(ce->getPredicate()) { default: assert(0 && "unhandled ICmp predicate"); case ICmpInst::ICMP_EQ: return op1->Eq(op2); case ICmpInst::ICMP_NE: return op1->Ne(op2); case ICmpInst::ICMP_UGT: return op1->Ugt(op2); case ICmpInst::ICMP_UGE: return op1->Uge(op2); case ICmpInst::ICMP_ULT: return op1->Ult(op2); case ICmpInst::ICMP_ULE: return op1->Ule(op2); case ICmpInst::ICMP_SGT: return op1->Sgt(op2); case ICmpInst::ICMP_SGE: return op1->Sge(op2); case ICmpInst::ICMP_SLT: return op1->Slt(op2); case ICmpInst::ICMP_SLE: return op1->Sle(op2); } } case Instruction::Select: return op1->isTrue() ? op2 : op3; case Instruction::FAdd: case Instruction::FSub: case Instruction::FMul: case Instruction::FDiv: case Instruction::FRem: case Instruction::FPTrunc: case Instruction::FPExt: case Instruction::UIToFP: case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: case Instruction::FCmp: assert(0 && "floating point ConstantExprs unsupported"); } }
/** * Print the given instruction. * * @param inst the instruction */ void JVMWriter::printInstruction(const Instruction *inst) { const Value *left, *right; if(inst->getNumOperands() >= 1) left = inst->getOperand(0); if(inst->getNumOperands() >= 2) right = inst->getOperand(1); switch(inst->getOpcode()) { case Instruction::Ret: printStartInvocationTag(); printEndInvocationTag("lljvm/runtime/Memory/destroyStackFrame()V"); if(inst->getNumOperands() >= 1) { printValueLoad(left); printSimpleInstruction( getTypePrefix(left->getType(), true) + "return"); } else { printSimpleInstruction("return"); } break; case Instruction::Unwind: printSimpleInstruction("getstatic", "lljvm/runtime/Instruction$Unwind/instance " "Llljvm/runtime/Instruction$Unwind;"); printSimpleInstruction("athrow"); // TODO: need to destroy stack frames break; case Instruction::Unreachable: printSimpleInstruction("getstatic", "lljvm/runtime/Instruction$Unreachable/instance " "Llljvm/runtime/Instruction$Unreachable;"); printSimpleInstruction("athrow"); break; case Instruction::Add: case Instruction::FAdd: case Instruction::Sub: case Instruction::FSub: case Instruction::Mul: case Instruction::FMul: case Instruction::UDiv: case Instruction::SDiv: case Instruction::FDiv: case Instruction::URem: case Instruction::SRem: case Instruction::FRem: case Instruction::And: case Instruction::Or: case Instruction::Xor: case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: printArithmeticInstruction(inst->getOpcode(), left, right); break; case Instruction::SExt: case Instruction::Trunc: case Instruction::ZExt: case Instruction::FPTrunc: case Instruction::FPExt: case Instruction::UIToFP: case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: case Instruction::PtrToInt: case Instruction::IntToPtr: case Instruction::BitCast: printCastInstruction(inst->getOpcode(), left, cast<CastInst>(inst)->getDestTy(), cast<CastInst>(inst)->getSrcTy()); break; case Instruction::ICmp: case Instruction::FCmp: printCmpInstruction(cast<CmpInst>(inst)->getPredicate(), left, right); break; case Instruction::Br: printBranchInstruction(cast<BranchInst>(inst)); break; case Instruction::Select: printSelectInstruction(inst->getOperand(0), inst->getOperand(1), inst->getOperand(2)); break; case Instruction::Load: printIndirectLoad(inst->getOperand(0)); break; case Instruction::Store: printIndirectStore(inst->getOperand(1), inst->getOperand(0)); break; case Instruction::GetElementPtr: printGepInstruction(inst->getOperand(0), gep_type_begin(inst), gep_type_end(inst)); break; case Instruction::Call: printCallInstruction(cast<CallInst>(inst)); break; case Instruction::Invoke: printInvokeInstruction(cast<InvokeInst>(inst)); break; case Instruction::Switch: printSwitchInstruction(cast<SwitchInst>(inst)); break; case Instruction::Alloca: printAllocaInstruction(cast<AllocaInst>(inst)); break; case Instruction::VAArg: printVAArgInstruction(cast<VAArgInst>(inst)); break; default: errs() << "Instruction = " << *inst << '\n'; llvm_unreachable("Unsupported instruction"); } }
DyckVertex* AAAnalyzer::handle_gep(GEPOperator* gep) { Value * ptr = gep->getPointerOperand(); DyckVertex* current = wrapValue(ptr); gep_type_iterator preGTI = gep_type_begin(gep); // preGTI is the PointerTy of ptr gep_type_iterator GTI = gep_type_begin(gep); // GTI is the PointerTy of ptr if (GTI != gep_type_end(gep)) GTI++; // ptr's element type, e.g. struct int num_indices = gep->getNumIndices(); int idxidx = 0; while (idxidx < num_indices) { Value * idx = gep->getOperand(++idxidx); if (/*!isa<ConstantInt>(idx) ||*/ !GTI->isSized()) { // current->addProperty("unknown-offset", (void*) 1); break; } if ((*preGTI)->isStructTy()) { // example: gep y 0 constIdx // s1: y--deref-->?1--(-2-constIdx)-->?2 DyckVertex* theStruct = this->addPtrTo(current, NULL); ConstantInt * ci = cast<ConstantInt>(idx); if (ci == NULL) { errs() << ("ERROR: when dealing with gep: \n"); errs() << *gep << "\n"; exit(1); } // field index need not be the same as original value // make it be a negative integer long fieldIdx = (long) (*(ci->getValue().getRawData())); DyckVertex* field = this->addField(theStruct, -2 - fieldIdx, NULL); // s2: ?3--deref-->?2 DyckVertex* fieldPtr = this->addPtrTo(NULL, field); /// the label representation and feature impl is temporal. @FIXME // s3: y--2-->?3 current->getRepresentative()->addTarget(fieldPtr->getRepresentative(), (void*) (fieldIdx)); // update current current = fieldPtr; } else if ((*preGTI)->isPointerTy() || (*preGTI)->isArrayTy()) { #ifndef ARRAY_SIMPLIFIED current = addPtrOffset(current, getConstantIntRawData(cast<ConstantInt>(idx)) * dl.getTypeAllocSize(*GTI), dgraph); #endif } else { errs() << "ERROR in handle_gep: unknown type:\n"; errs() << "Type Id: " << (*preGTI)->getTypeID() << "\n"; exit(1); } if (GTI != gep_type_end(gep)) GTI++; if (preGTI != gep_type_end(gep)) preGTI++; } return current; }