bool llvm::ValueCounter::runOnModule(Module& M) { std::set<Value*> values; for(Module::iterator Fit = M.begin(), Fend = M.end(); Fit != Fend; Fit++){ if (!values.count(Fit)) values.insert(Fit); for(Function::arg_iterator Arg = Fit->arg_begin(), aEnd = Fit->arg_end(); Arg != aEnd; Arg++) { if (!values.count(Arg)) values.insert(Arg); } for (Function::iterator BBit = Fit->begin(), BBend = Fit->end(); BBit != BBend; BBit++) { for (BasicBlock::iterator Iit = BBit->begin(), Iend = BBit->end(); Iit != Iend; Iit++) { if (!values.count(Iit)) values.insert(Iit); for(unsigned int i = 0; i < Iit->getNumOperands(); i++){ if (!values.count(Iit->getOperand(i))) values.insert(Iit->getOperand(i)); } } } } TotalValues = values.size(); //We don't modify anything, so we must return false; return false; }
bool OvershiftCheckPass::runOnModule(Module &M) { Function *overshiftCheckFunction = 0; LLVMContext &ctx = M.getContext(); bool moduleChanged = false; for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) { for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) { for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) { if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) { // find all shift instructions Instruction::BinaryOps opcode = binOp->getOpcode(); if (opcode == Instruction::Shl || opcode == Instruction::LShr || opcode == Instruction::AShr ) { std::vector<llvm::Value*> args; // Determine bit width of first operand uint64_t bitWidth=i->getOperand(0)->getType()->getScalarSizeInBits(); ConstantInt *bitWidthC = ConstantInt::get(Type::getInt64Ty(ctx), bitWidth, false); args.push_back(bitWidthC); CastInst *shift = CastInst::CreateIntegerCast(i->getOperand(1), Type::getInt64Ty(ctx), false, /* sign doesn't matter */ "int_cast_to_i64", &*i); args.push_back(shift); // Lazily bind the function to avoid always importing it. if (!overshiftCheckFunction) { Constant *fc = M.getOrInsertFunction("klee_overshift_check", Type::getVoidTy(ctx), Type::getInt64Ty(ctx), Type::getInt64Ty(ctx), NULL); overshiftCheckFunction = cast<Function>(fc); } // Inject CallInstr to check if overshifting possible CallInst *ci = CallInst::Create(overshiftCheckFunction, args, "", &*i); // set debug information from binary operand to preserve it ci->setDebugLoc(binOp->getDebugLoc()); moduleChanged = true; } } } } } return moduleChanged; }
bool ARM64PromoteConstant::runOnFunction(Function &F) { // Look for instructions using constant vector // Promote that constant to a global variable. // Create as few load of this variable as possible and update the uses // accordingly bool LocalChange = false; SmallSet<Constant *, 8> AlreadyChecked; for (Function::iterator IBB = F.begin(), IEndBB = F.end(); IBB != IEndBB; ++IBB) { for (BasicBlock::iterator II = IBB->begin(), IEndI = IBB->end(); II != IEndI; ++II) { // Traverse the operand, looking for constant vectors // Replace them by a load of a global variable of type constant vector for (unsigned OpIdx = 0, EndOpIdx = II->getNumOperands(); OpIdx != EndOpIdx; ++OpIdx) { Constant *Cst = dyn_cast<Constant>(II->getOperand(OpIdx)); // There is no point is promoting global value, they are already global. // Do not promote constant expression, as they may require some code // expansion. if (Cst && !isa<GlobalValue>(Cst) && !isa<ConstantExpr>(Cst) && AlreadyChecked.insert(Cst)) LocalChange |= promoteConstant(Cst); } } } return LocalChange; }
void IntTest::pbzip2_like(Module &M) { TestBanner X("pbzip2-like"); vector<StoreInst *> writes; Function *f_rand = M.getFunction("rand"); assert(f_rand); Function *f_producer = M.getFunction("_Z8producerPv.SLICER"); assert(f_producer); // Search along the CFG. We need to make sure reads and writes are in // a consistent order. for (Function::iterator bb = f_producer->begin(); bb != f_producer->end(); ++bb) { for (BasicBlock::iterator ins = bb->begin(); ins != bb->end(); ++ins) { if (CallInst *ci = dyn_cast<CallInst>(ins)) { if (ci->getCalledFunction() == f_rand) { for (BasicBlock::iterator j = bb->begin(); j != bb->end(); ++j) { if (StoreInst *si = dyn_cast<StoreInst>(j)) writes.push_back(si); } } } } } errs() << "=== writes ===\n"; for (size_t i = 0; i < writes.size(); ++i) { errs() << *writes[i] << "\n"; } vector<LoadInst *> reads; Function *f_consumer = M.getFunction("_Z8consumerPv.SLICER"); assert(f_consumer); for (Function::iterator bb = f_consumer->begin(); bb != f_consumer->end(); ++bb) { for (BasicBlock::iterator ins = bb->begin(); ins != bb->end(); ++ins) { if (ins->getOpcode() == Instruction::Add && ins->getType()->isIntegerTy(8)) { LoadInst *li = dyn_cast<LoadInst>(ins->getOperand(0)); assert(li); reads.push_back(li); } } } errs() << "=== reads ===\n"; for (size_t i = 0; i < reads.size(); ++i) { errs() << *reads[i] << "\n"; } assert(writes.size() == reads.size()); AliasAnalysis &AA = getAnalysis<AdvancedAlias>(); for (size_t i = 0; i < writes.size(); ++i) { for (size_t j = i + 1; j < reads.size(); ++j) { errs() << "i = " << i << ", j = " << j << "... "; AliasAnalysis::AliasResult res = AA.alias( writes[i]->getPointerOperand(), reads[j]->getPointerOperand()); assert(res == AliasAnalysis::NoAlias); print_pass(errs()); } } }
void LowerEmAsyncify::FindContextVariables(AsyncCallEntry & Entry) { BasicBlock *AfterCallBlock = Entry.AfterCallBlock; Function & F = *AfterCallBlock->getParent(); // Create a new entry block as if in the callback function // theck check variables that no longer properly dominate their uses BasicBlock *EntryBlock = BasicBlock::Create(TheModule->getContext(), "", &F, &F.getEntryBlock()); BranchInst::Create(AfterCallBlock, EntryBlock); DominatorTreeWrapperPass DTW; DTW.runOnFunction(F); DominatorTree& DT = DTW.getDomTree(); // These blocks may be using some values defined at or before AsyncCallBlock BasicBlockSet Ramifications = FindReachableBlocksFrom(AfterCallBlock); SmallPtrSet<Value*, 256> ContextVariables; Values Pending; // Examine the instructions, find all variables that we need to store in the context for (BasicBlockSet::iterator RI = Ramifications.begin(), RE = Ramifications.end(); RI != RE; ++RI) { for (BasicBlock::iterator I = (*RI)->begin(), E = (*RI)->end(); I != E; ++I) { for (unsigned i = 0, NumOperands = I->getNumOperands(); i < NumOperands; ++i) { Value *O = I->getOperand(i); if (Instruction *Inst = dyn_cast<Instruction>(O)) { if (Inst == Entry.AsyncCallInst) continue; // for the original async call, we will load directly from async return value if (ContextVariables.count(Inst) != 0) continue; // already examined if (!DT.dominates(Inst, I->getOperandUse(i))) { // `I` is using `Inst`, yet `Inst` does not dominate `I` if we arrive directly at AfterCallBlock // so we need to save `Inst` in the context ContextVariables.insert(Inst); Pending.push_back(Inst); } } else if (Argument *Arg = dyn_cast<Argument>(O)) { // count() should be as fast/slow as insert, so just insert here ContextVariables.insert(Arg); } } } } // restore F EntryBlock->eraseFromParent(); Entry.ContextVariables.clear(); Entry.ContextVariables.reserve(ContextVariables.size()); for (SmallPtrSet<Value*, 256>::iterator I = ContextVariables.begin(), E = ContextVariables.end(); I != E; ++I) { Entry.ContextVariables.push_back(*I); } }
void LTOModule::addDefinedFunctionSymbol(Function* f, Mangler &mangler) { // add to list of defined symbols addDefinedSymbol(f, mangler, true); // add external symbols referenced by this function. for (Function::iterator b = f->begin(); b != f->end(); ++b) { for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) { for (unsigned count = 0, total = i->getNumOperands(); count != total; ++count) { findExternalRefs(i->getOperand(count), mangler); } } } }
bool DivCheckPass::runOnModule(Module &M) { Function *divZeroCheckFunction = 0; LLVMContext &ctx = M.getContext(); bool moduleChanged = false; for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f) { for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b) { for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) { if (BinaryOperator* binOp = dyn_cast<BinaryOperator>(i)) { // find all [s|u][div|mod] instructions Instruction::BinaryOps opcode = binOp->getOpcode(); if (opcode == Instruction::SDiv || opcode == Instruction::UDiv || opcode == Instruction::SRem || opcode == Instruction::URem) { CastInst *denominator = CastInst::CreateIntegerCast(i->getOperand(1), Type::getInt64Ty(ctx), false, /* sign doesn't matter */ "int_cast_to_i64", &*i); // Lazily bind the function to avoid always importing it. if (!divZeroCheckFunction) { Constant *fc = M.getOrInsertFunction("klee_div_zero_check", Type::getVoidTy(ctx), Type::getInt64Ty(ctx), NULL); divZeroCheckFunction = cast<Function>(fc); } CallInst * ci = CallInst::Create(divZeroCheckFunction, denominator, "", &*i); // Set debug location of checking call to that of the div/rem // operation so error locations are reported in the correct // location. ci->setDebugLoc(binOp->getDebugLoc()); moduleChanged = true; } } } } } return moduleChanged; }
bool RemoveExtendsPass::runOnFunction(Function& f) { CurrentFile::set(__FILE__); bool changed = false ; //see if there are any ROCCCNames or ROCCCSizes that caused the extend for(Function::iterator BB = f.begin(); BB != f.end(); ++BB) { begin: for(BasicBlock::iterator II = BB->begin(); II != BB->end(); ++II) { if( dynamic_cast<FPExtInst*>(&*II) or dynamic_cast<ZExtInst*>(&*II) or dynamic_cast<SExtInst*>(&*II) or dynamic_cast<BitCastInst*>(&*II) ) { INTERNAL_MESSAGE("Attempting to remove uses of " << II->getName() << "\n"); for(Value::use_iterator UI = II->use_begin(); UI != II->use_end(); ++UI) { dynamic_cast<Instruction*>(*UI)->replaceUsesOfWith(II, II->getOperand(0)); goto begin; } if( II->use_begin() == II->use_end() ) { II->eraseFromParent(); II = BB->begin(); } else { INTERNAL_ERROR("Extend " << *II << " is still used in " << **II->use_begin() << "!"); assert(0 and "Extend operation still exists!"); } } } } return changed ; }
void MutationGen::genMutationFile(Function & F){ int index = 0; for(Function::iterator FI = F.begin(); FI != F.end(); ++FI){ BasicBlock *BB = FI; #if NEED_LOOP_INFO bool isLoop = LI->getLoopFor(BB); #endif for(BasicBlock::iterator BI = BB->begin(); BI != BB->end(); ++BI, index++){ unsigned opc = BI->getOpcode(); if( !((opc >= 14 && opc <= 31) || opc == 34 || opc == 52 || opc == 55) ){// omit alloca and getelementptr continue; } int idxtmp = index; #if NEED_LOOP_INFO if(isLoop){ assert(idxtmp != 0); idxtmp = 0 - idxtmp; } #endif switch(opc){ case Instruction::Add: case Instruction::Sub: case Instruction::Mul: case Instruction::UDiv: case Instruction::SDiv: case Instruction::URem: case Instruction::SRem:{ // TODO: add for i1, i8. Support i32 and i64 first if(! (BI->getType()->isIntegerTy(32) || BI->getType()->isIntegerTy(64))){ continue; } genLVR(BI, F.getName(), idxtmp); genUOI(BI, F.getName(), idxtmp); genROV(BI, F.getName(), idxtmp); genABV(BI, F.getName(), idxtmp); genAOR(BI, F.getName(), idxtmp); break; } case Instruction::ICmp:{ if(! (BI->getOperand(0)->getType()->isIntegerTy(32) || BI->getOperand(0)->getType()->isIntegerTy(64)) ){ continue; } genLVR(BI, F.getName(), idxtmp); genUOI(BI, F.getName(), idxtmp); genROV(BI, F.getName(), idxtmp); genABV(BI, F.getName(), idxtmp); genROR(BI, F.getName(), idxtmp); break; } case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: case Instruction::And: case Instruction::Or: case Instruction::Xor:{ // TODO: add for i1, i8. Support i32 and i64 first if(! (BI->getType()->isIntegerTy(32) || BI->getType()->isIntegerTy(64))){ continue; } genLVR(BI, F.getName(), idxtmp); genUOI(BI, F.getName(), idxtmp); genROV(BI, F.getName(), idxtmp); genABV(BI, F.getName(), idxtmp); genLOR(BI, F.getName(), idxtmp); break; } case Instruction::Call: { CallInst* call = cast<CallInst>(BI); // TODO: omit function-pointer if(call->getCalledFunction() == NULL){ continue; } /*Value* callee = dyn_cast<Value>(&*(call->op_end() - 1)); if(callee->getType()->isPointerTy()){ continue; }*/ StringRef name = call->getCalledFunction()->getName(); if(name.startswith("llvm")){//omit llvm inside functions continue; } // TODO: add for ommiting i8. Support i32 and i64 first if(! ( isSupportedType(BI->getType())|| BI->getType()->isVoidTy() ) ){ continue; } genLVR(BI, F.getName(), idxtmp); genUOI(BI, F.getName(), idxtmp); genROV(BI, F.getName(), idxtmp); genABV(BI, F.getName(), idxtmp); genSTDCall(BI, F.getName(), idxtmp); break; } case Instruction::Store:{ auto addr = BI->op_begin() + 1;// the pointer of the storeinst if( ! (dyn_cast<LoadInst>(&*addr) || dyn_cast<AllocaInst>(&*addr) || dyn_cast<Constant>(&*addr) || dyn_cast<GetElementPtrInst>(&*addr) ) ){ continue; } // TODO:: add for i8 Value* tobestore = dyn_cast<Value>(BI->op_begin()); if(! isSupportedType(tobestore->getType())){ continue; } genLVR(BI, F.getName(), idxtmp); genUOI(BI, F.getName(), idxtmp); genABV(BI, F.getName(), idxtmp); genSTDStore(BI, F.getName(), idxtmp); break; } case Instruction::GetElementPtr:{ // TODO: break; } default:{ } } } } ofresult.flush(); }
void HeterotbbTransform::edit_template_function (Module &M,Function* F,Function* new_join,GlobalVariable *old_gb,Value *gb) { SmallVector<Value*, 16> Args; // Argument lists to the new call vector<Instruction *> toDelete; // old_gb->dump(); // gb->dump(); Constant *Ids[2]; for (Function::iterator BI=F->begin(),BE = F->end(); BI != BE; ++BI) { for (BasicBlock::iterator II = BI->begin(), IE = BI->end(); II != IE; ++II) { GetElementPtrInst *GEP; GlobalVariable *op; if (isa<CallInst>(II) || isa<InvokeInst>(II)) { CallSite CI(cast<Instruction>(II)); //replace dummy reduce with new reduce if(CI.getCalledFunction()->getName().equals("__join_reduce_hetero")) { Args.clear(); CastInst *newarg1 = CastInst::Create(Instruction::BitCast, CI.getArgument(0), new_join->arg_begin()->getType(), "arg1",CI.getInstruction()); Args.push_back(newarg1); CastInst *newarg2 = CastInst::Create(Instruction::BitCast, CI.getArgument(1), new_join->arg_begin()->getType(), "arg2", CI.getInstruction()); Args.push_back(newarg2); //no need to set attributes Instruction *NewCall = CallInst::Create(new_join, Args, "", CI.getInstruction()); cast<CallInst>(NewCall)->setCallingConv(CI.getCallingConv()); toDelete.push_back(CI.getInstruction()); DEBUG(dbgs()<<"Joins Replaced\n"); } } /* %arrayidx18 = getelementptr inbounds i32 addrspace(3)* getelementptr inbounds ([192 x i32] addrspace(3)* @opencl_kernel_join_name_local_arr, i32 0, i32 0), i64 %idxprom1 */ if((GEP = dyn_cast<GetElementPtrInst>(II)) /*&& (op = dyn_cast<GlobalVariable>(GEP->getOperand(0)))*/ /*&& (op->getName().equals("opencl_kernel_join_name_local_arr"))*/) { //II->dump(); Value *val= II->getOperand(0); if(Constant *op=dyn_cast<ConstantExpr>(val)) { //II->dump(); //II->getOperand(1)->dump(); /*Ids[0]=cast<Constant>(op->getOperand(1)); Ids[1]=cast<Constant>(op->getOperand(1)); Constant *new_op = ConstantExpr::getInBoundsGetElementPtr(cast<Constant>(gb),Ids,2); new_op->dump(); Instruction *inst = GetElementPtrInst::CreateInBounds(new_op, II->getOperand(1), II->getName()+"_temp",II); Value *Elts[] = {MDString::get(M.getContext(), "local_access")}; MDNode *Node = MDNode::get(M.getContext(), Elts); inst->setMetadata("local_access",Node); inst->dump(); II->replaceAllUsesWith(inst); toDelete.push_back(II); */ Value *Idxs[2] = {ConstantInt::get(Type::getInt32Ty(M.getContext()), 0), ConstantInt::get(Type::getInt32Ty(M.getContext()), 0) }; //gb->getType()->dump(); //gb->dump(); Instruction *inst_= GetElementPtrInst::CreateInBounds(gb, Idxs, /*Idxs+2,*/ II->getName()+"_temp_",II); //inst_->dump(); Instruction *inst= GetElementPtrInst::CreateInBounds(inst_, II->getOperand(1), II->getName()+"_temp",II); Value *Elts[] = {MDString::get(M.getContext(), inst->getName())}; MDNode *Node = MDNode::get(M.getContext(), Elts); inst->setMetadata("local_access",Node); //inst->dump(); II->replaceAllUsesWith(inst); toDelete.push_back(II); } } } } while(!toDelete.empty()) { Instruction *g = toDelete.back(); toDelete.pop_back(); g->eraseFromParent(); } }
bool GenericToNVVM::runOnModule(Module &M) { // Create a clone of each global variable that has the default address space. // The clone is created with the global address space specifier, and the pair // of original global variable and its clone is placed in the GVMap for later // use. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E;) { GlobalVariable *GV = &*I++; if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC && !llvm::isTexture(*GV) && !llvm::isSurface(*GV) && !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) { GlobalVariable *NewGV = new GlobalVariable( M, GV->getValueType(), GV->isConstant(), GV->getLinkage(), GV->hasInitializer() ? GV->getInitializer() : nullptr, "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL); NewGV->copyAttributesFrom(GV); GVMap[GV] = NewGV; } } // Return immediately, if every global variable has a specific address space // specifier. if (GVMap.empty()) { return false; } // Walk through the instructions in function defitinions, and replace any use // of original global variables in GVMap with a use of the corresponding // copies in GVMap. If necessary, promote constants to instructions. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (I->isDeclaration()) { continue; } IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg()); for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE; ++BBI) { for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE; ++II) { for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) { Value *Operand = II->getOperand(i); if (isa<Constant>(Operand)) { II->setOperand( i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder)); } } } } ConstantToValueMap.clear(); } // Copy GVMap over to a standard value map. ValueToValueMapTy VM; for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I) VM[I->first] = I->second; // Walk through the metadata section and update the debug information // associated with the global variables in the default address space. for (NamedMDNode &I : M.named_metadata()) { remapNamedMDNode(VM, &I); } // Walk through the global variable initializers, and replace any use of // original global variables in GVMap with a use of the corresponding copies // in GVMap. The copies need to be bitcast to the original global variable // types, as we cannot use cvta in global variable initializers. for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) { GlobalVariable *GV = I->first; GlobalVariable *NewGV = I->second; // Remove GV from the map so that it can be RAUWed. Note that // DenseMap::erase() won't invalidate any iterators but this one. auto Next = std::next(I); GVMap.erase(I); I = Next; Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType()); // At this point, the remaining uses of GV should be found only in global // variable initializers, as other uses have been already been removed // while walking through the instructions in function definitions. GV->replaceAllUsesWith(BitCastNewGV); std::string Name = GV->getName(); GV->eraseFromParent(); NewGV->setName(Name); } assert(GVMap.empty() && "Expected it to be empty by now"); return true; }
string getOperandName(BasicBlock::iterator inst) { return (inst->getOperand(1))->getName().str(); }
/// Determine whether the instructions in this range may be safely and cheaply /// speculated. This is not an important enough situation to develop complex /// heuristics. We handle a single arithmetic instruction along with any type /// conversions. static bool shouldSpeculateInstrs(BasicBlock::iterator Begin, BasicBlock::iterator End, Loop *L) { bool seenIncrement = false; bool MultiExitLoop = false; if (!L->getExitingBlock()) MultiExitLoop = true; for (BasicBlock::iterator I = Begin; I != End; ++I) { if (!isSafeToSpeculativelyExecute(I)) return false; if (isa<DbgInfoIntrinsic>(I)) continue; switch (I->getOpcode()) { default: return false; case Instruction::GetElementPtr: // GEPs are cheap if all indices are constant. if (!cast<GEPOperator>(I)->hasAllConstantIndices()) return false; // fall-thru to increment case case Instruction::Add: case Instruction::Sub: case Instruction::And: case Instruction::Or: case Instruction::Xor: case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: { Value *IVOpnd = !isa<Constant>(I->getOperand(0)) ? I->getOperand(0) : !isa<Constant>(I->getOperand(1)) ? I->getOperand(1) : nullptr; if (!IVOpnd) return false; // If increment operand is used outside of the loop, this speculation // could cause extra live range interference. if (MultiExitLoop) { for (User *UseI : IVOpnd->users()) { auto *UserInst = cast<Instruction>(UseI); if (!L->contains(UserInst)) return false; } } if (seenIncrement) return false; seenIncrement = true; break; } case Instruction::Trunc: case Instruction::ZExt: case Instruction::SExt: // ignore type conversions break; } } return true; }
void SuperBlock::fixSideEntrances() { // due to merging of BBs, some superblocks may have 1 BB remaining list<map<BasicBlock*, list<BasicBlock*> >::iterator > delSuperBlocks; for (map<BasicBlock*, list<BasicBlock*> >::iterator sp = superBlocks.begin(), sp_e = superBlocks.end(); sp != sp_e; ++sp) { // we need to keep track of the predecessor of the current basic block // being checked BasicBlock* prev = sp->first; // don't clone basic blocks if the code size threshold is achieved if (currCodeSize/originalCodeSize > CODE_EXPANSION_THRESHOLD) { break; } // the first basic block for a superblock need not be duplicated for (list<BasicBlock*>::iterator bb = sp->second.begin(), bb_e = sp->second.end(); bb != bb_e; ++bb) { // first, collect all predecessors for this BB // (note: we could not just iterate through as the predecessor set may // change list<BasicBlock*> predBBs; for (pred_iterator pred = pred_begin(*bb), pred_e = pred_end(*bb); pred != pred_e; ++pred) { predBBs.push_back(*pred); } // now, walk through all predecessors of this current basic block BasicBlock* clonedBB = NULL; for (list<BasicBlock*>::iterator pred = predBBs.begin(), pred_e = predBBs.end(); pred != pred_e; ++pred) { // if it is not the predecessor of this current basic block present in // the superblock, duplicate! if (*pred != prev) { // there is no need to clone this BB multiple times if (clonedBB == NULL) { ValueToValueMapTy vmap; // clone this basic block, and place the corresponding code after // the last BB of this superblock clonedBB = CloneBasicBlock(*bb, vmap, ".cloned", (*bb)->getParent()); vmap[*bb] = clonedBB; /* errs() << "@@ BEFORE: " << *clonedBB << "\n"; // fix phi nodes in the cloned BB for (BasicBlock::iterator I = clonedBB->begin(); isa<PHINode>(I); ++I) { PHINode* PN = dyn_cast<PHINode>(I); int bbIdx = PN->getBasicBlockIndex(prev); if (bbIdx != -1) { PN->removeIncomingValue(bbIdx, false); } } */ // add size of duplicated BBs to total code size count currCodeSize += clonedBB->size(); // modify operands in this basic block for (BasicBlock::iterator instr = clonedBB->begin(), instr_e = clonedBB->end(); instr != instr_e; ++instr) { for (unsigned idx = 0, num_ops = instr->getNumOperands(); idx < num_ops; ++idx) { Value* op = instr->getOperand(idx); ValueToValueMapTy::iterator op_it = vmap.find(op); if (op_it != vmap.end()) { instr->setOperand(idx, op_it->second); } } } } // remove phi nodes into this BB in the trace /* for (BasicBlock::iterator I = (*bb)->begin(); isa<PHINode>(I); ++I) { PHINode* PN = dyn_cast<PHINode>(I); int bbIdx = PN->getBasicBlockIndex(*pred); if (bbIdx != -1) { PN->removeIncomingValue(bbIdx, false); } } */ // modify the branch instruction of the predecessor not in the superblock to // branch to the cloned basic block Instruction* br_instr = (*pred)->getTerminator(); br_instr->replaceUsesOfWith((Value*)*bb, (Value*)clonedBB); } } // determine if we can merge the BB (definitely can be merged), and its clone // with theirpredecessors if (clonedBB != NULL) { if (MergeBlockIntoPredecessor(*bb, this)) { // since we have merged this BB, delete from our superblock mappings partOfSuperBlock.erase(*bb); bb = sp->second.erase(bb); --bb; if (sp->second.empty()) { delSuperBlocks.push_back(sp); } } MergeBlockIntoPredecessor(clonedBB, this); } prev = *bb; } } // erase some superblocks (which only have 1 BB remaining) for (list<map<BasicBlock*, list<BasicBlock*> >::iterator >::iterator del = delSuperBlocks.begin(), del_e = delSuperBlocks.end(); del != del_e; ++del) { superBlocks.erase(*del); } }
/// InputFilename is a LLVM bitcode file. Read it using bitcode reader. /// Collect global functions and symbol names in symbols vector. /// Collect external references in references vector. /// Return LTO_READ_SUCCESS if there is no error. enum LTOStatus LTO::readLLVMObjectFile(const std::string &InputFilename, NameToSymbolMap &symbols, std::set<std::string> &references) { Module *m = getModule(InputFilename); if (!m) return LTO_READ_FAILURE; // Collect Target info getTarget(m); if (!Target) return LTO_READ_FAILURE; // Use mangler to add GlobalPrefix to names to match linker names. // FIXME : Instead of hard coding "-" use GlobalPrefix. Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix()); modules.push_back(m); for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) { LTOLinkageTypes lt = getLTOLinkageType(f); LTOVisibilityTypes vis = getLTOVisibilityType(f); if (!f->isDeclaration() && lt != LTOInternalLinkage && strncmp (f->getName().c_str(), "llvm.", 5)) { int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment()); LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, f, f->getName(), mangler.getValueName(f), Log2_32(alignment)); symbols[newSymbol->getMangledName()] = newSymbol; allSymbols[newSymbol->getMangledName()] = newSymbol; } // Collect external symbols referenced by this function. for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b) for (BasicBlock::iterator i = b->begin(), be = b->end(); i != be; ++i) { for (unsigned count = 0, total = i->getNumOperands(); count != total; ++count) findExternalRefs(i->getOperand(count), references, mangler); } } for (Module::global_iterator v = m->global_begin(), e = m->global_end(); v != e; ++v) { LTOLinkageTypes lt = getLTOLinkageType(v); LTOVisibilityTypes vis = getLTOVisibilityType(v); if (!v->isDeclaration() && lt != LTOInternalLinkage && strncmp (v->getName().c_str(), "llvm.", 5)) { const TargetData *TD = Target->getTargetData(); LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, v, v->getName(), mangler.getValueName(v), TD->getPreferredAlignmentLog(v)); symbols[newSymbol->getMangledName()] = newSymbol; allSymbols[newSymbol->getMangledName()] = newSymbol; for (unsigned count = 0, total = v->getNumOperands(); count != total; ++count) findExternalRefs(v->getOperand(count), references, mangler); } } return LTO_READ_SUCCESS; }
bool ReplaceNopCastsAndByteSwaps::processBasicBlock(BasicBlock& BB) { bool Changed = false; /** * First pass: replace nopCasts with bitcasts and bswap intrinsics with logic operations */ for ( BasicBlock::iterator it = BB.begin(); it != BB.end(); ) { Instruction * Inst = it++; if (isNopCast(Inst) ) { assert( isa<CallInst>(Inst) ); CallInst * call = cast<CallInst>(Inst); if ( TypeSupport::isClientType( call->getType()) ) { llvm::errs() << "Cast of client type: " << *call << "\n"; continue; } if ( TypeSupport::isClientType( call->getArgOperand(0)->getType()) ) { llvm::errs() << "Cast of client type: " << *call->getArgOperand(0) << "\n"; continue; } ReplaceInstWithInst( call, BitCastInst::Create( Instruction::CastOps::BitCast, call->getArgOperand(0), call->getType() ) ); Changed = true; } else if( IntrinsicInst* II = dyn_cast<IntrinsicInst>(Inst) ) { if(II->getIntrinsicID() == Intrinsic::bswap) { IL->LowerIntrinsicCall(II); Changed = true; } else if(II->getIntrinsicID() == Intrinsic::cheerp_deallocate) { II->eraseFromParent(); Changed = true; } } } /** * Second pass: collapse bitcasts of bitcasts. * * Note: this might leave some dead instruction around, but we don't care since bitcasts are inlined anyway */ for ( BasicBlock::iterator it = BB.begin(); it != BB.end(); ++it ) { if ( isa<BitCastInst>(it) ) { while ( BitCastInst * src = dyn_cast<BitCastInst>(it->getOperand(0) ) ) { it->setOperand(0, src->getOperand(0) ); Changed = true; } } } return Changed; }
void TaskDebugBranchCheck::addFunctionSummaries(BasicBlock* from_bb, BasicBlock* to_bb, Instruction* first_inst) { //errs() << "++++++++++++++++++++DETECTED BRANCHES++++++++++++++++++++++\n"; //errs() << "BB 1 First inst: " << *(from_bb->getFirstNonPHI()) << "\n"; //TerminatorInst *TInst = from_bb->getTerminator(); //errs() << "BB 1 Last inst: " << *TInst << "\n\n"; //errs() << "BB 2 First inst: " << *(to_bb->getFirstNonPHI()) << "\n"; //TInst = to_bb->getTerminator(); //errs() << "BB 2 Last inst: " << *TInst << "\n\n"; //errs() << "++++++++++++++++++++DETECTED BRANCHES++++++++++++++++++++++\n"; std::vector<Value*> locks_acq; std::vector<Value*> locks_rel; bool startInst = false; for (BasicBlock::iterator i = from_bb->begin(); i != from_bb->end(); ++i) { if (startInst == false) { if (first_inst == dyn_cast<Instruction>(i)) { startInst = true; } else { continue; } } switch (i->getOpcode()) { case Instruction::Call: { CallInst* callInst = dyn_cast<CallInst>(i); if(callInst->getCalledFunction() != NULL) { if(callInst->getCalledFunction() == lockAcquire) { locks_acq.push_back(callInst->getArgOperand(1)); } else if (callInst->getCalledFunction() == lockRelease) { locks_rel.push_back(callInst->getArgOperand(1)); } } break; } case Instruction::Load: { //errs() << "LOAD INST " << *i << "\n"; Value* op_l = i->getOperand(0); if (hasAnnotation(i, op_l, "check_av", 1)) { Constant* read = ConstantInt::get(Type::getInt32Ty(to_bb->getContext()), 0); instrument_access(to_bb->getFirstNonPHI(), op_l, read, locks_acq, locks_rel); } break; } case Instruction::Store: { //errs() << "STR INST " << *i << "\n"; Value* op_s = i->getOperand(1); if (hasAnnotation(i, op_s, "check_av", 1)) { Constant* write = ConstantInt::get(Type::getInt32Ty(to_bb->getContext()), 1); instrument_access(to_bb->getFirstNonPHI(), op_s, write, locks_acq, locks_rel); } break; } } } }
void StatsTracker::computeReachableUncovered() { KModule *km = executor.kmodule; Module *m = km->module; static bool init = true; const InstructionInfoTable &infos = *km->infos; StatisticManager &sm = *theStatisticManager; if (init) { init = false; // Compute call targets. It would be nice to use alias information // instead of assuming all indirect calls hit all escaping // functions, eh? for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); fnIt != fn_ie; ++fnIt) { for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); bbIt != bb_ie; ++bbIt) { for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); it != ie; ++it) { if (isa<CallInst>(it) || isa<InvokeInst>(it)) { if (isa<InlineAsm>(it->getOperand(0))) { // We can never call through here so assume no targets // (which should be correct anyhow). callTargets.insert(std::make_pair(it, std::vector<Function*>())); } else if (Function *target = getDirectCallTarget(it)) { callTargets[it].push_back(target); } else { callTargets[it] = std::vector<Function*>(km->escapingFunctions.begin(), km->escapingFunctions.end()); } } } } } // Compute function callers as reflexion of callTargets. for (calltargets_ty::iterator it = callTargets.begin(), ie = callTargets.end(); it != ie; ++it) for (std::vector<Function*>::iterator fit = it->second.begin(), fie = it->second.end(); fit != fie; ++fit) functionCallers[*fit].push_back(it->first); // Initialize minDistToReturn to shortest paths through // functions. 0 is unreachable. std::vector<Instruction *> instructions; for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); fnIt != fn_ie; ++fnIt) { if (fnIt->isDeclaration()) { if (fnIt->doesNotReturn()) { functionShortestPath[fnIt] = 0; } else { functionShortestPath[fnIt] = 1; // whatever } continue; } else { functionShortestPath[fnIt] = 0; } KFunction *kf = km->functionMap[fnIt]; for (unsigned i = 0; i < kf->numInstructions; ++i) { Instruction *inst = kf->instrPostOrder[i]->inst; instructions.push_back(inst); sm.setIndexedValue(stats::minDistToReturn, kf->instrPostOrder[i]->info->id, isa<ReturnInst>(inst)); } } // I'm so lazy it's not even worklisted. bool changed; do { changed = false; for (std::vector<Instruction*>::iterator it = instructions.begin(), ie = instructions.end(); it != ie; ++it) { Instruction *inst = *it; unsigned bestThrough = 0; if (isa<CallInst>(inst) || isa<InvokeInst>(inst)) { std::vector<Function*> &targets = callTargets[inst]; for (std::vector<Function*>::iterator fnIt = targets.begin(), ie = targets.end(); fnIt != ie; ++fnIt) { uint64_t dist = functionShortestPath[*fnIt]; if (dist) { dist = 1+dist; // count instruction itself if (bestThrough==0 || dist<bestThrough) bestThrough = dist; } } } else { bestThrough = 1; } if (bestThrough) { unsigned id = infos.getInfo(*it).id; uint64_t best, cur = best = sm.getIndexedValue(stats::minDistToReturn, id); std::vector<Instruction*> succs = getSuccs(*it); for (std::vector<Instruction*>::iterator it2 = succs.begin(), ie = succs.end(); it2 != ie; ++it2) { uint64_t dist = sm.getIndexedValue(stats::minDistToReturn, infos.getInfo(*it2).id); if (dist) { uint64_t val = bestThrough + dist; if (best==0 || val<best) best = val; } } if (best != cur) { sm.setIndexedValue(stats::minDistToReturn, id, best); changed = true; // Update shortest path if this is the entry point. Function *f = inst->getParent()->getParent(); if (inst==f->begin()->begin()) functionShortestPath[f] = best; } } } } while (changed); } // compute minDistToUncovered, 0 is unreachable std::vector<Instruction *> instructions; std::vector<unsigned> ids; for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); fnIt != fn_ie; ++fnIt) { if (fnIt->isDeclaration()) continue; KFunction *kf = km->functionMap[fnIt]; for (unsigned i = 0; i < kf->numInstructions; ++i) { Instruction *inst = kf->instrPostOrder[i]->inst; unsigned id = kf->instrPostOrder[i]->info->id; instructions.push_back(inst); ids.push_back(id); sm.setIndexedValue(stats::minDistToGloballyUncovered, id, sm.getIndexedValue(stats::globallyUncoveredInstructions, id)); } } // I'm so lazy it's not even worklisted. bool changed; do { changed = false; for (unsigned i = 0; i < instructions.size(); ++i) { Instruction *inst = instructions[i]; unsigned id = ids[i]; uint64_t best, cur = best = sm.getIndexedValue(stats::minDistToGloballyUncovered, id); unsigned bestThrough = 0; if (isa<CallInst>(inst) || isa<InvokeInst>(inst)) { std::vector<Function*> &targets = callTargets[inst]; for (std::vector<Function*>::iterator fnIt = targets.begin(), ie = targets.end(); fnIt != ie; ++fnIt) { uint64_t dist = functionShortestPath[*fnIt]; if (dist) { dist = 1+dist; // count instruction itself if (bestThrough==0 || dist<bestThrough) bestThrough = dist; } if (!(*fnIt)->isDeclaration()) { uint64_t calleeDist = sm.getIndexedValue(stats::minDistToGloballyUncovered, infos.getFunctionInfo(*fnIt).id); if (calleeDist) { calleeDist = 1+calleeDist; // count instruction itself if (best==0 || calleeDist<best) best = calleeDist; } } } } else { bestThrough = 1; } if (bestThrough) { std::vector<Instruction*> succs = getSuccs(inst); for (std::vector<Instruction*>::iterator it2 = succs.begin(), ie = succs.end(); it2 != ie; ++it2) { uint64_t dist = sm.getIndexedValue(stats::minDistToGloballyUncovered, infos.getInfo(*it2).id); if (dist) { uint64_t val = bestThrough + dist; if (best==0 || val<best) best = val; } } } if (best != cur) { sm.setIndexedValue(stats::minDistToGloballyUncovered, infos.getInfo(inst).id, best); changed = true; } } } while (changed); for (std::set<ExecutionState*>::iterator it = executor.states.begin(), ie = executor.states.end(); it != ie; ++it) { ExecutionState *es = *it; uint64_t currentFrameMinDist = 0; for (ExecutionState::stack_ty::iterator sfIt = es->stack().begin(), sf_ie = es->stack().end(); sfIt != sf_ie; ++sfIt) { ExecutionState::stack_ty::iterator next = sfIt + 1; KInstIterator kii; if (next==es->stack().end()) { kii = es->pc(); } else { kii = next->caller; ++kii; } sfIt->minDistToUncoveredOnReturn = currentFrameMinDist; currentFrameMinDist = computeMinDistToUncovered(kii, currentFrameMinDist); } } LOG(INFO) << "Processed " << instructions.size() << " instructions in static analysis"; }
/// eliminateUnconditionalBranch - Clone the instructions from the destination /// block into the source block, eliminating the specified unconditional branch. /// If the destination block defines values used by successors of the dest /// block, we may need to insert PHI nodes. /// void TailDup::eliminateUnconditionalBranch(BranchInst *Branch) { BasicBlock *SourceBlock = Branch->getParent(); BasicBlock *DestBlock = Branch->getSuccessor(0); assert(SourceBlock != DestBlock && "Our predicate is broken!"); DEBUG(errs() << "TailDuplication[" << SourceBlock->getParent()->getName() << "]: Eliminating branch: " << *Branch); // See if we can avoid duplicating code by moving it up to a dominator of both // blocks. if (BasicBlock *DomBlock = FindObviousSharedDomOf(SourceBlock, DestBlock)) { DEBUG(errs() << "Found shared dominator: " << DomBlock->getName() << "\n"); // If there are non-phi instructions in DestBlock that have no operands // defined in DestBlock, and if the instruction has no side effects, we can // move the instruction to DomBlock instead of duplicating it. BasicBlock::iterator BBI = DestBlock->getFirstNonPHI(); while (!isa<TerminatorInst>(BBI)) { Instruction *I = BBI++; bool CanHoist = I->isSafeToSpeculativelyExecute() && !I->mayReadFromMemory(); if (CanHoist) { for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) if (Instruction *OpI = dyn_cast<Instruction>(I->getOperand(op))) if (OpI->getParent() == DestBlock || (isa<InvokeInst>(OpI) && OpI->getParent() == DomBlock)) { CanHoist = false; break; } if (CanHoist) { // Remove from DestBlock, move right before the term in DomBlock. DestBlock->getInstList().remove(I); DomBlock->getInstList().insert(DomBlock->getTerminator(), I); DEBUG(errs() << "Hoisted: " << *I); } } } } // Tail duplication can not update SSA properties correctly if the values // defined in the duplicated tail are used outside of the tail itself. For // this reason, we spill all values that are used outside of the tail to the // stack. for (BasicBlock::iterator I = DestBlock->begin(); I != DestBlock->end(); ++I) if (I->isUsedOutsideOfBlock(DestBlock)) { // We found a use outside of the tail. Create a new stack slot to // break this inter-block usage pattern. DemoteRegToStack(*I); } // We are going to have to map operands from the original block B to the new // copy of the block B'. If there are PHI nodes in the DestBlock, these PHI // nodes also define part of this mapping. Loop over these PHI nodes, adding // them to our mapping. // std::map<Value*, Value*> ValueMapping; BasicBlock::iterator BI = DestBlock->begin(); bool HadPHINodes = isa<PHINode>(BI); for (; PHINode *PN = dyn_cast<PHINode>(BI); ++BI) ValueMapping[PN] = PN->getIncomingValueForBlock(SourceBlock); // Clone the non-phi instructions of the dest block into the source block, // keeping track of the mapping... // for (; BI != DestBlock->end(); ++BI) { Instruction *New = BI->clone(); New->setName(BI->getName()); SourceBlock->getInstList().push_back(New); ValueMapping[BI] = New; } // Now that we have built the mapping information and cloned all of the // instructions (giving us a new terminator, among other things), walk the new // instructions, rewriting references of old instructions to use new // instructions. // BI = Branch; ++BI; // Get an iterator to the first new instruction for (; BI != SourceBlock->end(); ++BI) for (unsigned i = 0, e = BI->getNumOperands(); i != e; ++i) { std::map<Value*, Value*>::const_iterator I = ValueMapping.find(BI->getOperand(i)); if (I != ValueMapping.end()) BI->setOperand(i, I->second); } // Next we check to see if any of the successors of DestBlock had PHI nodes. // If so, we need to add entries to the PHI nodes for SourceBlock now. for (succ_iterator SI = succ_begin(DestBlock), SE = succ_end(DestBlock); SI != SE; ++SI) { BasicBlock *Succ = *SI; for (BasicBlock::iterator PNI = Succ->begin(); isa<PHINode>(PNI); ++PNI) { PHINode *PN = cast<PHINode>(PNI); // Ok, we have a PHI node. Figure out what the incoming value was for the // DestBlock. Value *IV = PN->getIncomingValueForBlock(DestBlock); // Remap the value if necessary... std::map<Value*, Value*>::const_iterator I = ValueMapping.find(IV); if (I != ValueMapping.end()) IV = I->second; PN->addIncoming(IV, SourceBlock); } } // Next, remove the old branch instruction, and any PHI node entries that we // had. BI = Branch; ++BI; // Get an iterator to the first new instruction DestBlock->removePredecessor(SourceBlock); // Remove entries in PHI nodes... SourceBlock->getInstList().erase(Branch); // Destroy the uncond branch... // Final step: now that we have finished everything up, walk the cloned // instructions one last time, constant propagating and DCE'ing them, because // they may not be needed anymore. // if (HadPHINodes) { while (BI != SourceBlock->end()) { Instruction *Inst = BI++; if (isInstructionTriviallyDead(Inst)) Inst->eraseFromParent(); else if (Constant *C = ConstantFoldInstruction(Inst)) { Inst->replaceAllUsesWith(C); Inst->eraseFromParent(); } } } ++NumEliminated; // We just killed a branch! }
void transform(Module &M,Function &f,vector <BasicBlock*> &BB1,vector <BasicBlock*> &BB2,vector<Instruction*>I1,vector<Instruction*>I2) { LLVMContext &context = M.getContext(); Instruction *br,*I; Type* Int1= Type::getInt8PtrTy(context); Type *typpe=Type::getInt32Ty(context); Type* voidd= Type::getVoidTy(context); vector <BasicBlock*> BB3,BB4,contt,tran; vector<Instruction*>inst1,inst2; BasicBlock *bt; Instruction *in; unsigned i=0; Function *under_over = cast<Function>(M.getOrInsertFunction ("llvm.x86.sse.stmxcsr",voidd,Int1,nullptr));//function how test condition(overflow,underflow...) //*******************************take the basic block and his copy of the highest type******************** for (Function::iterator blocdebase = f.begin(), e = f.end(); blocdebase != e; ++blocdebase) { unsigned n=Search(BB1,blocdebase); if(n<BB1.size()) { BB3.push_back(BB1[n]); BB4.push_back(BB2[n]); } } //********************************take the instruction of each block ******************************* bt=f.begin(); for(unsigned i=0;i<BB3.size();i++) { for(BasicBlock::iterator instruction = BB3[i]->begin(), ee = BB3[i]->end(); instruction != ee; ++instruction) { if (dyn_cast<LoadInst>(instruction)) { //from read instruction unsigned n=Searchinst(I2,dyn_cast<Instruction>(instruction->getOperand(0))); unsigned n1=Searchinst(inst2,dyn_cast<Instruction>(instruction->getOperand(0))); if(n<I2.size()&&n1>inst2.size()) { inst2.push_back(I2[n]);//copy instruction inst1.push_back(I1[n]);//orginal instruction } } if (dyn_cast<StoreInst>(instruction)) { //from write instruction unsigned n=Searchinst(I2,dyn_cast<Instruction>(instruction->getOperand(0))); unsigned n1=Searchinst(inst2,dyn_cast<Instruction>(instruction->getOperand(0))); unsigned n2=Searchinst(I2,dyn_cast<Instruction>(instruction->getOperand(1))); unsigned n3=Searchinst(inst2,dyn_cast<Instruction>(instruction->getOperand(1))); if(n<I2.size()&&n1>inst2.size()){inst2.push_back(I2[n]);inst1.push_back(I1[n]);} else if(n2<I2.size()&&n3>inst2.size()){inst2.push_back(I2[n2]);inst1.push_back(I1[n2]);} } } } while(i<BB3.size()) { BasicBlock *cont = BasicBlock::Create(context, "continue", BB3[i]->getParent());//block that allows to continue in the same way BasicBlock *transforms = BasicBlock::Create(context, "transforms", BB3[i]->getParent());//block that do the transformation I= BB3[i]->getTerminator(); br=I->clone(); I->eraseFromParent(); //*********************************test to choose what to do************************* AllocaInst *test = new AllocaInst(typpe,0, "test",BB3[i]); BitCastInst *newb= new BitCastInst(test,Int1," ",BB3[i]); CallInst::Create(under_over, newb, "",BB3[i]); LoadInst *Cov=new LoadInst(test,"",false,BB3[i]); Value *one = ConstantInt::get(Type::getInt32Ty(context), 63); Value *two = ConstantInt::get(Type::getInt32Ty(context), 16); Value *three = ConstantInt::get(Type::getInt32Ty(context), 8); BinaryOperator *te1 = BinaryOperator::Create(Instruction::And,Cov,one,"",BB3[i]); BinaryOperator *te2 = BinaryOperator::Create(Instruction::And,te1,two,"",BB3[i]); BinaryOperator *te3 = BinaryOperator::Create(Instruction::And,Cov,three,"",BB3[i]); BinaryOperator *te4 = BinaryOperator::Create(Instruction::Or,te3,te2,"",BB3[i]); Value *z = ConstantInt::get(Type::getInt32Ty(context), 0); Value *CondI = new ICmpInst(*BB3[i], ICmpInst::ICMP_NE, te4,z , "cond"); //************************************************************************ BranchInst::Create (transforms,cont ,CondI,BB3[i]);// branch to the block of continue BranchInst::Create(BB4[i],transforms);// branch to the block copy cont->getInstList().push_back(br);// branch to the next block contt.push_back(cont);//take all the continents blocks tran.push_back(transforms);//take all the transformations blocks i++; } BB3.clear(); BB4.clear(); i=0; while(i<contt.size()) { I= contt[i]->getTerminator(); int size= I1.size(); for(unsigned a=0;a<inst1.size();a++) { LoadInst *new_load = new LoadInst(inst2[a],"Nl",false,I);//load the copy value new StoreInst(new_load,inst1[a] , false,I);//store the copy value in original value //********************************************************************** in= tran[i]->getTerminator(); LoadInst *new_load1 = new LoadInst(inst1[a],"e",false,in);//load the original value of original block int id=Searchinst(I1,inst1[a]); AllocaInst *t=dyn_cast<AllocaInst>(I1[(id+(size/3))]); Type *T=t->getAllocatedType (); if(inst1[a]->getType()==I1[(id+(size/3))]->getType())//same type of original value of copy block { new StoreInst(new_load1,I1[(id+(size/3))] , false,4,in); } else//different type { FPExtInst *c= new FPExtInst (new_load1,T , "",in); new StoreInst(c,I1[(id+(size/3))] , false,in); } } i++; } inst1.clear(); contt.clear(); }