/// UpdateCallGraphAfterInlining - Once we have cloned code over from a callee /// into the caller, update the specified callgraph to reflect the changes we /// made. Note that it's possible that not all code was copied over, so only /// some edges of the callgraph may remain. static void UpdateCallGraphAfterInlining(CallSite CS, Function::iterator FirstNewBlock, ValueToValueMapTy &VMap, InlineFunctionInfo &IFI) { CallGraph &CG = *IFI.CG; const Function *Caller = CS.getInstruction()->getParent()->getParent(); const Function *Callee = CS.getCalledFunction(); CallGraphNode *CalleeNode = CG[Callee]; CallGraphNode *CallerNode = CG[Caller]; // Since we inlined some uninlined call sites in the callee into the caller, // add edges from the caller to all of the callees of the callee. CallGraphNode::iterator I = CalleeNode->begin(), E = CalleeNode->end(); // Consider the case where CalleeNode == CallerNode. CallGraphNode::CalledFunctionsVector CallCache; if (CalleeNode == CallerNode) { CallCache.assign(I, E); I = CallCache.begin(); E = CallCache.end(); } for (; I != E; ++I) { const Value *OrigCall = I->first; ValueToValueMapTy::iterator VMI = VMap.find(OrigCall); // Only copy the edge if the call was inlined! if (VMI == VMap.end() || VMI->second == 0) continue; // If the call was inlined, but then constant folded, there is no edge to // add. Check for this case. Instruction *NewCall = dyn_cast<Instruction>(VMI->second); if (NewCall == 0) continue; // Remember that this call site got inlined for the client of // InlineFunction. IFI.InlinedCalls.push_back(NewCall); // It's possible that inlining the callsite will cause it to go from an // indirect to a direct call by resolving a function pointer. If this // happens, set the callee of the new call site to a more precise // destination. This can also happen if the call graph node of the caller // was just unnecessarily imprecise. if (I->second->getFunction() == 0) if (Function *F = CallSite(NewCall).getCalledFunction()) { // Indirect call site resolved to direct call. CallerNode->addCalledFunction(CallSite(NewCall), CG[F]); continue; } CallerNode->addCalledFunction(CallSite(NewCall), I->second); } // Update the call graph by deleting the edge from Callee to Caller. We must // do this after the loop above in case Caller and Callee are the same. CallerNode->removeCallEdgeFor(CS); }
/// DeleteBasicBlock - remove the specified basic block from the program, /// updating the callgraph to reflect any now-obsolete edges due to calls that /// exist in the BB. void PruneEH::DeleteBasicBlock(BasicBlock *BB) { assert(pred_empty(BB) && "BB is not dead!"); CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph(); Instruction *TokenInst = nullptr; CallGraphNode *CGN = CG[BB->getParent()]; for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; ) { --I; if (I->getType()->isTokenTy()) { TokenInst = &*I; break; } if (auto CS = CallSite (&*I)) { const Function *Callee = CS.getCalledFunction(); if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID())) CGN->removeCallEdgeFor(CS); else if (!Callee->isIntrinsic()) CGN->removeCallEdgeFor(CS); } if (!I->use_empty()) I->replaceAllUsesWith(UndefValue::get(I->getType())); } if (TokenInst) { if (!isa<TerminatorInst>(TokenInst)) changeToUnreachable(TokenInst->getNextNode(), /*UseLLVMTrap=*/false); } else { // Get the list of successors of this block. std::vector<BasicBlock *> Succs(succ_begin(BB), succ_end(BB)); for (unsigned i = 0, e = Succs.size(); i != e; ++i) Succs[i]->removePredecessor(BB); BB->eraseFromParent(); } }
/// DeleteBasicBlock - remove the specified basic block from the program, /// updating the callgraph to reflect any now-obsolete edges due to calls that /// exist in the BB. void PruneEH::DeleteBasicBlock(BasicBlock *BB) { assert(pred_begin(BB) == pred_end(BB) && "BB is not dead!"); CallGraph &CG = getAnalysis<CallGraph>(); CallGraphNode *CGN = CG[BB->getParent()]; for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; ) { --I; if (CallInst *CI = dyn_cast<CallInst>(I)) { if (!isa<IntrinsicInst>(I)) CGN->removeCallEdgeFor(CI); } else if (InvokeInst *II = dyn_cast<InvokeInst>(I)) CGN->removeCallEdgeFor(II); if (!I->use_empty()) I->replaceAllUsesWith(UndefValue::get(I->getType())); } // Get the list of successors of this block. std::vector<BasicBlock*> Succs(succ_begin(BB), succ_end(BB)); for (unsigned i = 0, e = Succs.size(); i != e; ++i) Succs[i]->removePredecessor(BB); BB->eraseFromParent(); }
/// UpdateCallGraphAfterInlining - Once we have cloned code over from a callee /// into the caller, update the specified callgraph to reflect the changes we /// made. Note that it's possible that not all code was copied over, so only /// some edges of the callgraph may remain. static void UpdateCallGraphAfterInlining(CallSite CS, Function::iterator FirstNewBlock, DenseMap<const Value*, Value*> &ValueMap, CallGraph &CG) { const Function *Caller = CS.getInstruction()->getParent()->getParent(); const Function *Callee = CS.getCalledFunction(); CallGraphNode *CalleeNode = CG[Callee]; CallGraphNode *CallerNode = CG[Caller]; // Since we inlined some uninlined call sites in the callee into the caller, // add edges from the caller to all of the callees of the callee. CallGraphNode::iterator I = CalleeNode->begin(), E = CalleeNode->end(); // Consider the case where CalleeNode == CallerNode. CallGraphNode::CalledFunctionsVector CallCache; if (CalleeNode == CallerNode) { CallCache.assign(I, E); I = CallCache.begin(); E = CallCache.end(); } for (; I != E; ++I) { const Instruction *OrigCall = I->first.getInstruction(); DenseMap<const Value*, Value*>::iterator VMI = ValueMap.find(OrigCall); // Only copy the edge if the call was inlined! if (VMI != ValueMap.end() && VMI->second) { // If the call was inlined, but then constant folded, there is no edge to // add. Check for this case. if (Instruction *NewCall = dyn_cast<Instruction>(VMI->second)) CallerNode->addCalledFunction(CallSite::get(NewCall), I->second); } } // Update the call graph by deleting the edge from Callee to Caller. We must // do this after the loop above in case Caller and Callee are the same. CallerNode->removeCallEdgeFor(CS); }
/// updateCallSites - Update all sites that call F to use NF. CallGraphNode *SRETPromotion::updateCallSites(Function *F, Function *NF) { CallGraph &CG = getAnalysis<CallGraph>(); SmallVector<Value*, 16> Args; // Attributes - Keep track of the parameter attributes for the arguments. SmallVector<AttributeWithIndex, 8> ArgAttrsVec; // Get a new callgraph node for NF. CallGraphNode *NF_CGN = CG.getOrInsertFunction(NF); while (!F->use_empty()) { CallSite CS(*F->use_begin()); Instruction *Call = CS.getInstruction(); const AttrListPtr &PAL = F->getAttributes(); // Add any return attributes. if (Attributes attrs = PAL.getRetAttributes()) ArgAttrsVec.push_back(AttributeWithIndex::get(0, attrs)); // Copy arguments, however skip first one. CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end(); Value *FirstCArg = *AI; ++AI; // 0th parameter attribute is reserved for return type. // 1th parameter attribute is for first 1st sret argument. unsigned ParamIndex = 2; while (AI != AE) { Args.push_back(*AI); if (Attributes Attrs = PAL.getParamAttributes(ParamIndex)) ArgAttrsVec.push_back(AttributeWithIndex::get(ParamIndex - 1, Attrs)); ++ParamIndex; ++AI; } // Add any function attributes. if (Attributes attrs = PAL.getFnAttributes()) ArgAttrsVec.push_back(AttributeWithIndex::get(~0, attrs)); AttrListPtr NewPAL = AttrListPtr::get(ArgAttrsVec.begin(), ArgAttrsVec.end()); // Build new call instruction. Instruction *New; if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) { New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), Args.begin(), Args.end(), "", Call); cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv()); cast<InvokeInst>(New)->setAttributes(NewPAL); } else { New = CallInst::Create(NF, Args.begin(), Args.end(), "", Call); cast<CallInst>(New)->setCallingConv(CS.getCallingConv()); cast<CallInst>(New)->setAttributes(NewPAL); if (cast<CallInst>(Call)->isTailCall()) cast<CallInst>(New)->setTailCall(); } Args.clear(); ArgAttrsVec.clear(); New->takeName(Call); // Update the callgraph to know that the callsite has been transformed. CallGraphNode *CalleeNode = CG[Call->getParent()->getParent()]; CalleeNode->removeCallEdgeFor(Call); CalleeNode->addCalledFunction(New, NF_CGN); // Update all users of sret parameter to extract value using extractvalue. for (Value::use_iterator UI = FirstCArg->use_begin(), UE = FirstCArg->use_end(); UI != UE; ) { User *U2 = *UI++; CallInst *C2 = dyn_cast<CallInst>(U2); if (C2 && (C2 == Call)) continue; GetElementPtrInst *UGEP = cast<GetElementPtrInst>(U2); ConstantInt *Idx = cast<ConstantInt>(UGEP->getOperand(2)); Value *GR = ExtractValueInst::Create(New, Idx->getZExtValue(), "evi", UGEP); while(!UGEP->use_empty()) { // isSafeToUpdateAllCallers has checked that all GEP uses are // LoadInsts LoadInst *L = cast<LoadInst>(*UGEP->use_begin()); L->replaceAllUsesWith(GR); L->eraseFromParent(); } UGEP->eraseFromParent(); continue; } Call->eraseFromParent(); } return NF_CGN; }