aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/DataStructure/BottomUpClosure.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-11-10 06:52:47 +0000
committerChris Lattner <sabre@nondot.org>2002-11-10 06:52:47 +0000
commita1079051d8a594d12c2dc41b227593bfcc985121 (patch)
treee144ee9da12dff5dff7d71ba8d4131a039d1dee5 /lib/Analysis/DataStructure/BottomUpClosure.cpp
parent5c533ae837a2101e620a4e2f06acaa35f16e5fa7 (diff)
* 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
Diffstat (limited to 'lib/Analysis/DataStructure/BottomUpClosure.cpp')
-rw-r--r--lib/Analysis/DataStructure/BottomUpClosure.cpp58
1 files changed, 42 insertions, 16 deletions
diff --git a/lib/Analysis/DataStructure/BottomUpClosure.cpp b/lib/Analysis/DataStructure/BottomUpClosure.cpp
index c03e1c20e7..a19155dbef 100644
--- a/lib/Analysis/DataStructure/BottomUpClosure.cpp
+++ b/lib/Analysis/DataStructure/BottomUpClosure.cpp
@@ -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;
}