#include "llvm/Analysis/DataStructure.h"
#include "llvm/Module.h"
#include "Support/Statistic.h"
+#include "Support/Debug.h"
#include "DSCallSiteIterator.h"
namespace {
Statistic<> MaxSCC("budatastructure", "Maximum SCC Size in Call Graph");
+ Statistic<> NumBUInlines("budatastructures", "Number of graphs inlined");
+ Statistic<> NumCallEdges("budatastructures", "Number of 'actual' call edges");
RegisterAnalysis<BUDataStructures>
X("budatastructure", "Bottom-up Data Structure Analysis");
#endif
calculateReachableGraphs(I); // Calculate all graphs...
}
+
+ NumCallEdges += ActualCallees.size();
return false;
}
}
}
+ // Clean up the graph before we start inlining a bunch again...
+ SCCGraph->removeTriviallyDeadNodes();
+
// Now that we have one big happy family, resolve all of the call sites in
// the graph...
calculateGraph(*SCCGraph);
// Resolve the current call...
Function *Callee = *I;
- const DSCallSite &CS = I.getCallSite();
- ActualCallees.insert(std::make_pair(&CS.getCallInst(), Callee));
+ DSCallSite CS = I.getCallSite();
if (Callee->isExternal()) {
// Ignore this case, simple varargs functions we cannot stub out!
Graph.mergeInGraph(CS, *Callee, Graph, 0);
} else {
+ ActualCallees.insert(std::make_pair(&CS.getCallInst(), Callee));
+
// Get the data structure graph for the called function.
//
DSGraph &GI = getDSGraph(*Callee); // Graph to inline
Graph.mergeInGraph(CS, *Callee, GI,
DSGraph::KeepModRefBits |
DSGraph::StripAllocaBit | DSGraph::DontCloneCallNodes);
+ ++NumBUInlines;
#if 0
Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_after_" +
TempFCs.clear();
- // Recompute the Incomplete markers. If there are any function calls left
- // now that are complete, we must loop!
+ // Re-materialize nodes from the globals graph.
+ // Do not ignore globals inlined from callees -- they are not up-to-date!
+ Graph.getInlinedGlobals().clear();
+ Graph.updateFromGlobalGraph();
+
+ // Recompute the Incomplete markers
Graph.maskIncompleteMarkers();
Graph.markIncompleteNodes(DSGraph::MarkFormalArgs);
- // FIXME: materialize nodes from the globals graph as neccesary...
+
+ // Delete dead nodes. Treat globals that are unreachable but that can
+ // reach live nodes as live.
Graph.removeDeadNodes(DSGraph::KeepUnreachableGlobals);
//Graph.writeGraphToFile(std::cerr, "bu_" + F.getName());