+ DEBUG(std::cerr << "[" << GI->getGraphSize() << "+"
+ << GI->getAuxFunctionCalls().size() << "] into '"
+ << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+ << Graph.getAuxFunctionCalls().size() << "]\n");
+ Graph.mergeInGraph(CS, *Callee, *GI,
+ DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes);
+ ++NumBUInlines;
+ } else {
+ if (!Printed)
+ std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n";
+ std::cerr << " calls " << CalledFuncs.size()
+ << " fns from site: " << CS.getCallSite().getInstruction()
+ << " " << *CS.getCallSite().getInstruction();
+ std::cerr << " Fns =";
+ unsigned NumPrinted = 0;
+
+ for (std::vector<Function*>::iterator I = CalledFuncs.begin(),
+ E = CalledFuncs.end(); I != E; ++I) {
+ if (NumPrinted++ < 8) std::cerr << " " << (*I)->getName();
+
+ // Add the call edges to the call graph.
+ ActualCallees.insert(std::make_pair(TheCall, *I));
+ }
+ std::cerr << "\n";
+
+ // See if we already computed a graph for this set of callees.
+ std::sort(CalledFuncs.begin(), CalledFuncs.end());
+ std::pair<DSGraph*, std::vector<DSNodeHandle> > &IndCallGraph =
+ (*IndCallGraphMap)[CalledFuncs];
+
+ if (IndCallGraph.first == 0) {
+ std::vector<Function*>::iterator I = CalledFuncs.begin(),
+ E = CalledFuncs.end();
+
+ // Start with a copy of the first graph.
+ GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs);
+ GI->setGlobalsGraph(Graph.getGlobalsGraph());
+ std::vector<DSNodeHandle> &Args = IndCallGraph.second;
+
+ // Get the argument nodes for the first callee. The return value is
+ // the 0th index in the vector.
+ GI->getFunctionArgumentsForCall(*I, Args);
+
+ // Merge all of the other callees into this graph.
+ for (++I; I != E; ++I) {
+ // If the graph already contains the nodes for the function, don't
+ // bother merging it in again.
+ if (!GI->containsFunction(*I)) {
+ GI->cloneInto(getDSGraph(**I));
+ ++NumBUInlines;
+ }
+
+ std::vector<DSNodeHandle> NextArgs;
+ GI->getFunctionArgumentsForCall(*I, NextArgs);
+ unsigned i = 0, e = Args.size();
+ for (; i != e; ++i) {
+ if (i == NextArgs.size()) break;
+ Args[i].mergeWith(NextArgs[i]);
+ }
+ for (e = NextArgs.size(); i != e; ++i)
+ Args.push_back(NextArgs[i]);
+ }
+
+ // Clean up the final graph!
+ GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
+ } else {
+ std::cerr << "***\n*** RECYCLED GRAPH ***\n***\n";
+ }