* 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:
Chris Lattner 2002-11-10 06:52:47 +00:00
parent 5c533ae837
commit a1079051d8

View File

@ -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;
}