mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-31 09:11:13 +00:00
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:
parent
e806173ab6
commit
2f3469013e
@ -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) {
|
||||||
|
if (N)
|
||||||
for (df_iterator<const DSNode*> I = df_begin(N), E = df_end(N); I != E; ++I)
|
for (df_iterator<const DSNode*> I = df_begin(N), E = df_end(N); I != E; ++I)
|
||||||
if (RC.hasClonedNode(*I))
|
if (RC.hasClonedNode(*I))
|
||||||
return true;
|
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,7 +1241,7 @@ 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());
|
||||||
@ -1239,12 +1249,13 @@ void DSGraph::mergeInGraph(const DSCallSite &CS, Function &F,
|
|||||||
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,21 +1274,38 @@ 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;
|
||||||
|
while (MadeChange) {
|
||||||
|
MadeChange = false;
|
||||||
for (hash_set<GlobalVariable*>::iterator I = NonCopiedGlobals.begin();
|
for (hash_set<GlobalVariable*>::iterator I = NonCopiedGlobals.begin();
|
||||||
I != NonCopiedGlobals.end();) {
|
I != NonCopiedGlobals.end();) {
|
||||||
DSNode *GlobalNode = Graph.getNodeForValue(*I).getNode();
|
DSNode *GlobalNode = Graph.getNodeForValue(*I).getNode();
|
||||||
if (RC.hasClonedNode(GlobalNode)) {
|
if (RC.hasClonedNode(GlobalNode)) {
|
||||||
// Already cloned it, remove from set.
|
// Already cloned it, remove from set.
|
||||||
NonCopiedGlobals.erase(I++);
|
NonCopiedGlobals.erase(I++);
|
||||||
|
MadeChange = true;
|
||||||
} else if (PathExistsToClonedNode(GlobalNode, RC)) {
|
} else if (PathExistsToClonedNode(GlobalNode, RC)) {
|
||||||
RC.getClonedNH(Graph.getNodeForValue(*I));
|
RC.getClonedNH(Graph.getNodeForValue(*I));
|
||||||
NonCopiedGlobals.erase(I++);
|
NonCopiedGlobals.erase(I++);
|
||||||
|
MadeChange = true;
|
||||||
} else {
|
} else {
|
||||||
++I;
|
++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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DSNodeHandle RetVal = getReturnNodeFor(F);
|
DSNodeHandle RetVal = getReturnNodeFor(F);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user