mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-16 16:37:30 +00:00
* Bottom-Up graphs print the Aux call vector
* Significantly improve DEBUG output * Aggressively fold calls together if we inlined a graph that provides call nodes. * Add a bailout if the current graph has over 200 call nodes in it, this is a really whacky case that should never happen. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4675 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5c533ae837
commit
a1079051d8
@ -27,7 +27,7 @@ bool BUDataStructures::run(Module &M) {
|
||||
// Simply calculate the graphs for each function...
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
|
||||
if (!I->isExternal())
|
||||
calculateGraph(*I);
|
||||
calculateGraph(*I, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ void BUDataStructures::releaseMemory() {
|
||||
GlobalsGraph = 0;
|
||||
}
|
||||
|
||||
DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
DSGraph &BUDataStructures::calculateGraph(Function &F, unsigned Indent) {
|
||||
// Make sure this graph has not already been calculated, or that we don't get
|
||||
// into an infinite loop with mutually recursive functions.
|
||||
//
|
||||
@ -56,11 +56,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
// Copy the local version into DSInfo...
|
||||
Graph = new DSGraph(getAnalysis<LocalDataStructures>().getDSGraph(F));
|
||||
Graph->setGlobalsGraph(GlobalsGraph);
|
||||
|
||||
#if 0
|
||||
// Populate the GlobalsGraph with globals from this one.
|
||||
Graph->GlobalsGraph->cloneGlobals(*Graph, /*cloneCalls*/ false);
|
||||
#endif
|
||||
Graph->setPrintAuxCalls();
|
||||
|
||||
// Start resolving calls...
|
||||
std::vector<DSCallSite> &FCs = Graph->getAuxFunctionCalls();
|
||||
@ -68,7 +64,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
// Start with a copy of the original call sites...
|
||||
FCs = Graph->getFunctionCalls();
|
||||
|
||||
DEBUG(std::cerr << " [BU] Inlining: " << F.getName() << "\n");
|
||||
DEBUG(std::cerr << std::string(Indent*4, ' ')
|
||||
<< "[BU] Calculating graph for: " << F.getName() << "\n");
|
||||
|
||||
bool Inlined;
|
||||
do {
|
||||
@ -86,6 +83,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
std::vector<GlobalValue*> Callees =
|
||||
Call.getCallee().getNode()->getGlobals();
|
||||
|
||||
unsigned OldNumCalls = FCs.size();
|
||||
|
||||
// Loop over the functions, inlining whatever we can...
|
||||
for (unsigned c = 0; c != Callees.size(); ++c) {
|
||||
// Must be a function type, so this cast MUST succeed.
|
||||
@ -94,7 +93,8 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
if (&FI == &F) {
|
||||
// Self recursion... simply link up the formal arguments with the
|
||||
// actual arguments...
|
||||
DEBUG(std::cerr << "\t[BU] Self Inlining: " << F.getName() << "\n");
|
||||
DEBUG(std::cerr << std::string(Indent*4, ' ')
|
||||
<< " [BU] Self Inlining: " << F.getName() << "\n");
|
||||
|
||||
// Handle self recursion by resolving the arguments and return value
|
||||
Graph->mergeInGraph(Call, *Graph, DSGraph::StripAllocaBit);
|
||||
@ -103,17 +103,20 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
Callees.erase(Callees.begin()+c--);
|
||||
|
||||
} else if (!FI.isExternal()) {
|
||||
DEBUG(std::cerr << "\t[BU] In " << F.getName() << " inlining: "
|
||||
DEBUG(std::cerr << std::string(Indent*4, ' ')
|
||||
<< " [BU] In " << F.getName() << " inlining: "
|
||||
<< FI.getName() << "\n");
|
||||
|
||||
// Get the data structure graph for the called function, closing it
|
||||
// if possible (which is only impossible in the case of mutual
|
||||
// recursion...
|
||||
//
|
||||
DSGraph &GI = calculateGraph(FI); // Graph to inline
|
||||
DSGraph &GI = calculateGraph(FI, Indent+1); // Graph to inline
|
||||
|
||||
DEBUG(std::cerr << "\t\t[BU] Got graph for " << FI.getName()
|
||||
<< " in: " << F.getName() << "\n");
|
||||
DEBUG(std::cerr << std::string(Indent*4, ' ')
|
||||
<< " [BU] Got graph for " << FI.getName()
|
||||
<< " in: " << F.getName() << "[" << GI.getGraphSize() << "+"
|
||||
<< GI.getAuxFunctionCalls().size() << "]\n");
|
||||
|
||||
// Handle self recursion by resolving the arguments and return value
|
||||
Graph->mergeInGraph(Call, GI, DSGraph::StripAllocaBit |
|
||||
@ -124,7 +127,7 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
|
||||
} else if (FI.getName() == "printf" || FI.getName() == "sscanf" ||
|
||||
FI.getName() == "fprintf" || FI.getName() == "open" ||
|
||||
FI.getName() == "sprintf") {
|
||||
FI.getName() == "sprintf" || FI.getName() == "fputs") {
|
||||
// FIXME: These special cases (eg printf) should go away when we can
|
||||
// define functions that take a variable number of arguments.
|
||||
|
||||
@ -146,7 +149,26 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
assert(0 && "Unimpl!");
|
||||
Inlined = true;
|
||||
}
|
||||
|
||||
// If we just inlined a function that had call nodes, chances are that
|
||||
// the call nodes are redundant with ones we already have. Eliminate
|
||||
// those call nodes now.
|
||||
//
|
||||
if (FCs.size() > OldNumCalls)
|
||||
Graph->removeTriviallyDeadNodes();
|
||||
}
|
||||
|
||||
if (FCs.size() > 200) {
|
||||
std::cerr << "Aborted inlining fn: '" << F.getName() << "'!"
|
||||
<< std::endl;
|
||||
Graph->maskIncompleteMarkers();
|
||||
Graph->markIncompleteNodes();
|
||||
Graph->removeDeadNodes();
|
||||
Graph->writeGraphToFile(std::cerr, "crap."+F.getName());
|
||||
exit(1);
|
||||
return *Graph;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Recompute the Incomplete markers. If there are any function calls left
|
||||
@ -156,11 +178,15 @@ DSGraph &BUDataStructures::calculateGraph(Function &F) {
|
||||
Graph->markIncompleteNodes();
|
||||
Graph->removeDeadNodes();
|
||||
}
|
||||
|
||||
} while (Inlined && !FCs.empty());
|
||||
|
||||
DEBUG(std::cerr << " [BU] Done inlining: " << F.getName() << " ["
|
||||
<< Graph->getGraphSize() << "+" << Graph->getFunctionCalls().size()
|
||||
DEBUG(std::cerr << std::string(Indent*4, ' ')
|
||||
<< "[BU] Done inlining: " << F.getName() << " ["
|
||||
<< Graph->getGraphSize() << "+" << Graph->getAuxFunctionCalls().size()
|
||||
<< "]\n");
|
||||
|
||||
//Graph->writeGraphToFile(std::cerr, "bu_" + F.getName());
|
||||
|
||||
return *Graph;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user