* Do not refer to ActualCallees in CBU, when we can do it locally.

* *DO NOT* print CBU graphs when asked to print our own.  This is just
  FREAKING confusing and misleading: it's better to not print anything.
* Simplify and clean up some code
* Add some more paranoia assertion checking code that I found to track
  down this bug:
* Fix a nasty bug that was causing us to crash on Prolangs-C++/objects,
  where we were missing processing some graphs.  This hunk is the bugfix:

-    if (!I->isExternal() && !FoldedGraphsMap.count(I))
+    if (!I->isExternal() && !ValMap.count(I))

  urg!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17386 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2004-10-31 23:41:26 +00:00
parent 4148266c9d
commit 31d3f671be
2 changed files with 47 additions and 30 deletions

View File

@@ -52,6 +52,10 @@ namespace PA {
// FoldedGraphsMap, one graph for each function // FoldedGraphsMap, one graph for each function
hash_map<const Function*, DSGraph*> FoldedGraphsMap; hash_map<const Function*, DSGraph*> FoldedGraphsMap;
/// ActualCallees - The actual functions callable from indirect call sites.
///
hash_multimap<Instruction*, Function*> ActualCallees;
// Equivalence class where functions that can potentially be called via the // Equivalence class where functions that can potentially be called via the
// same function pointer are in the same class. // same function pointer are in the same class.
@@ -122,9 +126,9 @@ namespace PA {
return *GlobalsGraph; return *GlobalsGraph;
} }
typedef llvm::BUDataStructures::ActualCalleesTy ActualCalleesTy; typedef hash_multimap<Instruction*, Function*> ActualCalleesTy;
const ActualCalleesTy &getActualCallees() const { const ActualCalleesTy &getActualCallees() const {
return CBU->getActualCallees(); return ActualCallees;
} }
virtual void getAnalysisUsage(AnalysisUsage &AU) const { virtual void getAnalysisUsage(AnalysisUsage &AU) const {
@@ -134,7 +138,7 @@ namespace PA {
/// print - Print out the analysis results... /// print - Print out the analysis results...
/// ///
void print(std::ostream &O, const Module *M) const { CBU->print(O, M); } void print(std::ostream &O, const Module *M) const {}
private: private:
void buildIndirectFunctionSets(Module &M); void buildIndirectFunctionSets(Module &M);

View File

@@ -37,6 +37,25 @@ namespace {
"Number of graphs inlined"); "Number of graphs inlined");
} }
#ifndef NDEBUG
template<typename GT>
static void CheckAllGraphs(Module *M, GT &ECGraphs) {
DSGraph &GG = ECGraphs.getGlobalsGraph();
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
if (!I->isExternal()) {
DSGraph &G = ECGraphs.getDSGraph(*I);
DSGraph::NodeMapTy GlobalsGraphNodeMapping;
for (DSScalarMap::global_iterator I = G.getScalarMap().global_begin(),
E = G.getScalarMap().global_end(); I != E; ++I)
DSGraph::computeNodeMapping(G.getNodeForValue(*I),
GG.getNodeForValue(*I),
GlobalsGraphNodeMapping);
}
}
#endif
// getDSGraphForCallSite - Return the common data structure graph for // getDSGraphForCallSite - Return the common data structure graph for
// callees at the specified call site. // callees at the specified call site.
// //
@@ -56,10 +75,13 @@ getSomeCalleeForCallSite(const CallSite &CS) const {
// //
bool PA::EquivClassGraphs::runOnModule(Module &M) { bool PA::EquivClassGraphs::runOnModule(Module &M) {
CBU = &getAnalysis<CompleteBUDataStructures>(); CBU = &getAnalysis<CompleteBUDataStructures>();
CheckAllGraphs(&M, *CBU);
GlobalsGraph = new DSGraph(CBU->getGlobalsGraph()); GlobalsGraph = new DSGraph(CBU->getGlobalsGraph());
GlobalsGraph->setPrintAuxCalls(); GlobalsGraph->setPrintAuxCalls();
ActualCallees = CBU->getActualCallees();
// Find equivalence classes of functions called from common call sites. // Find equivalence classes of functions called from common call sites.
// Fold the CBU graphs for all functions in an equivalence class. // Fold the CBU graphs for all functions in an equivalence class.
buildIndirectFunctionSets(M); buildIndirectFunctionSets(M);
@@ -77,9 +99,11 @@ bool PA::EquivClassGraphs::runOnModule(Module &M) {
} }
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isExternal() && !FoldedGraphsMap.count(I)) if (!I->isExternal() && !ValMap.count(I))
processSCC(getOrCreateGraph(*I), *I, Stack, NextID, ValMap); processSCC(getOrCreateGraph(*I), *I, Stack, NextID, ValMap);
DEBUG(CheckAllGraphs(&M, *this));
getGlobalsGraph().removeTriviallyDeadNodes(); getGlobalsGraph().removeTriviallyDeadNodes();
return false; return false;
} }
@@ -237,7 +261,7 @@ DSGraph &PA::EquivClassGraphs::getOrCreateGraph(Function &F) {
DSGraph *PA::EquivClassGraphs::cloneGraph(Function &F) { DSGraph *PA::EquivClassGraphs::cloneGraph(Function &F) {
DSGraph *&Graph = FoldedGraphsMap[&F]; DSGraph *&Graph = FoldedGraphsMap[&F];
DSGraph &CBUGraph = CBU->getDSGraph(F); DSGraph &CBUGraph = CBU->getDSGraph(F);
assert((Graph == NULL || Graph == &CBUGraph) && "Cloning a graph twice?"); assert(Graph == 0 && "Cloning a graph twice?");
// Copy the CBU graph... // Copy the CBU graph...
Graph = new DSGraph(CBUGraph); // updates the map via reference Graph = new DSGraph(CBUGraph); // updates the map via reference
@@ -280,11 +304,9 @@ unsigned PA::EquivClassGraphs::processSCC(DSGraph &FG, Function &F,
ActualCalleesTy::const_iterator I, E; ActualCalleesTy::const_iterator I, E;
for (tie(I, E) = getActualCallees().equal_range(Call); I != E; ++I) for (tie(I, E) = getActualCallees().equal_range(Call); I != E; ++I)
if (!I->second->isExternal()) { if (!I->second->isExternal()) {
DSGraph &CalleeG = getOrCreateGraph(*I->second); // Process the callee as necessary.
unsigned M = processSCC(getOrCreateGraph(*I->second), *I->second,
// Have we visited the destination function yet? Stack, NextID, ValMap);
std::map<Function*, unsigned>::iterator It = ValMap.find(I->second);
unsigned M = processSCC(CalleeG, *I->second, Stack, NextID, ValMap);
if (M < Min) Min = M; if (M < Min) Min = M;
} }
} }
@@ -296,22 +318,17 @@ unsigned PA::EquivClassGraphs::processSCC(DSGraph &FG, Function &F,
// If this is a new SCC, process it now. // If this is a new SCC, process it now.
bool IsMultiNodeSCC = false; bool IsMultiNodeSCC = false;
while (Stack.back() != &F) { while (Stack.back() != &F) {
DSGraph *NG = &getOrCreateGraph(* Stack.back()); DSGraph *NG = &getOrCreateGraph(*Stack.back());
ValMap[Stack.back()] = ~0U; ValMap[Stack.back()] = ~0U;
// Since all SCCs must be the same as those found in CBU, we do not need to // Since all SCCs must be the same as those found in CBU, we do not need to
// do any merging. Make sure all functions in the SCC share the same graph. // do any merging. Make sure all functions in the SCC share the same graph.
assert(NG == &FG && assert(NG == &FG && "ECG discovered different SCC's than the CBU pass?");
"FoldGraphs: Functions in the same SCC have different graphs?");
Stack.pop_back(); Stack.pop_back();
IsMultiNodeSCC = true; IsMultiNodeSCC = true;
} }
// Clean up the graph before we start inlining a bunch again...
if (IsMultiNodeSCC)
FG.removeTriviallyDeadNodes();
Stack.pop_back(); Stack.pop_back();
processGraph(FG, F); processGraph(FG, F);
@@ -392,17 +409,14 @@ void PA::EquivClassGraphs::processGraph(DSGraph &G, Function &F) {
#endif #endif
} }
// Recompute the Incomplete markers // Recompute the Incomplete markers.
if (CallerGraph != NULL) { assert(CallerGraph->getInlinedGlobals().empty());
assert(CallerGraph->getInlinedGlobals().empty()); CallerGraph->maskIncompleteMarkers();
CallerGraph->maskIncompleteMarkers(); CallerGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
CallerGraph->markIncompleteNodes(DSGraph::MarkFormalArgs);
// Delete dead nodes. Treat globals that are unreachable but that can
// Delete dead nodes. Treat globals that are unreachable but that can // reach live nodes as live.
// reach live nodes as live. CallerGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
CallerGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
}
// When this graph is finalized, clone the globals in the graph into the // When this graph is finalized, clone the globals in the graph into the
// globals graph to make sure it has everything, from all graphs. // globals graph to make sure it has everything, from all graphs.
@@ -416,7 +430,6 @@ void PA::EquivClassGraphs::processGraph(DSGraph &G, Function &F) {
E = MainSM.global_end(); I != E; ++I) E = MainSM.global_end(); I != E; ++I)
RC.getClonedNH(MainSM[*I]); RC.getClonedNH(MainSM[*I]);
DEBUG(std::cerr << " -- DONE ProcessGraph for function "
DEBUG(std::cerr << " --DONE ProcessGraph for function "
<< F.getName() << "\n"); << F.getName() << "\n");
} }