// doFinalization - Remove now-dead linkonce functions at the end of // processing to avoid breaking the SCC traversal. bool Inliner::doFinalization(CallGraph &CG) { std::set<CallGraphNode*> FunctionsToRemove; // Scan for all of the functions, looking for ones that should now be removed // from the program. Insert the dead ones in the FunctionsToRemove set. for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) { CallGraphNode *CGN = I->second; if (Function *F = CGN ? CGN->getFunction() : 0) { // If the only remaining users of the function are dead constants, remove // them. F->removeDeadConstantUsers(); if ((F->hasLinkOnceLinkage() || F->hasInternalLinkage()) && F->use_empty()) { // Remove any call graph edges from the function to its callees. while (!CGN->empty()) CGN->removeCallEdgeTo((CGN->end()-1)->second); // Remove any edges from the external node to the function's call graph // node. These edges might have been made irrelegant due to // optimization of the program. CG.getExternalCallingNode()->removeAnyCallEdgeTo(CGN); // Removing the node for callee from the call graph and delete it. FunctionsToRemove.insert(CGN); } } } // Now that we know which functions to delete, do so. We didn't want to do // this inline, because that would invalidate our CallGraph::iterator // objects. :( bool Changed = false; for (std::set<CallGraphNode*>::iterator I = FunctionsToRemove.begin(), E = FunctionsToRemove.end(); I != E; ++I) { delete CG.removeFunctionFromModule(*I); ++NumDeleted; Changed = true; } return Changed; }
// InlineCallIfPossible - If it is possible to inline the specified call site, // do so and update the CallGraph for this operation. static bool InlineCallIfPossible(CallSite CS, CallGraph &CG, const std::set<Function*> &SCCFunctions, const TargetData &TD) { Function *Callee = CS.getCalledFunction(); if (!InlineFunction(CS, &CG, &TD)) return false; // If we inlined the last possible call site to the function, delete the // function body now. if (Callee->use_empty() && Callee->hasInternalLinkage() && !SCCFunctions.count(Callee)) { DOUT << " -> Deleting dead function: " << Callee->getName() << "\n"; // Remove any call graph edges from the callee to its callees. CallGraphNode *CalleeNode = CG[Callee]; while (!CalleeNode->empty()) CalleeNode->removeCallEdgeTo((CalleeNode->end()-1)->second); // Removing the node for callee from the call graph and delete it. delete CG.removeFunctionFromModule(CalleeNode); ++NumDeleted; } return true; }