[llvm-commits] [poolalloc] r56857 - in /poolalloc/trunk/lib/DSA: BottomUpClosure.cpp CallTargets.cpp DataStructure.cpp
Andrew Lenharth
alenhar2 at cs.uiuc.edu
Tue Sep 30 10:11:51 PDT 2008
Author: alenhar2
Date: Tue Sep 30 12:11:50 2008
New Revision: 56857
URL: http://llvm.org/viewvc/llvm-project?rev=56857&view=rev
Log:
inline graph whenever possible, but don't propagate unresolved call nodes if not inlining complete nodes. Greatly improves precision.
Modified:
poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
poolalloc/trunk/lib/DSA/CallTargets.cpp
poolalloc/trunk/lib/DSA/DataStructure.cpp
Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=56857&r1=56856&r2=56857&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Sep 30 12:11:50 2008
@@ -129,6 +129,25 @@
CS.getCalleeNode()->addFullFunctionList(Callees);
// If any of the callees are unresolvable, remove the whole batch!
+ for (unsigned i = OldSize; i != Callees.size(); )
+ if (Callees[i]->isDeclaration()) {
+ Callees.erase(Callees.begin()+i);
+ } else
+ ++i;
+ }
+}
+
+static void GetAnyCallees(const DSCallSite &CS,
+ std::vector<Function*> &Callees) {
+ if (CS.isDirectCall()) {
+ if (!CS.getCalleeFunc()->isDeclaration())
+ Callees.push_back(CS.getCalleeFunc());
+ } else {
+ // Get all callees.
+ unsigned OldSize = Callees.size();
+ CS.getCalleeNode()->addFullFunctionList(Callees);
+
+ // If any of the callees are unresolvable, remove the whole batch!
for (unsigned i = OldSize, e = Callees.size(); i != e; ++i)
if (Callees[i]->isDeclaration()) {
Callees.erase(Callees.begin()+OldSize, Callees.end());
@@ -145,6 +164,14 @@
GetAllCallees(*I, Callees);
}
+/// GetAnyAuxCallees - Return a list containing all of the callees in
+/// the aux list for the specified graph in the Callees vector.
+static void GetAnyAuxCallees(DSGraph &G, std::vector<Function*> &Callees) {
+ Callees.clear();
+ for (DSGraph::afc_iterator I = G.afc_begin(), E = G.afc_end(); I != E; ++I)
+ GetAnyCallees(*I, Callees);
+}
+
unsigned BUDataStructures::calculateGraphs(Function *F,
std::vector<Function*> &Stack,
unsigned &NextID,
@@ -168,7 +195,7 @@
// Find all callee functions.
std::vector<Function*> CalleeFunctions;
- GetAllAuxCallees(Graph, CalleeFunctions);
+ GetAnyAuxCallees(Graph, CalleeFunctions);
// The edges out of the current node are the call site targets...
for (unsigned i = 0, e = CalleeFunctions.size(); i != e; ++i) {
@@ -202,8 +229,9 @@
// Should we revisit the graph? Only do it if there are now new resolvable
// callees.
- GetAllAuxCallees(Graph, CalleeFunctions);
- if (!CalleeFunctions.empty()) {
+ std::vector<Function*> CalleeFunctionsNew;
+ GetAnyAuxCallees(Graph, CalleeFunctionsNew);
+ if (CalleeFunctionsNew.size() > CalleeFunctions.size()) {
DOUT << "Recalculating " << F->getName() << " due to new knowledge\n";
ValMap.erase(F);
return calculateGraphs(F, Stack, NextID, ValMap);
@@ -340,107 +368,115 @@
}
GetAllCallees(CS, CalledFuncs);
+ bool isComplete = true;
if (CalledFuncs.empty()) {
// Remember that we could not resolve this yet!
AuxCallsList.splice(AuxCallsList.end(), TempFCs, TempFCs.begin());
+ isComplete = false;
+ GetAnyCallees(CS, CalledFuncs);
+ }
+
+ if (CalledFuncs.empty())
continue;
- } else {
- DSGraph *GI;
- Instruction *TheCall = CS.getCallSite().getInstruction();
-
- if (CalledFuncs.size() == 1) {
- Function *Callee = CalledFuncs[0];
- ActualCallees.insert(std::make_pair(TheCall, Callee));
-
- // Get the data structure graph for the called function.
- GI = &getDSGraph(*Callee); // Graph to inline
- DOUT << " Inlining graph for " << Callee->getName()
- << "[" << 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)
- DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
- DEBUG(std::cerr << " calls " << CalledFuncs.size()
- << " fns from site: " << CS.getCallSite().getInstruction()
- << " " << *CS.getCallSite().getInstruction());
- DEBUG(std::cerr << " Fns =");
- unsigned NumPrinted = 0;
-
- for (std::vector<Function*>::iterator I = CalledFuncs.begin(),
- E = CalledFuncs.end(); I != E; ++I) {
- if (NumPrinted++ < 8) cerr << " " << (*I)->getName();
- // Add the call edges to the call graph.
- ActualCallees.insert(std::make_pair(TheCall, *I));
- }
- 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]);
+ DSGraph *GI;
+ Instruction *TheCall = CS.getCallSite().getInstruction();
+
+ if (CalledFuncs.size() == 1) {
+ Function *Callee = CalledFuncs[0];
+ ActualCallees.insert(std::make_pair(TheCall, Callee));
+
+ // Get the data structure graph for the called function.
+ GI = &getDSGraph(*Callee); // Graph to inline
+ DOUT << " Inlining graph for " << Callee->getName()
+ << "[" << GI->getGraphSize() << "+"
+ << GI->getAuxFunctionCalls().size() << "] into '"
+ << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+ << Graph.getAuxFunctionCalls().size() << "]\n";
+ Graph.mergeInGraph(CS, *Callee, *GI,
+ DSGraph::StripAllocaBit|DSGraph::DontCloneCallNodes|
+ (isComplete?0:DSGraph::DontCloneAuxCallNodes));
+ ++NumBUInlines;
+ } else {
+ if (!Printed)
+ DEBUG(std::cerr << "In Fns: " << Graph.getFunctionNames() << "\n");
+ DEBUG(std::cerr << " calls " << CalledFuncs.size()
+ << " fns from site: " << CS.getCallSite().getInstruction()
+ << " " << *CS.getCallSite().getInstruction());
+ DEBUG(std::cerr << " Fns =");
+ unsigned NumPrinted = 0;
+
+ for (std::vector<Function*>::iterator I = CalledFuncs.begin(),
+ E = CalledFuncs.end(); I != E; ++I) {
+ if (NumPrinted++ < 8) DOUT << " " << (*I)->getName();
+
+ // Add the call edges to the call graph.
+ ActualCallees.insert(std::make_pair(TheCall, *I));
+ }
+ DOUT << "\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;
}
-
- // Clean up the final graph!
- GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
- } else {
- cerr << "***\n*** RECYCLED GRAPH ***\n***\n";
+
+ 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]);
}
-
- GI = IndCallGraph.first;
-
- // Merge the unified graph into this graph now.
- DOUT << " Inlining multi callee graph "
- << "[" << GI->getGraphSize() << "+"
- << GI->getAuxFunctionCalls().size() << "] into '"
- << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
- << Graph.getAuxFunctionCalls().size() << "]\n";
-
- Graph.mergeInGraph(CS, IndCallGraph.second, *GI,
- DSGraph::StripAllocaBit |
- DSGraph::DontCloneCallNodes);
- ++NumBUInlines;
+
+ // Clean up the final graph!
+ GI->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
+ } else {
+ DOUT << "***\n*** RECYCLED GRAPH ***\n***\n";
}
+
+ GI = IndCallGraph.first;
+
+ // Merge the unified graph into this graph now.
+ DOUT << " Inlining multi callee graph "
+ << "[" << GI->getGraphSize() << "+"
+ << GI->getAuxFunctionCalls().size() << "] into '"
+ << Graph.getFunctionNames() << "' [" << Graph.getGraphSize() <<"+"
+ << Graph.getAuxFunctionCalls().size() << "]\n";
+
+ Graph.mergeInGraph(CS, IndCallGraph.second, *GI,
+ DSGraph::StripAllocaBit |
+ DSGraph::DontCloneCallNodes|
+ (isComplete?0:DSGraph::DontCloneAuxCallNodes));
+ ++NumBUInlines;
}
- TempFCs.erase(TempFCs.begin());
+ if (isComplete)
+ TempFCs.erase(TempFCs.begin());
}
// Recompute the Incomplete markers
Modified: poolalloc/trunk/lib/DSA/CallTargets.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/CallTargets.cpp?rev=56857&r1=56856&r2=56857&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/CallTargets.cpp (original)
+++ poolalloc/trunk/lib/DSA/CallTargets.cpp Tue Sep 30 12:11:50 2008
@@ -77,7 +77,6 @@
void CallTargetFinder::print(std::ostream &O, const Module *M) const
{
- return;
O << "[* = incomplete] CS: func list\n";
for (std::map<CallSite, std::vector<Function*> >::const_iterator ii =
IndMap.begin(),
Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=56857&r1=56856&r2=56857&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Tue Sep 30 12:11:50 2008
@@ -1368,7 +1368,6 @@
DestCS.addPtrArg(getClonedNH(SrcCS.getPtrArg(a)));
}
-
//===----------------------------------------------------------------------===//
// DSCallSite Implementation
//===----------------------------------------------------------------------===//
@@ -1493,14 +1492,14 @@
void DSGraph::removeFunctionCalls(Function& F) {
for (std::list<DSCallSite>::iterator I = FunctionCalls.begin(),
E = FunctionCalls.end(); I != E; ++I)
- if (I->isDirectCall() && &I->getCaller() == &F) {
+ if (I->isDirectCall() && I->getCalleeFunc() == &F) {
FunctionCalls.erase(I);
break;
}
for (std::list<DSCallSite>::iterator I = AuxFunctionCalls.begin(),
E = AuxFunctionCalls.end(); I != E; ++I)
- if (I->isDirectCall() && &I->getCaller() == &F) {
+ if (I->isDirectCall() && I->getCalleeFunc() == &F) {
AuxFunctionCalls.erase(I);
break;
}
@@ -2747,7 +2746,7 @@
//Clone or Steal the Source Graph
DSGraph &BaseGraph = GraphSource->getDSGraph(*F);
if (Clone) {
- G = new DSGraph(BaseGraph, GlobalECs);
+ G = new DSGraph(BaseGraph, GlobalECs, DSGraph::DontCloneAuxCallNodes);
} else {
G = new DSGraph(GlobalECs, GraphSource->getTargetData());
G->spliceFrom(BaseGraph);
More information about the llvm-commits
mailing list