From ccc27ecd354c8b68d15546b5dd2c9e5739fa8ef6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 12 Nov 2002 15:58:08 +0000 Subject: [PATCH] Inline graphs from outside the SCC into the SCC before SCC resolution starts llvm-svn: 4701 --- .../DataStructure/BottomUpClosure.cpp | 108 +++++++++++++++++- 1 file changed, 104 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp b/llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp index e096dde24916..435cb1beafc9 100644 --- a/llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp +++ b/llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp @@ -214,18 +214,43 @@ unsigned BUDataStructures::calculateGraphs(Function *F, std::vector::iterator I = Stack.end(); do { --I; +#ifndef NDEBUG /*DEBUG*/(std::cerr << " Fn #" << (Stack.end()-I) << "/" << (Stack.end()-FirstInSCC) << " in SCC: " << (*I)->getName()); DSGraph &G = getDSGraph(**I); std::cerr << " [" << G.getGraphSize() << "+" - << G.getAuxFunctionCalls().size() << "] " << std::flush; + << G.getAuxFunctionCalls().size() << "] "; +#endif - // Inline all graphs into the last (highest numbered) node in the SCC + // Eliminate all call sites in the SCC that are not to functions that are + // in the SCC. + inlineNonSCCGraphs(**I, SCCFunctions); + +#ifndef NDEBUG + std::cerr << "after Non-SCC's [" << G.getGraphSize() << "+" + << G.getAuxFunctionCalls().size() << "]\n"; +#endif + } while (I != FirstInSCC); + + I = Stack.end(); + do { + --I; +#ifndef NDEBUG + /*DEBUG*/(std::cerr << " Fn #" << (Stack.end()-I) << "/" + << (Stack.end()-FirstInSCC) << " in SCC: " + << (*I)->getName()); + DSGraph &G = getDSGraph(**I); + std::cerr << " [" << G.getGraphSize() << "+" + << G.getAuxFunctionCalls().size() << "] "; +#endif + // Inline all graphs into the SCC nodes... calculateSCCGraph(**I, SCCFunctions); +#ifndef NDEBUG std::cerr << "after [" << G.getGraphSize() << "+" << G.getAuxFunctionCalls().size() << "]\n"; +#endif } while (I != FirstInSCC); @@ -329,8 +354,83 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) { } +// inlineNonSCCGraphs - This method is almost like the other two calculate graph +// methods. This one is used to inline function graphs (from functions outside +// of the SCC) into functions in the SCC. It is not supposed to touch functions +// IN the SCC at all. +// +DSGraph &BUDataStructures::inlineNonSCCGraphs(Function &F, + std::set &SCCFunctions){ + DSGraph &Graph = getDSGraph(F); + DEBUG(std::cerr << " [BU] Inlining Non-SCC graphs for: " + << F.getName() << "\n"); + + // Move our call site list into TempFCs so that inline call sites go into the + // new call site list and doesn't invalidate our iterators! + std::vector TempFCs; + std::vector &AuxCallsList = Graph.getAuxFunctionCalls(); + TempFCs.swap(AuxCallsList); + + // Loop over all of the resolvable call sites + unsigned LastCallSiteIdx = ~0U; + for (CallSiteIterator I = CallSiteIterator::begin(TempFCs), + E = CallSiteIterator::end(TempFCs); I != E; ++I) { + // If we skipped over any call sites, they must be unresolvable, copy them + // to the real call site list. + LastCallSiteIdx++; + for (; LastCallSiteIdx < I.getCallSiteIdx(); ++LastCallSiteIdx) + AuxCallsList.push_back(TempFCs[LastCallSiteIdx]); + LastCallSiteIdx = I.getCallSiteIdx(); + + // Resolve the current call... + Function *Callee = *I; + DSCallSite &CS = I.getCallSite(); + + if (Callee->isExternal()) { + // Ignore this case, simple varargs functions we cannot stub out! + } else if (SCCFunctions.count(Callee)) { + // Calling a function in the SCC, ignore it for now! + DEBUG(std::cerr << " SCC CallSite for: " << Callee->getName() << "\n"); + AuxCallsList.push_back(CS); + } else { + // Get the data structure graph for the called function. + // + DSGraph &GI = getDSGraph(*Callee); // Graph to inline + + DEBUG(std::cerr << " Inlining graph for " << Callee->getName() + << " in: " << F.getName() << "[" << GI.getGraphSize() << "+" + << GI.getAuxFunctionCalls().size() << "]\n"); + + // Handle self recursion by resolving the arguments and return value + Graph.mergeInGraph(CS, GI, DSGraph::StripAllocaBit | + DSGraph::DontCloneCallNodes); + } + } + + // Make sure to catch any leftover unresolvable calls... + for (++LastCallSiteIdx; LastCallSiteIdx < TempFCs.size(); ++LastCallSiteIdx) + AuxCallsList.push_back(TempFCs[LastCallSiteIdx]); + + TempFCs.clear(); + + // Recompute the Incomplete markers. If there are any function calls left + // now that are complete, we must loop! + Graph.maskIncompleteMarkers(); + Graph.markIncompleteNodes(); + Graph.removeDeadNodes(); + + DEBUG(std::cerr << " [BU] Done Non-SCC inlining: " << F.getName() << " [" + << Graph.getGraphSize() << "+" << Graph.getAuxFunctionCalls().size() + << "]\n"); + + //Graph.writeGraphToFile(std::cerr, "bu_" + F.getName()); + + return Graph; +} + + DSGraph &BUDataStructures::calculateSCCGraph(Function &F, - std::set &InlinedSCCFunctions) { + std::set &SCCFunctions){ DSGraph &Graph = getDSGraph(F); DEBUG(std::cerr << " [BU] Calculating SCC graph for: " << F.getName()<<"\n"); @@ -391,7 +491,7 @@ DSGraph &BUDataStructures::calculateSCCGraph(Function &F, Graph.mergeInGraph(CS, GI, DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes); - if (InlinedSCCFunctions.count(Callee)) + if (SCCFunctions.count(Callee)) SCCCallSiteMap.insert(std::make_pair(Callee, CS)); } }