void PhiElimination::splitCriticalEdge( IRFunction * func, BasicBlock * block) { //if (block->numOfPrecursors() <= 1) // return; auto GetInnerBlock = [func, block] (const std::string &from, const std::string &to) { BasicBlock *BB = func->createBasicBlock(from + "-" + to); Goto *go2 = IRContext::create<Goto>(block); BB->push_back(go2); BB->addSuccessor(block); go2->set_parent(BB); return BB; }; size_t size = block->numOfPrecursors(); for (auto pre = block->precursor_begin(); pre != block->precursor_end(); ++pre) { BasicBlock *PBB = *pre; // Check whether split. if (PBB->numOfSuccessors() <= 1) continue; // split it. BasicBlock *BB = GetInnerBlock( PBB->getBlockName(), block->getBlockName()); *pre = BB; PBB->successor_replace(block, BB); if (PBB->back()->is_goto()) { Goto *GT = static_cast<Goto*>(PBB->back()); GT->setTarget(BB); } else if (PBB->back()->is_branch()) { Branch *branch = static_cast<Branch*>(PBB->back()); if (branch->then() == block) branch->setThen(BB); else branch->setElse(BB); } else { assert(0 && "impossible"); } } }
// // Override the runOnLoop function provided by LoopPass. // Return true because we intend on modifying the control flow graph. // bool LicmPass::runOnLoop(Loop *loop, LPPassManager &LPM) { unsigned int depth = loop->getLoopDepth(); info = &getAnalysis<LoopInfo>(); cout << "Loop<depth = " << depth << ">" << endl; // check if there is a preheader BasicBlock* preheader = loop->getLoopPreheader(); if (!preheader) { return false; } // Run analysis passes on blocks. const BlockVector& blocks = loop->getBlocks(); BlockStates states = dominance.runOnBlocks(blocks); showDominators(blocks, states, preheader); // Cache all the invariants we have found so far. Invariants invariants; findInvariants(loop, blocks, states, preheader, invariants); // Finally, hoist the invariants into the preheader. // We want to delete this instruction and move it to the end of the // preheader (before the branch). We can do with with moveBefore. for (Invariants::iterator I = invariants.begin(), IE = invariants.end(); I != IE; ++I) { Instruction* end = &(preheader->back()); Instruction* instr = *I; instr->moveBefore(end); } // assume we modified the loop return true; };
bool CFGTree::identifySuccessorRelation(BasicBlock *predBB, BasicBlock *succBB) { bool identify = false; BasicBlock *bb = predBB; while (true) { Instruction *inst = &(bb->back()); if (inst->getOpcode() == Instruction::Br) { BranchInst *bi = dyn_cast<BranchInst>(inst); if (bi->isUnconditional()) { bb = bi->getSuccessor(0); if (bb == succBB) { identify = true; break; } } else { identify = foundSameBrInstFromCFGTree(inst, root); break; } } else { if (inst->getOpcode() == Instruction::Ret) break; else assert(false && "Unsupported instruction!"); } } return identify; }
// TransformLongJmpCall - Transform a longjmp call into a call to the // internal __llvm_sjljeh_throw_longjmp function. It then takes care of // throwing the exception for us. void LowerSetJmp::TransformLongJmpCall(CallInst* Inst) { const Type* SBPTy = PointerType::getUnqual(Type::getInt8Ty(Inst->getContext())); // Create the call to "__llvm_sjljeh_throw_longjmp". This takes the // same parameters as "longjmp", except that the buffer is cast to a // char*. It returns "void", so it doesn't need to replace any of // Inst's uses and doesn't get a name. CastInst* CI = new BitCastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst); SmallVector<Value *, 2> Args; Args.push_back(CI); Args.push_back(Inst->getOperand(2)); CallInst::Create(ThrowLongJmp, Args.begin(), Args.end(), "", Inst); SwitchValuePair& SVP = SwitchValMap[Inst->getParent()->getParent()]; // If the function has a setjmp call in it (they are transformed first) // we should branch to the basic block that determines if this longjmp // is applicable here. Otherwise, issue an unwind. if (SVP.first) BranchInst::Create(SVP.first->getParent(), Inst); else new UnwindInst(Inst->getContext(), Inst); // Remove all insts after the branch/unwind inst. Go from back to front to // avoid replaceAllUsesWith if possible. BasicBlock *BB = Inst->getParent(); Instruction *Removed; do { Removed = &BB->back(); // If the removed instructions have any users, replace them now. if (!Removed->use_empty()) Removed->replaceAllUsesWith(UndefValue::get(Removed->getType())); Removed->eraseFromParent(); } while (Removed != Inst); ++LongJmpsTransformed; }
/// canBasicBlockModify - Return true if it is possible for execution of the /// specified basic block to modify the location Loc. /// bool AAResults::canBasicBlockModify(const BasicBlock &BB, const MemoryLocation &Loc) { return canInstructionRangeModRef(BB.front(), BB.back(), Loc, MRI_Mod); }
bool FuncAddrTaken::runOnModule(Module &M) { bool Changed = false; // add declaration of function __patch_at // declare void @__patch_at(void) FunctionType *FT = FunctionType::get(Type::getVoidTy(M.getContext()), false); Function* PatchAt = Function::Create(FT, Function::ExternalLinkage, "__patch_at", &M); if (PatchAt->getName() != "__patch_at") { PatchAt->eraseFromParent(); return false; } Changed = true; // Simple optimization so that no function address will be taken twice // in the same basic block. std::map<BasicBlock*, std::set<std::string> > UniqPatchAt; // before each store instruction that manipulates a function, create a call // to __patch_at for (auto F = M.getFunctionList().begin(); F != M.getFunctionList().end(); F++) { for (auto BB = F->begin(); BB != F->end(); BB++) { for (auto MI = BB->begin(); MI != BB->end(); MI++) { if (isa<StoreInst>(MI)) { // check if the store inst moves a function to a variable Value *V = InnerMost(cast<StoreInst>(MI)->getValueOperand()); addPatchAt(M, FT, V, MI, UniqPatchAt); if (isa<ConstantVector>(V)) { std::set<Value*> patched; for (unsigned i = 0; i < cast<ConstantVector>(V)->getNumOperands(); i++) { Value *VV = InnerMost(cast<ConstantVector>(V)->getOperand(i)); if (patched.find(VV) == patched.end()) { addPatchAt(M, FT, VV, MI, UniqPatchAt); patched.insert(VV); } } } else if (isa<ConstantStruct>(V)) { std::set<Value*> patched; for (unsigned i = 0; i < cast<ConstantStruct>(V)->getNumOperands(); i++) { Value *VV = InnerMost(cast<ConstantStruct>(V)->getOperand(i)); if (patched.find(VV) == patched.end()) { addPatchAt(M, FT, VV, MI, UniqPatchAt); patched.insert(VV); } } } else if (isa<ConstantArray>(V)) { std::set<Value*> patched; for (unsigned i = 0; i < cast<ConstantArray>(V)->getNumOperands(); i++) { Value *VV = InnerMost(cast<ConstantArray>(V)->getOperand(i)); if (patched.find(VV) == patched.end()) { addPatchAt(M, FT, VV, MI, UniqPatchAt); patched.insert(VV); } } } } else if (isa<SelectInst>(MI)) { Value *V = InnerMost(cast<SelectInst>(MI)->getTrueValue()); addPatchAt(M, FT, V, MI, UniqPatchAt); V = InnerMost(cast<SelectInst>(MI)->getFalseValue()); addPatchAt(M, FT, V, MI, UniqPatchAt); } else if (isa<CallInst>(MI)) { CallInst* CI = cast<CallInst>(MI); for (unsigned i = 0; i < CI->getNumArgOperands(); i++) { Value *V = InnerMost(CI->getArgOperand(i)); addPatchAt(M, FT, V, MI, UniqPatchAt); } } else if (isa<InvokeInst>(MI)) { InvokeInst* CI = cast<InvokeInst>(MI); for (unsigned i = 0; i < CI->getNumArgOperands(); i++) { Value *V = InnerMost(CI->getArgOperand(i)); addPatchAt(M, FT, V, MI, UniqPatchAt); } } else if (isa<ReturnInst>(MI)) { Value *V = cast<ReturnInst>(MI)->getReturnValue(); if (V) { V = InnerMost(V); addPatchAt(M, FT, V, MI, UniqPatchAt); } } else if (isa<PHINode>(MI)) { for (unsigned i = 0; i < cast<PHINode>(MI)->getNumIncomingValues(); i++) { Value *V = InnerMost(cast<PHINode>(MI)->getIncomingValue(i)); BasicBlock* BB = cast<PHINode>(MI)->getIncomingBlock(i); // right before the last (maybe terminator) instruction. addPatchAt(M, FT, V, &(BB->back()), UniqPatchAt); } } } } } // TODO: separate the following virtual table traversal code into another pass for (auto G = M.getGlobalList().begin(); G != M.getGlobalList().end(); G++) { if (isa<GlobalVariable>(G) && cast<GlobalVariable>(G)->hasInitializer()) { const GlobalVariable *GV = cast<GlobalVariable>(G); const Constant *C = GV->getInitializer(); if (GV->hasName() && isa<ConstantArray>(C) && GV->getName().startswith("_ZTV")) { std::string VTName = CXXDemangledName(GV->getName().data()); if (VTName.size() && VTName.find("vtable") == 0) { //llvm::errs() << VTName << "\n"; VTName = VTName.substr(11); // get pass "vtable for " llvm::NamedMDNode* MD = M.getOrInsertNamedMetadata("MCFIVtable"); std::string info = VTName; for (unsigned i = 0; i < cast<ConstantArray>(C)->getNumOperands(); i++) { Value *V = InnerMost(cast<ConstantArray>(C)->getOperand(i)); if (isa<Function>(V) && cast<Function>(V)->hasName()) { //llvm::errs() << cast<Function>(V)->getName() << "\n"; info += std::string("#") + cast<Function>(V)->getName().str(); } } MD->addOperand(llvm::MDNode::get(M.getContext(), llvm::MDString::get( M.getContext(), info.c_str()))); } } } } return Changed; }
/// canBasicBlockModify - Return true if it is possible for execution of the /// specified basic block to modify the value pointed to by Ptr. /// bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB, const Location &Loc) { return canInstructionRangeModify(BB.front(), BB.back(), Loc); }
bool ObjCARCContract::runOnFunction(Function &F) { if (!EnableARCOpts) return false; // If nothing in the Module uses ARC, don't do anything. if (!Run) return false; Changed = false; AA = &getAnalysis<AliasAnalysis>(); DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); PA.setAA(&getAnalysis<AliasAnalysis>()); DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n"); // Track whether it's ok to mark objc_storeStrong calls with the "tail" // keyword. Be conservative if the function has variadic arguments. // It seems that functions which "return twice" are also unsafe for the // "tail" argument, because they are setjmp, which could need to // return to an earlier stack state. bool TailOkForStoreStrongs = !F.isVarArg() && !F.callsFunctionThatReturnsTwice(); // For ObjC library calls which return their argument, replace uses of the // argument with uses of the call return value, if it dominates the use. This // reduces register pressure. SmallPtrSet<Instruction *, 4> DependingInstructions; SmallPtrSet<const BasicBlock *, 4> Visited; for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) { Instruction *Inst = &*I++; DEBUG(dbgs() << "Visiting: " << *Inst << "\n"); // First try to peephole Inst. If there is nothing further we can do in // terms of undoing objc-arc-expand, process the next inst. if (tryToPeepholeInstruction(F, Inst, I, DependingInstructions, Visited, TailOkForStoreStrongs)) continue; // Otherwise, try to undo objc-arc-expand. // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts // and such; to do the replacement, the argument must have type i8*. Value *Arg = cast<CallInst>(Inst)->getArgOperand(0); // TODO: Change this to a do-while. for (;;) { // If we're compiling bugpointed code, don't get in trouble. if (!isa<Instruction>(Arg) && !isa<Argument>(Arg)) break; // Look through the uses of the pointer. for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE; ) { // Increment UI now, because we may unlink its element. Use &U = *UI++; unsigned OperandNo = U.getOperandNo(); // If the call's return value dominates a use of the call's argument // value, rewrite the use to use the return value. We check for // reachability here because an unreachable call is considered to // trivially dominate itself, which would lead us to rewriting its // argument in terms of its return value, which would lead to // infinite loops in GetArgRCIdentityRoot. if (DT->isReachableFromEntry(U) && DT->dominates(Inst, U)) { Changed = true; Instruction *Replacement = Inst; Type *UseTy = U.get()->getType(); if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) { // For PHI nodes, insert the bitcast in the predecessor block. unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo); BasicBlock *BB = PHI->getIncomingBlock(ValNo); if (Replacement->getType() != UseTy) Replacement = new BitCastInst(Replacement, UseTy, "", &BB->back()); // While we're here, rewrite all edges for this PHI, rather // than just one use at a time, to minimize the number of // bitcasts we emit. for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) if (PHI->getIncomingBlock(i) == BB) { // Keep the UI iterator valid. if (UI != UE && &PHI->getOperandUse( PHINode::getOperandNumForIncomingValue(i)) == &*UI) ++UI; PHI->setIncomingValue(i, Replacement); } } else { if (Replacement->getType() != UseTy) Replacement = new BitCastInst(Replacement, UseTy, "", cast<Instruction>(U.getUser())); U.set(Replacement); } } } // If Arg is a no-op casted pointer, strip one level of casts and iterate. if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg)) Arg = BI->getOperand(0); else if (isa<GEPOperator>(Arg) && cast<GEPOperator>(Arg)->hasAllZeroIndices()) Arg = cast<GEPOperator>(Arg)->getPointerOperand(); else if (isa<GlobalAlias>(Arg) && !cast<GlobalAlias>(Arg)->mayBeOverridden()) Arg = cast<GlobalAlias>(Arg)->getAliasee(); else break; } } // If this function has no escaping allocas or suspicious vararg usage, // objc_storeStrong calls can be marked with the "tail" keyword. if (TailOkForStoreStrongs) for (CallInst *CI : StoreStrongCalls) CI->setTailCall(); StoreStrongCalls.clear(); return Changed; }
set<Strator::StratorWorker::LockSet>& Strator::StratorWorker::traverseStatement(const Function& f, const BasicBlock::const_iterator& inst, const Strator::StratorWorker::LockSet& entryLockSet, Strator::StratorWorker::LockSet lockSet){ // cerr << "@: "; // llvm::errs() << *inst; // cerr << endl; //if (f.getName() == "queueDelete") // printMultithreaded(); if(stratorStatementMap.find(&(*inst)) == stratorStatementMap.end()){ stratorStatementMap[&(*inst)] = new StratorStatement(); } StratorStatement* sStmt= stratorStatementMap[&(*inst)]; /// Check the statement cache, if the lockset is in the cache, don't analyze if(sStmt->statementCache.isInCache(entryLockSet, lockSet)){ set<Strator::StratorWorker::LockSet>* emptySet = new set<Strator::StratorWorker::LockSet>(); return *emptySet; } /// Otherwise add (entryLockSet, lockSet) to the cache sStmt->statementCache.addToCache(entryLockSet, lockSet); /// Terminator instructions for our analysis: /// Ret /// IndirectBr: Probably this is one such instruction for us, /// as we evaluate more systems, we'll see what happens if we use it if(inst->getOpcode() == Instruction::IndirectBr){ printLocation(*inst); assert(false && "We hit an indirect branch\n"); } if(inst->getOpcode() == Instruction::Ret){ set<Strator::StratorWorker::LockSet>* returnSet = new set<Strator::StratorWorker::LockSet>(); returnSet->insert(lockSet); return *returnSet; } #undef DEBUG_TYPE #define DEBUG_TYPE "strator-parval" if(inst->getOpcode() == Instruction::BitCast){ DEBUG(errs() << *inst << " = " << *inst->getOperand(0) << "\n"); parentValue[&*inst] = inst->getOperand(0); } vector<LockSet>* workingList = new vector<StratorWorker::LockSet>(); /// TODO: What do we do with invoke? if(inst->getOpcode() == Instruction::Call) { const CallInst* callInst = dyn_cast<CallInst>(&(*inst)); assert(callInst && "Call inst pointer is NULL!!!, this shouldn't have happened"); Function* calledFunc = callInst->getCalledFunction(); StratorFunction* sFunc = NULL; if(UpwardPropagationLevel != 0 ){ sFunc = getStratorFunction(calledFunc); sFunc->currentCaller = &f; } /// Since we don't have a lock intrinsic or anything like that, /// we will discover locks and unlocks upon function calls. assert((((int)inst->getNumOperands())-1) >= 0 && "Something wrong with the operands of call instruction"); if(isMultiThreadedAPI(inst->getOperand(inst->getNumOperands() -1 ))){ multithreadedFunctionMap[f.getName().str()] = true; /// Now check if we also want to propagete the "multithreadedness" to callers: /// If the called function is a thread-related function, then the parent function(s) /// are added to a a multithreadedAPI set depending on the propagation level which is /// checked in subsequent calls to isMultiThreadedAPI if(UpwardPropagationLevel != 0){ /// move up to the parents of this call to mark all of them as multithreaded for(unsigned i=0; i<UpwardPropagationLevel; ++i){ const Function* caller = sFunc->currentCaller; if(!caller) break; else { /// The upper level function becomes a multithreaded API, son any /// subsequent caller of such functions also become multithreaded. multithreadedAPISet.insert(caller); /// They also become multithreaded functions themselves multithreadedFunctionMap[caller->getName().str()] = true; sFunc = getStratorFunction(caller); } } } } if(calledFunc){ if (isLock(calledFunc)){ Lock l = getLockValue(&(*inst)); if(PrintLockUnlock) cerr << "lock inst:" << l << endl; if(l) lockSet.insert(l); } else if (isUnLock(calledFunc)){ Lock l = getLockValue(&(*inst)); if(PrintLockUnlock) cerr << "unlock inst:" << l << endl; if(l) lockSet.erase(l); } else{ bool atThreadCreationFunction = false; /// Now check if we have a resolved call, that is a direct function call /// We have a resolved function call if(isThreadCreationFunction(calledFunc->getName().str())) { /// If the created function is a thread creation function we /// need to find the worker function operand and traverse it atThreadCreationFunction = true; calledFunc = getThreadWorkerFunction(callInst); } /// Check if the current function is a multithreaded API if(multithreadedFunctionMap[f.getName().str()]){ /// If so, the current callee also becomes multithreaded multithreadedFunctionMap[calledFunc->getName().str()] = true; } #undef DEBUG_TYPE #define DEBUG_TYPE "strator-parval" /// We pass some values to the called function, updating flow sensitive value map CallSite cs(const_cast<CallInst*>(callInst)); Function::arg_iterator calleeIt; CallSite::arg_iterator callerIt; if(atThreadCreationFunction) { /// this is only supported for pthread right now assert(cs.arg_size() == 4 && "pthread_create should have 4 operands!"); assert(calledFunc->arg_size() == 1 && "pthread thread worker function should have 1 operand"); DEBUG(errs() << *calledFunc->arg_begin() << " = " << *cs.getArgument(3) << "\n"); parentValue[calledFunc->arg_begin()] = cs.getArgument(3); }else{ for (callerIt = cs.arg_begin(), calleeIt = calledFunc->arg_begin(); callerIt != cs.arg_end() && calleeIt != calledFunc->arg_end(); callerIt++, calleeIt++){ DEBUG(errs() << *calleeIt << " = " << *(callerIt->get()) << "\n"); parentValue[calleeIt] = callerIt->get(); } } set<StratorWorker::LockSet>& functionLockSets = traverseFunction(*calledFunc, lockSet); /// Maybe the called function was multi threaded: If so, the caller becomes multi /// threaded from this point on if the following two lines are uncommented. /// However, this support adds a large number of false positives /* if(multithreadedFunctionMap[calledFunc->getName().str()]) multithreadedFunctionMap[f.getName().str()] = true; */ /// arguments of callee are no longer valid, updating flow sensitive value map for (calleeIt = calledFunc->arg_begin(); calleeIt != calledFunc->arg_end(); calleeIt++){ parentValue.erase(calleeIt); } workingList->insert(workingList->begin(), functionLockSets.begin(), functionLockSets.end()); } } else { /// call is not resolved, process the lockset at hand as the working set workingList->insert(workingList->begin(), lockSet); } } /// TODO: We can leverage the llvm function onlyreadsmemory maybe? At least look at the code if(inst->getOpcode() == Instruction::Load || inst->getOpcode() == Instruction::Store){ detectRaces(*inst, (inst->getOpcode() == Instruction::Store), lockSet); } /// If this is the last instruction of the current BB /// it means from here we have successor nodes in the control flow. set<StratorWorker::LockSet>* returnSet = new set<StratorWorker::LockSet>(); BasicBlock* bb = const_cast<BasicBlock*>(inst->getParent()); /// TODO: try to check for terminator instruction here vector<StratorWorker::LockSet>::iterator workingListLockset; if(workingList->size() > 0){ if(&(bb->back()) == &(*inst)){ for(workingListLockset = workingList->begin(); workingListLockset != workingList->end(); ++workingListLockset) for(succ_iterator child = succ_begin(bb), end = succ_end(bb); child != end; ++child){ BasicBlock::iterator firstInstr = child->begin(); set<Strator::StratorWorker::LockSet>& statementLockSets = traverseStatement(f, firstInstr, entryLockSet, *workingListLockset); returnSet->insert(statementLockSets.begin(), statementLockSets.end()); } } else{ /// not the last instruction, simply instruction pointer to the next instruction BasicBlock::const_iterator nextInst = inst; ++nextInst; for(workingListLockset = workingList->begin(); workingListLockset != workingList->end(); ++workingListLockset){ set<Strator::StratorWorker::LockSet>& statementLockSets = traverseStatement(f, nextInst, entryLockSet, *workingListLockset); returnSet->insert(statementLockSets.begin(), statementLockSets.end()); } } } else{ if(&(bb->back()) == &(*inst)){ for(succ_iterator child = succ_begin(bb), end = succ_end(bb); child != end; ++child){ BasicBlock::iterator firstInstr = child->begin(); set<LockSet>& statementLockSets = traverseStatement(f, firstInstr, entryLockSet, lockSet); returnSet->insert(statementLockSets.begin(), statementLockSets.end()); } } else{ BasicBlock::const_iterator nextInst = inst; ++nextInst; set<Strator::StratorWorker::LockSet>& statementLockSets = traverseStatement(f, nextInst, entryLockSet, lockSet); returnSet->insert(statementLockSets.begin(), statementLockSets.end()); } } return *returnSet; }
bool ObjCARCContract::runOnFunction(Function &F) { if (!EnableARCOpts) return false; // If nothing in the Module uses ARC, don't do anything. if (!Run) return false; Changed = false; AA = &getAnalysis<AliasAnalysis>(); DT = &getAnalysis<DominatorTree>(); PA.setAA(&getAnalysis<AliasAnalysis>()); // Track whether it's ok to mark objc_storeStrong calls with the "tail" // keyword. Be conservative if the function has variadic arguments. // It seems that functions which "return twice" are also unsafe for the // "tail" argument, because they are setjmp, which could need to // return to an earlier stack state. bool TailOkForStoreStrongs = !F.isVarArg() && !F.callsFunctionThatReturnsTwice(); // For ObjC library calls which return their argument, replace uses of the // argument with uses of the call return value, if it dominates the use. This // reduces register pressure. SmallPtrSet<Instruction *, 4> DependingInstructions; SmallPtrSet<const BasicBlock *, 4> Visited; for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) { Instruction *Inst = &*I++; DEBUG(dbgs() << "ObjCARCContract: Visiting: " << *Inst << "\n"); // Only these library routines return their argument. In particular, // objc_retainBlock does not necessarily return its argument. InstructionClass Class = GetBasicInstructionClass(Inst); switch (Class) { case IC_Retain: case IC_FusedRetainAutorelease: case IC_FusedRetainAutoreleaseRV: break; case IC_Autorelease: case IC_AutoreleaseRV: if (ContractAutorelease(F, Inst, Class, DependingInstructions, Visited)) continue; break; case IC_RetainRV: { // If we're compiling for a target which needs a special inline-asm // marker to do the retainAutoreleasedReturnValue optimization, // insert it now. if (!RetainRVMarker) break; BasicBlock::iterator BBI = Inst; BasicBlock *InstParent = Inst->getParent(); // Step up to see if the call immediately precedes the RetainRV call. // If it's an invoke, we have to cross a block boundary. And we have // to carefully dodge no-op instructions. do { if (&*BBI == InstParent->begin()) { BasicBlock *Pred = InstParent->getSinglePredecessor(); if (!Pred) goto decline_rv_optimization; BBI = Pred->getTerminator(); break; } --BBI; } while (IsNoopInstruction(BBI)); if (&*BBI == GetObjCArg(Inst)) { DEBUG(dbgs() << "ObjCARCContract: Adding inline asm marker for " "retainAutoreleasedReturnValue optimization.\n"); Changed = true; InlineAsm *IA = InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()), /*isVarArg=*/false), RetainRVMarker->getString(), /*Constraints=*/"", /*hasSideEffects=*/true); CallInst::Create(IA, "", Inst); } decline_rv_optimization: break; } case IC_InitWeak: { // objc_initWeak(p, null) => *p = null CallInst *CI = cast<CallInst>(Inst); if (IsNullOrUndef(CI->getArgOperand(1))) { Value *Null = ConstantPointerNull::get(cast<PointerType>(CI->getType())); Changed = true; new StoreInst(Null, CI->getArgOperand(0), CI); DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n" << " New = " << *Null << "\n"); CI->replaceAllUsesWith(Null); CI->eraseFromParent(); } continue; } case IC_Release: ContractRelease(Inst, I); continue; case IC_User: // Be conservative if the function has any alloca instructions. // Technically we only care about escaping alloca instructions, // but this is sufficient to handle some interesting cases. if (isa<AllocaInst>(Inst)) TailOkForStoreStrongs = false; continue; case IC_IntrinsicUser: // Remove calls to @clang.arc.use(...). Inst->eraseFromParent(); continue; default: continue; } DEBUG(dbgs() << "ObjCARCContract: Finished List.\n\n"); // Don't use GetObjCArg because we don't want to look through bitcasts // and such; to do the replacement, the argument must have type i8*. const Value *Arg = cast<CallInst>(Inst)->getArgOperand(0); for (;;) { // If we're compiling bugpointed code, don't get in trouble. if (!isa<Instruction>(Arg) && !isa<Argument>(Arg)) break; // Look through the uses of the pointer. for (Value::const_use_iterator UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE; ) { Use &U = UI.getUse(); unsigned OperandNo = UI.getOperandNo(); ++UI; // Increment UI now, because we may unlink its element. // If the call's return value dominates a use of the call's argument // value, rewrite the use to use the return value. We check for // reachability here because an unreachable call is considered to // trivially dominate itself, which would lead us to rewriting its // argument in terms of its return value, which would lead to // infinite loops in GetObjCArg. if (DT->isReachableFromEntry(U) && DT->dominates(Inst, U)) { Changed = true; Instruction *Replacement = Inst; Type *UseTy = U.get()->getType(); if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) { // For PHI nodes, insert the bitcast in the predecessor block. unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo); BasicBlock *BB = PHI->getIncomingBlock(ValNo); if (Replacement->getType() != UseTy) Replacement = new BitCastInst(Replacement, UseTy, "", &BB->back()); // While we're here, rewrite all edges for this PHI, rather // than just one use at a time, to minimize the number of // bitcasts we emit. for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) if (PHI->getIncomingBlock(i) == BB) { // Keep the UI iterator valid. if (&PHI->getOperandUse( PHINode::getOperandNumForIncomingValue(i)) == &UI.getUse()) ++UI; PHI->setIncomingValue(i, Replacement); } } else { if (Replacement->getType() != UseTy) Replacement = new BitCastInst(Replacement, UseTy, "", cast<Instruction>(U.getUser())); U.set(Replacement); } } } // If Arg is a no-op casted pointer, strip one level of casts and iterate. if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg)) Arg = BI->getOperand(0); else if (isa<GEPOperator>(Arg) && cast<GEPOperator>(Arg)->hasAllZeroIndices()) Arg = cast<GEPOperator>(Arg)->getPointerOperand(); else if (isa<GlobalAlias>(Arg) && !cast<GlobalAlias>(Arg)->mayBeOverridden()) Arg = cast<GlobalAlias>(Arg)->getAliasee(); else break; } } // If this function has no escaping allocas or suspicious vararg usage, // objc_storeStrong calls can be marked with the "tail" keyword. if (TailOkForStoreStrongs) for (SmallPtrSet<CallInst *, 8>::iterator I = StoreStrongCalls.begin(), E = StoreStrongCalls.end(); I != E; ++I) (*I)->setTailCall(); StoreStrongCalls.clear(); return Changed; }
bool ObjCARCContract::runOnFunction(Function &F) { if (!EnableARCOpts) return false; // If nothing in the Module uses ARC, don't do anything. if (!Run) return false; Changed = false; AA = &getAnalysis<AAResultsWrapperPass>().getAAResults(); DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); PA.setAA(&getAnalysis<AAResultsWrapperPass>().getAAResults()); DenseMap<BasicBlock *, ColorVector> BlockColors; if (F.hasPersonalityFn() && isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) BlockColors = colorEHFunclets(F); LLVM_DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n"); // Track whether it's ok to mark objc_storeStrong calls with the "tail" // keyword. Be conservative if the function has variadic arguments. // It seems that functions which "return twice" are also unsafe for the // "tail" argument, because they are setjmp, which could need to // return to an earlier stack state. bool TailOkForStoreStrongs = !F.isVarArg() && !F.callsFunctionThatReturnsTwice(); // For ObjC library calls which return their argument, replace uses of the // argument with uses of the call return value, if it dominates the use. This // reduces register pressure. SmallPtrSet<Instruction *, 4> DependingInstructions; SmallPtrSet<const BasicBlock *, 4> Visited; for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) { Instruction *Inst = &*I++; LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n"); // First try to peephole Inst. If there is nothing further we can do in // terms of undoing objc-arc-expand, process the next inst. if (tryToPeepholeInstruction(F, Inst, I, DependingInstructions, Visited, TailOkForStoreStrongs, BlockColors)) continue; // Otherwise, try to undo objc-arc-expand. // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts // and such; to do the replacement, the argument must have type i8*. // Function for replacing uses of Arg dominated by Inst. auto ReplaceArgUses = [Inst, this](Value *Arg) { // If we're compiling bugpointed code, don't get in trouble. if (!isa<Instruction>(Arg) && !isa<Argument>(Arg)) return; // Look through the uses of the pointer. for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end(); UI != UE; ) { // Increment UI now, because we may unlink its element. Use &U = *UI++; unsigned OperandNo = U.getOperandNo(); // If the call's return value dominates a use of the call's argument // value, rewrite the use to use the return value. We check for // reachability here because an unreachable call is considered to // trivially dominate itself, which would lead us to rewriting its // argument in terms of its return value, which would lead to // infinite loops in GetArgRCIdentityRoot. if (!DT->isReachableFromEntry(U) || !DT->dominates(Inst, U)) continue; Changed = true; Instruction *Replacement = Inst; Type *UseTy = U.get()->getType(); if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) { // For PHI nodes, insert the bitcast in the predecessor block. unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo); BasicBlock *IncomingBB = PHI->getIncomingBlock(ValNo); if (Replacement->getType() != UseTy) { // A catchswitch is both a pad and a terminator, meaning a basic // block with a catchswitch has no insertion point. Keep going up // the dominator tree until we find a non-catchswitch. BasicBlock *InsertBB = IncomingBB; while (isa<CatchSwitchInst>(InsertBB->getFirstNonPHI())) { InsertBB = DT->getNode(InsertBB)->getIDom()->getBlock(); } assert(DT->dominates(Inst, &InsertBB->back()) && "Invalid insertion point for bitcast"); Replacement = new BitCastInst(Replacement, UseTy, "", &InsertBB->back()); } // While we're here, rewrite all edges for this PHI, rather // than just one use at a time, to minimize the number of // bitcasts we emit. for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) if (PHI->getIncomingBlock(i) == IncomingBB) { // Keep the UI iterator valid. if (UI != UE && &PHI->getOperandUse( PHINode::getOperandNumForIncomingValue(i)) == &*UI) ++UI; PHI->setIncomingValue(i, Replacement); } } else { if (Replacement->getType() != UseTy) Replacement = new BitCastInst(Replacement, UseTy, "", cast<Instruction>(U.getUser())); U.set(Replacement); } } }; Value *Arg = cast<CallInst>(Inst)->getArgOperand(0); Value *OrigArg = Arg; // TODO: Change this to a do-while. for (;;) { ReplaceArgUses(Arg); // If Arg is a no-op casted pointer, strip one level of casts and iterate. if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg)) Arg = BI->getOperand(0); else if (isa<GEPOperator>(Arg) && cast<GEPOperator>(Arg)->hasAllZeroIndices()) Arg = cast<GEPOperator>(Arg)->getPointerOperand(); else if (isa<GlobalAlias>(Arg) && !cast<GlobalAlias>(Arg)->isInterposable()) Arg = cast<GlobalAlias>(Arg)->getAliasee(); else { // If Arg is a PHI node, get PHIs that are equivalent to it and replace // their uses. if (PHINode *PN = dyn_cast<PHINode>(Arg)) { SmallVector<Value *, 1> PHIList; getEquivalentPHIs(*PN, PHIList); for (Value *PHI : PHIList) ReplaceArgUses(PHI); } break; } } // Replace bitcast users of Arg that are dominated by Inst. SmallVector<BitCastInst *, 2> BitCastUsers; // Add all bitcast users of the function argument first. for (User *U : OrigArg->users()) if (auto *BC = dyn_cast<BitCastInst>(U)) BitCastUsers.push_back(BC); // Replace the bitcasts with the call return. Iterate until list is empty. while (!BitCastUsers.empty()) { auto *BC = BitCastUsers.pop_back_val(); for (User *U : BC->users()) if (auto *B = dyn_cast<BitCastInst>(U)) BitCastUsers.push_back(B); ReplaceArgUses(BC); } } // If this function has no escaping allocas or suspicious vararg usage, // objc_storeStrong calls can be marked with the "tail" keyword. if (TailOkForStoreStrongs) for (CallInst *CI : StoreStrongCalls) CI->setTailCall(); StoreStrongCalls.clear(); return Changed; }
/// canBasicBlockModify - Return true if it is possible for execution of the /// specified basic block to modify the value pointed to by Ptr. /// bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB, const Value *Ptr, unsigned Size) { return canInstructionRangeModify(BB.front(), BB.back(), Ptr, Size); }
std::vector<SetOfFormulasPtr> FaultLocalization::allDiagnosis(Formula *TF, std::vector<ProgramTrace*> traces, YicesSolver *yices) { std::vector<SetOfFormulasPtr> MCSes; int progress = 0; int total = traces.size(); // Working formula Formula *WF = new Formula(TF); // For each E in WF, E tagged as soft do unsigned z = 0; std::vector<BoolVarExprPtr> AV; std::map<BoolVarExprPtr, ExprPtr> AVMap; std::vector<ExprPtr> clauses = WF->getExprs(); for(ExprPtr e : clauses) { if (e->isSoft()) { // AI is a new auxiliary var. created std::ostringstream oss; oss << z++; BoolVarExprPtr ai = Expression::mkBoolVar("a_"+oss.str()); ai->setInstruction(e->getInstruction()); ai->setLine(e->getLine()); AV.push_back(ai); AVMap[ai] = e; ExprPtr notai = Expression::mkNot(ai); //notai->setWeight(e->getWeight()); notai->setLine(e->getLine()); notai->setSoft(); WF->add(notai); // Remove E and add EA as hard ExprPtr ea = Expression::mkOr(e, ai); WF->remove(e); ea->setHard(); WF->add(ea); } } if (AV.empty()) { delete WF; std::cout << "No MaxSMT solution!\n"; if (options->verbose()) { std::cout << "==============================================\n"; } return MCSes; } yices->init(); yices->addToContext(WF); for(ProgramTrace *E : traces) { if (options->verbose()) { displayProgressBar(progress, total); } // At this point there is only WF in the context yices->push(); // Assert as hard the error-inducing input formula ExprPtr eiExpr = E->getProgramInputsFormula(TF); eiExpr->setHard(); yices->addToContext(eiExpr); if (options->dbgMsg()) { std::cout << "-- Error-inducing Input: "; eiExpr->dump(); std::cout << std::endl; } // Assert as hard the golden output (if any) // (= return_var golden_output) Value *goldenOutput = E->getExpectedOutput(); if (goldenOutput) { BasicBlock *lastBB = &targetFun->back(); Instruction *lastInst = &lastBB->back(); if (ReturnInst *ret= dyn_cast<ReturnInst>(lastInst)) { Value *retVal = ret->getReturnValue(); if (retVal) { ExprPtr retExpr = Expression::getExprFromValue(retVal); ExprPtr goExpr = Expression::getExprFromValue(goldenOutput); ExprPtr eqExpr = Expression::mkEq(retExpr, goExpr); eqExpr->setHard(); yices->addToContext(eqExpr); if (options->dbgMsg()) { std::cout << "-- Golden ouput: "; eqExpr->dump(); std::cout << std::endl; } } } } // Compute a MCS SetOfFormulasPtr M = allMinMCS(yices, AV, AVMap); if (!M->empty()) { SetOfFormulasPtr M2 = avToClauses(M, AVMap); MCSes.push_back(M2); if (options->printMCS()) { std::cout << "\n" << M2 << "\n" << std::endl; } } else { //if (options->verbose() || options->dbgMsg()) { std::cout << "Empty MCS!\n"; //} } // Backtrack to the point where there // was no Pre/Post-conditions in the formula yices->pop(); // Progress bar progress++; } yices->clean(); delete WF; if (options->verbose()) { displayProgressBar(progress, total); std::cout << std::endl; } return MCSes; }
/// [LIBUNWIND] Find the (possibly absent) call to @llvm.eh.selector /// in the given landing pad. In principle, llvm.eh.exception is /// required to be in the landing pad; in practice, SplitCriticalEdge /// can break that invariant, and then inlining can break it further. /// There's a real need for a reliable solution here, but until that /// happens, we have some fragile workarounds here. static EHSelectorInst *findSelectorForLandingPad(BasicBlock *lpad) { // Look for an exception call in the actual landing pad. EHExceptionInst *exn = findExceptionInBlock(lpad); if (exn) return findSelectorForException(exn); // Okay, if that failed, look for one in an obvious successor. If // we find one, we'll fix the IR by moving things back to the // landing pad. bool dominates = true; // does the lpad dominate the exn call BasicBlock *nonDominated = 0; // if not, the first non-dominated block BasicBlock *lastDominated = 0; // and the block which branched to it BasicBlock *exnBlock = lpad; // We need to protect against lpads that lead into infinite loops. SmallPtrSet<BasicBlock*,4> visited; visited.insert(exnBlock); do { // We're not going to apply this hack to anything more complicated // than a series of unconditional branches, so if the block // doesn't terminate in an unconditional branch, just fail. More // complicated cases can arise when, say, sinking a call into a // split unwind edge and then inlining it; but that can do almost // *anything* to the CFG, including leaving the selector // completely unreachable. The only way to fix that properly is // to (1) prohibit transforms which move the exception or selector // values away from the landing pad, e.g. by producing them with // instructions that are pinned to an edge like a phi, or // producing them with not-really-instructions, and (2) making // transforms which split edges deal with that. BranchInst *branch = dyn_cast<BranchInst>(&exnBlock->back()); if (!branch || branch->isConditional()) return 0; BasicBlock *successor = branch->getSuccessor(0); // Fail if we found an infinite loop. if (!visited.insert(successor)) return 0; // If the successor isn't dominated by exnBlock: if (!successor->getSinglePredecessor()) { // We don't want to have to deal with threading the exception // through multiple levels of phi, so give up if we've already // followed a non-dominating edge. if (!dominates) return 0; // Otherwise, remember this as a non-dominating edge. dominates = false; nonDominated = successor; lastDominated = exnBlock; } exnBlock = successor; // Can we stop here? exn = findExceptionInBlock(exnBlock); } while (!exn); // Look for a selector call for the exception we found. EHSelectorInst *selector = findSelectorForException(exn); if (!selector) return 0; // The easy case is when the landing pad still dominates the // exception call, in which case we can just move both calls back to // the landing pad. if (dominates) { selector->moveBefore(lpad->getFirstNonPHI()); exn->moveBefore(selector); return selector; } // Otherwise, we have to split at the first non-dominating block. // The CFG looks basically like this: // lpad: // phis_0 // insnsAndBranches_1 // br label %nonDominated // nonDominated: // phis_2 // insns_3 // %exn = call i8* @llvm.eh.exception() // insnsAndBranches_4 // %selector = call @llvm.eh.selector(i8* %exn, ... // We need to turn this into: // lpad: // phis_0 // %exn0 = call i8* @llvm.eh.exception() // %selector0 = call @llvm.eh.selector(i8* %exn0, ... // insnsAndBranches_1 // br label %split // from lastDominated // nonDominated: // phis_2 (without edge from lastDominated) // %exn1 = call i8* @llvm.eh.exception() // %selector1 = call i8* @llvm.eh.selector(i8* %exn1, ... // br label %split // split: // phis_2 (edge from lastDominated, edge from split) // %exn = phi ... // %selector = phi ... // insns_3 // insnsAndBranches_4 assert(nonDominated); assert(lastDominated); // First, make clones of the intrinsics to go in lpad. EHExceptionInst *lpadExn = cast<EHExceptionInst>(exn->clone()); EHSelectorInst *lpadSelector = cast<EHSelectorInst>(selector->clone()); lpadSelector->setArgOperand(0, lpadExn); lpadSelector->insertBefore(lpad->getFirstNonPHI()); lpadExn->insertBefore(lpadSelector); // Split the non-dominated block. BasicBlock *split = nonDominated->splitBasicBlock(nonDominated->getFirstNonPHI(), nonDominated->getName() + ".lpad-fix"); // Redirect the last dominated branch there. cast<BranchInst>(lastDominated->back()).setSuccessor(0, split); // Move the existing intrinsics to the end of the old block. selector->moveBefore(&nonDominated->back()); exn->moveBefore(selector); Instruction *splitIP = &split->front(); // For all the phis in nonDominated, make a new phi in split to join // that phi with the edge from lastDominated. for (BasicBlock::iterator i = nonDominated->begin(), e = nonDominated->end(); i != e; ++i) { PHINode *phi = dyn_cast<PHINode>(i); if (!phi) break; PHINode *splitPhi = PHINode::Create(phi->getType(), 2, phi->getName(), splitIP); phi->replaceAllUsesWith(splitPhi); splitPhi->addIncoming(phi, nonDominated); splitPhi->addIncoming(phi->removeIncomingValue(lastDominated), lastDominated); } // Make new phis for the exception and selector. PHINode *exnPhi = PHINode::Create(exn->getType(), 2, "", splitIP); exn->replaceAllUsesWith(exnPhi); selector->setArgOperand(0, exn); // except for this use exnPhi->addIncoming(exn, nonDominated); exnPhi->addIncoming(lpadExn, lastDominated); PHINode *selectorPhi = PHINode::Create(selector->getType(), 2, "", splitIP); selector->replaceAllUsesWith(selectorPhi); selectorPhi->addIncoming(selector, nonDominated); selectorPhi->addIncoming(lpadSelector, lastDominated); return lpadSelector; }
bool LoopRegionDump::visitLoop(Loop *L, Module *mod) { // Ensure we are working only on outermost loops if (L->getLoopDepth() > 1) return false; // Get the function we are in Function *currFunc = L->getHeader()->getParent(); // Are we in an isolated Region std::size_t found = currFunc->getName().find("__cere__"); if (found == std::string::npos) return false; // If we want to dump a particular region, look if it's this one if (!GlobalDump && RegionToDump != currFunc->getName()) { return false; } else if (ReadFromFile) { if (!(std::find(RegionsToDump.begin(), RegionsToDump.end(), currFunc->getName()) != RegionsToDump.end())) return false; } // Create dump function Function *func_dump = mod->getFunction("dump"); if (!func_dump) { // If function "dump" not found, creates it FunctionType *DumpFuncTy = createDumpFunctionType(mod); func_dump = Function::Create(DumpFuncTy, GlobalValue::ExternalLinkage, "dump", mod); } // Create after_dump function Function *func_after_dump = mod->getFunction("after_dump"); if (!func_after_dump) { // If function "after_dump" not found, creates it // Create a void type std::vector<Type *> FuncTy_12_args; FunctionType *AfterDumpFuncTy = FunctionType::get( /*Result=*/Type::getVoidTy(mod->getContext()), /*Params=*/FuncTy_12_args, /*isVarArg=*/false); func_after_dump = Function::Create( AfterDumpFuncTy, GlobalValue::ExternalLinkage, "after_dump", mod); } // Get predecessor loop basic block BasicBlock *PredBB = L->getLoopPredecessor(); // Get all exit blocks SmallVector<BasicBlock *, 8> exitblocks; L->getExitBlocks(exitblocks); if (PredBB == NULL || exitblocks.size() == 0) return false; ++RegionCounter; // Create arguments for the dump function std::vector<Value *> funcParameter = createDumpFunctionParameters(mod, currFunc, PredBB, InvocationToDump); // Call dump function just before the region CallInst::Create(func_dump, funcParameter, "", &PredBB->back()); // Call after dump in each exit blocks for (SmallVectorImpl<BasicBlock *>::iterator I = exitblocks.begin(), E = exitblocks.end(); I != E; ++I) { CallInst::Create(func_after_dump, "", &(*I)->front()); } return true; }