// visitInvokeInst - Converting the "invoke" instruction is fairly // straight-forward. The old exception part is replaced by a query asking // if this is a longjmp exception. If it is, then it goes to the longjmp // exception blocks. Otherwise, control is passed the old exception. void LowerSetJmp::visitInvokeInst(InvokeInst& II) { if (II.getCalledFunction()) if (!IsTransformableFunction(II.getCalledFunction()->getName()) || II.getCalledFunction()->isIntrinsic()) return; BasicBlock* BB = II.getParent(); // If not reachable from a setjmp call, don't transform. if (!DFSBlocks.count(BB)) return; BasicBlock* ExceptBB = II.getUnwindDest(); Function* Func = BB->getParent(); BasicBlock* NewExceptBB = BasicBlock::Create("InvokeExcept", Func); BasicBlock::InstListType& InstList = NewExceptBB->getInstList(); // If this is a longjmp exception, then branch to the preliminary BB of // the longjmp exception handling. Otherwise, go to the old exception. CallInst* IsLJExcept = CallInst::Create(IsLJException, "IsLJExcept"); InstList.push_back(IsLJExcept); BranchInst::Create(PrelimBBMap[Func], ExceptBB, IsLJExcept, NewExceptBB); II.setUnwindDest(NewExceptBB); ++InvokesTransformed; }
void DeadStoreEliminationPass::runOverwrittenDeadStoreAnalysisOnFn(Function &F) { MDA = &getAnalysis<MemoryDependenceAnalysis>(F); for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) { Instruction *inst = I; if (StoreInst* SI = dyn_cast<StoreInst>(inst)) { Value *ptr = SI->getPointerOperand(); MemDepResult mdr = MDA->getDependency(inst); Instruction *depInst = mdr.getInst(); if (depInst && (isa<CallInst>(depInst) || isa<InvokeInst>(depInst))) { Function *calledFn; if (CallInst* CI = dyn_cast<CallInst>(depInst)) { calledFn = CI->getCalledFunction(); } else { InvokeInst *II = dyn_cast<InvokeInst>(depInst); calledFn = II->getCalledFunction(); } if (!fnThatStoreOnArgs.count(calledFn)) continue; CallSite CS(depInst); CallSite::arg_iterator actualArgIter = CS.arg_begin(); Function::arg_iterator formalArgIter = calledFn->arg_begin(); int size = calledFn->arg_size(); std::set<Value*> storedArgs = fnThatStoreOnArgs[calledFn]; for (int i = 0; i < size; ++i, ++actualArgIter, ++formalArgIter) { Value *formalArg = formalArgIter; Value *actualArg = *actualArgIter; if (ptr == actualArg && storedArgs.count(formalArg)) { int64_t InstWriteOffset, DepWriteOffset; DEBUG(errs() << " Verifying if store is completely overwritten.\n"); AliasAnalysis::Location Loc(ptr, getPointerSize(ptr, *AA), NULL); AliasAnalysis::Location DepLoc(actualArg, getPointerSize(actualArg, *AA), NULL); OverwriteResult OR = isOverwrite(Loc, DepLoc, *AA, DepWriteOffset, InstWriteOffset); if (OR == OverwriteComplete) { DEBUG(errs() << " Store on " << formalArg->getName() << " will be removed with cloning\n"); deadArguments[depInst].insert(formalArg); } } } if (deadArguments.count(depInst)) { fn2Clone[calledFn].push_back(depInst); } } } } } }
void visitInvokeInst(InvokeInst &I) { Function* target = I.getCalledFunction(); if (target == NULL) { anyUnknown = true; return; } if (isInternal(target)) { if (used != NULL) used->push(target); } else { interface->call(target->getName(), arg_begin(I), arg_end(I)); } this->visitInstruction(I); }