Only clone nodes that are needed in the caller, don't clone ALL aux calls. This improves

povray from having ~600K nodes and 300K call nodes to 65K nodes and 25K call nodes.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12109 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2004-03-04 03:57:53 +00:00
parent e806173ab6
commit 2f3469013e

View File

@ -1183,12 +1183,22 @@ void DSGraph::cloneInto(const DSGraph &G, DSScalarMap &OldValMap,
} }
static bool PathExistsToClonedNode(const DSNode *N, ReachabilityCloner &RC) { static bool PathExistsToClonedNode(const DSNode *N, ReachabilityCloner &RC) {
for (df_iterator<const DSNode*> I = df_begin(N), E = df_end(N); I != E; ++I) if (N)
if (RC.hasClonedNode(*I)) for (df_iterator<const DSNode*> I = df_begin(N), E = df_end(N); I != E; ++I)
return true; if (RC.hasClonedNode(*I))
return true;
return false; return false;
} }
static bool PathExistsToClonedNode(const DSCallSite &CS,
ReachabilityCloner &RC) {
if (PathExistsToClonedNode(CS.getRetVal().getNode(), RC))
return true;
for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i)
if (PathExistsToClonedNode(CS.getPtrArg(i).getNode(), RC))
return true;
return false;
}
/// mergeInGraph - The method is used for merging graphs together. If the /// mergeInGraph - The method is used for merging graphs together. If the
/// argument graph is not *this, it makes a clone of the specified graph, then /// argument graph is not *this, it makes a clone of the specified graph, then
@ -1231,20 +1241,21 @@ void DSGraph::mergeInGraph(const DSCallSite &CS, Function &F,
if (!CS.getRetVal().isNull()) if (!CS.getRetVal().isNull())
RC.merge(CS.getRetVal(), Graph.getReturnNodeFor(F)); RC.merge(CS.getRetVal(), Graph.getReturnNodeFor(F));
// If requested, copy the calls or aux-calls lists. // If requested, copy all of the calls.
if (!(CloneFlags & DontCloneCallNodes)) { if (!(CloneFlags & DontCloneCallNodes)) {
// Copy the function calls list... // Copy the function calls list...
FunctionCalls.reserve(FunctionCalls.size()+Graph.FunctionCalls.size()); FunctionCalls.reserve(FunctionCalls.size()+Graph.FunctionCalls.size());
for (unsigned i = 0, ei = Graph.FunctionCalls.size(); i != ei; ++i) for (unsigned i = 0, ei = Graph.FunctionCalls.size(); i != ei; ++i)
FunctionCalls.push_back(DSCallSite(Graph.FunctionCalls[i], RC)); FunctionCalls.push_back(DSCallSite(Graph.FunctionCalls[i], RC));
} }
// If the user has us copying aux calls (the normal case), set up a data
// structure to keep track of which ones we've copied over.
std::vector<bool> CopiedAuxCall;
if (!(CloneFlags & DontCloneAuxCallNodes)) { if (!(CloneFlags & DontCloneAuxCallNodes)) {
// Copy the auxiliary function calls list...
AuxFunctionCalls.reserve(AuxFunctionCalls.size()+ AuxFunctionCalls.reserve(AuxFunctionCalls.size()+
Graph.AuxFunctionCalls.size()); Graph.AuxFunctionCalls.size());
for (unsigned i = 0, ei = Graph.AuxFunctionCalls.size(); i != ei; ++i) CopiedAuxCall.resize(Graph.AuxFunctionCalls.size());
AuxFunctionCalls.push_back(DSCallSite(Graph.AuxFunctionCalls[i], RC));
} }
// Clone over all globals that appear in the caller and callee graphs. // Clone over all globals that appear in the caller and callee graphs.
@ -1263,18 +1274,35 @@ void DSGraph::mergeInGraph(const DSCallSite &CS, Function &F,
// maintain the connection information. Every time we decide to include a // maintain the connection information. Every time we decide to include a
// new global, this might make other globals live, so we must iterate // new global, this might make other globals live, so we must iterate
// unfortunately. // unfortunately.
bool MadeChange = false; bool MadeChange = true;
for (hash_set<GlobalVariable*>::iterator I = NonCopiedGlobals.begin(); while (MadeChange) {
I != NonCopiedGlobals.end();) { MadeChange = false;
DSNode *GlobalNode = Graph.getNodeForValue(*I).getNode(); for (hash_set<GlobalVariable*>::iterator I = NonCopiedGlobals.begin();
if (RC.hasClonedNode(GlobalNode)) { I != NonCopiedGlobals.end();) {
// Already cloned it, remove from set. DSNode *GlobalNode = Graph.getNodeForValue(*I).getNode();
NonCopiedGlobals.erase(I++); if (RC.hasClonedNode(GlobalNode)) {
} else if (PathExistsToClonedNode(GlobalNode, RC)) { // Already cloned it, remove from set.
RC.getClonedNH(Graph.getNodeForValue(*I)); NonCopiedGlobals.erase(I++);
NonCopiedGlobals.erase(I++); MadeChange = true;
} else { } else if (PathExistsToClonedNode(GlobalNode, RC)) {
++I; RC.getClonedNH(Graph.getNodeForValue(*I));
NonCopiedGlobals.erase(I++);
MadeChange = true;
} else {
++I;
}
}
// If requested, copy any aux calls that can reach copied nodes.
if (!(CloneFlags & DontCloneAuxCallNodes)) {
for (unsigned i = 0, ei = Graph.AuxFunctionCalls.size(); i != ei; ++i)
if (!CopiedAuxCall[i] &&
PathExistsToClonedNode(Graph.AuxFunctionCalls[i], RC)) {
AuxFunctionCalls.push_back(DSCallSite(Graph.AuxFunctionCalls[i],
RC));
CopiedAuxCall[i] = true;
MadeChange = true;
}
} }
} }