Do not do horrible things to the CBU graphs. In particular, we do NOT own
authorChris Lattner <sabre@nondot.org>
Sun, 31 Oct 2004 21:56:11 +0000 (21:56 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 31 Oct 2004 21:56:11 +0000 (21:56 +0000)
the CBU graphs, copy them instead of hacking on the CBU graphs.

Also, instead of forwarding request from ECGraphs clients to the CBU graphs
clients, service them ourselves.

Finally, remove a broken "optimization"

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17378 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/DataStructure/EquivClassGraphs.h
lib/Analysis/DataStructure/EquivClassGraphs.cpp

index 81b9ac8a8128aa77d132248c8a03161b2d922739..ea41ac33df2ff4e6b424c8c91bcbdb403790d20e 100644 (file)
@@ -1,4 +1,4 @@
-//===-- EquivClassGraphs.h - Merge equiv-class graphs & inline bottom-up --===//
+//===-- EquivClassGraphs.h - Merge equiv-class graphs -----------*- C++ -*-===//
 // 
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,14 +7,13 @@
 // 
 //===----------------------------------------------------------------------===//
 //
-// This pass is the same as the complete bottom-up graphs, but
-// with functions partitioned into equivalence classes and a single merged
-// DS graph for all functions in an equivalence class.  After this merging,
-// graphs are inlined bottom-up on the SCCs of the final (CBU) call graph.
+// This pass is the same as the complete bottom-up graphs, but with functions
+// partitioned into equivalence classes and a single merged DS graph for all
+// functions in an equivalence class.  After this merging, graphs are inlined
+// bottom-up on the SCCs of the final (CBU) call graph.
 //
 //===----------------------------------------------------------------------===//
 
-
 #include "llvm/Analysis/DataStructure/DataStructure.h"
 #include "llvm/Analysis/DataStructure/DSGraph.h"
 #include "llvm/ADT/EquivalenceClasses.h"
@@ -49,6 +48,8 @@ namespace PA {
   struct EquivClassGraphs : public ModulePass {
     CompleteBUDataStructures *CBU;
 
+    DSGraph *GlobalsGraph;
+
     // FoldedGraphsMap, one graph for each function
     hash_map<const Function*, DSGraph*> FoldedGraphsMap;
   
@@ -69,7 +70,7 @@ namespace PA {
     /// EquivClassGraphs - Computes the equivalence classes and then the
     /// folded DS graphs for each class.
     /// 
-    virtual bool runOnModule(Module &M) { computeFoldedGraphs(M); return true; }
+    virtual bool runOnModule(Module &M);
 
     /// getCBUDataStructures - Get the CompleteBUDataStructures object
     /// 
@@ -117,15 +118,8 @@ namespace PA {
       return GraphInfo;
     }
 
-    /// sameAsCBUGraph - Check if the folded graph for this function is
-    /// the same as the CBU graph.
-    bool sameAsCBUGraph(const Function &F) const {
-      DSGraph& foldedGraph = getDSGraph(F);
-      return (&foldedGraph == &CBU->getDSGraph(F));
-    }
-
     DSGraph &getGlobalsGraph() const {
-      return CBU->getGlobalsGraph();
+      return *GlobalsGraph;
     }
     
     typedef llvm::BUDataStructures::ActualCalleesTy ActualCalleesTy;
@@ -143,8 +137,6 @@ namespace PA {
     void print(std::ostream &O, const Module *M) const { CBU->print(O, M); }
 
   private:
-    void computeFoldedGraphs(Module &M);
-
     void buildIndirectFunctionSets(Module &M);
 
     unsigned processSCC(DSGraph &FG, Function &F, std::vector<Function*> &Stack,
index c125aa7ef7da1a09cdaabceb4e3a975019e181e3..4c00b7aad9d25e51bca5a5c2761f87dfad09c1a8 100644 (file)
@@ -31,7 +31,8 @@ using namespace llvm;
 namespace {
   RegisterAnalysis<PA::EquivClassGraphs> X("equivdatastructure",
                     "Equivalence-class Bottom-up Data Structure Analysis");
-  Statistic<> NumEquivBUInlines("equivdatastructures", "Number of graphs inlined");
+  Statistic<> NumEquivBUInlines("equivdatastructures",
+                                "Number of graphs inlined");
   Statistic<> NumFoldGraphInlines("Inline equiv-class graphs bottom up",
                                   "Number of graphs inlined");
 }
@@ -44,19 +45,22 @@ Function *PA::EquivClassGraphs::
 getSomeCalleeForCallSite(const CallSite &CS) const {
   Function *thisFunc = CS.getCaller();
   assert(thisFunc && "getDSGraphForCallSite(): Not a valid call site?");
-  DSNode *calleeNode = CBU->getDSGraph(*thisFunc).
-    getNodeForValue(CS.getCalledValue()).getNode();
+  DSGraph &DSG = getDSGraph(*thisFunc);
+  DSNode *calleeNode = DSG.getNodeForValue(CS.getCalledValue()).getNode();
   std::map<DSNode*, Function *>::const_iterator I =
     OneCalledFunction.find(calleeNode);
   return (I == OneCalledFunction.end())? NULL : I->second;
 }
 
-// computeFoldedGraphs - Calculate the bottom up data structure
-// graphs for each function in the program.
+// runOnModule - Calculate the bottom up data structure graphs for each function
+// in the program.
 //
-void PA::EquivClassGraphs::computeFoldedGraphs(Module &M) {
+bool PA::EquivClassGraphs::runOnModule(Module &M) {
   CBU = &getAnalysis<CompleteBUDataStructures>();
 
+  GlobalsGraph = new DSGraph(CBU->getGlobalsGraph());
+  GlobalsGraph->setPrintAuxCalls();
+
   // Find equivalence classes of functions called from common call sites.
   // Fold the CBU graphs for all functions in an equivalence class.
   buildIndirectFunctionSets(M);
@@ -78,6 +82,7 @@ void PA::EquivClassGraphs::computeFoldedGraphs(Module &M) {
       processSCC(getOrCreateGraph(*I), *I, Stack, NextID, ValMap);
 
   getGlobalsGraph().removeTriviallyDeadNodes();
+  return false;
 }
 
 
@@ -163,9 +168,9 @@ void PA::EquivClassGraphs::buildIndirectFunctionSets(Module &M) {
 #endif
 
     if (EqClass.size() > 1) {
-      // This equiv class has multiple functions: merge their graphs.
-      // First, clone the CBU graph for the leader and make it the 
-      // common graph for the equivalence graph.
+      // This equiv class has multiple functions: merge their graphs.  First,
+      // clone the CBU graph for the leader and make it the common graph for the
+      // equivalence graph.
       DSGraph* mergedG = cloneGraph(*LF);
 
       // Record the argument nodes for use in merging later below
@@ -174,9 +179,9 @@ void PA::EquivClassGraphs::buildIndirectFunctionSets(Module &M) {
         if (DS::isPointerType(AI1->getType()))
           GraphInfo.argNodes.push_back(mergedG->getNodeForValue(AI1));
       
-      // Merge in the graphs of all other functions in this equiv. class.
-      // Note that two or more functions may have the same graph, and it
-      // only needs to be merged in once.  Use a set to find repetitions.
+      // Merge in the graphs of all other functions in this equiv. class.  Note
+      // that two or more functions may have the same graph, and it only needs
+      // to be merged in once.  Use a set to find repetitions.
       std::set<DSGraph*> GraphsMerged;
       for (std::set<Function*>::const_iterator EqI = EqClass.begin(),
              EqEnd = EqClass.end(); EqI != EqEnd; ++EqI) {
@@ -227,16 +232,13 @@ DSGraph &PA::EquivClassGraphs::getOrCreateGraph(Function &F) {
   DSGraph *&Graph = FoldedGraphsMap[&F];
   if (Graph) return *Graph;
 
-  // Use the CBU graph directly without copying it.
-  // This automatically updates the FoldedGraphsMap via the reference.
-  Graph = &CBU->getDSGraph(F);
-  return *Graph;
+  return *cloneGraph(F);
 }
 
 DSGraph *PA::EquivClassGraphs::cloneGraph(Function &F) {
   DSGraph *&Graph = FoldedGraphsMap[&F];
   DSGraph &CBUGraph = CBU->getDSGraph(F);
-  assert(Graph == NULL || Graph == &CBUGraph && "Cloning a graph twice?");
+  assert((Graph == NULL || Graph == &CBUGraph) && "Cloning a graph twice?");
 
   // Copy the CBU graph...
   Graph = new DSGraph(CBUGraph);           // updates the map via reference
@@ -326,32 +328,7 @@ void PA::EquivClassGraphs::processGraph(DSGraph &G, Function &F) {
 
   hash_set<Instruction*> calls;
 
-  DSGraph* CallerGraph = sameAsCBUGraph(F) ? NULL : &getOrCreateGraph(F);
-
-  // If the function has not yet been cloned, let's check if any callees
-  // need to be inlined before cloning it.
-  // 
-  for (unsigned i=0, e=G.getFunctionCalls().size(); i!=e && !CallerGraph; ++i) {
-    const DSCallSite &CS = G.getFunctionCalls()[i];
-    Instruction *TheCall = CS.getCallSite().getInstruction();
-    
-    // Loop over all potential callees to find the first non-external callee.
-    // Some inlining is needed if there is such a callee and it has changed.
-    ActualCalleesTy::const_iterator I, E;
-    for (tie(I, E) = getActualCallees().equal_range(TheCall); I != E; ++I)
-      if (!I->second->isExternal() && !sameAsCBUGraph(*I->second)) {
-        // Ok, the caller does need to be cloned... go ahead and do it now.
-        // clone the CBU graph for F now because we have not cloned it so far
-        CallerGraph = cloneGraph(F);
-        break;
-      }
-  }
-
-  if (!CallerGraph) {                   // No inlining is needed.
-    DEBUG(std::cerr << "  --DONE ProcessGraph for function " << F.getName()
-          << " (NO INLINING NEEDED)\n");
-    return;
-  }
+  DSGraph* CallerGraph = &getOrCreateGraph(F);
 
   // Else we need to inline some callee graph.  Visit all call sites.
   // The edges out of the current node are the call site targets...
@@ -377,7 +354,7 @@ void PA::EquivClassGraphs::processGraph(DSGraph &G, Function &F) {
         break;
 
     // Now check if the graph has changed and if so, clone and inline it.
-    if (I != E && !sameAsCBUGraph(*I->second)) {
+    if (I != E) {
       Function *CalleeFunc = I->second;
       
       // Merge the callee's graph into this graph, if not already the same.
@@ -427,6 +404,20 @@ void PA::EquivClassGraphs::processGraph(DSGraph &G, Function &F) {
     CallerGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
   }
 
+
+  // When this graph is finalized, clone the globals in the graph into the
+  // globals graph to make sure it has everything, from all graphs.
+  DSScalarMap &MainSM = CallerGraph->getScalarMap();
+  ReachabilityCloner RC(*CallerGraph->getGlobalsGraph(), *CallerGraph,
+                        DSGraph::StripAllocaBit);
+
+  // Clone everything reachable from globals in the function graph into the
+  // globals graph.
+  for (DSScalarMap::global_iterator I = MainSM.global_begin(),
+         E = MainSM.global_end(); I != E; ++I) 
+    RC.getClonedNH(MainSM[*I]);
+
+
   DEBUG(std::cerr << "  --DONE ProcessGraph for function " 
                   << F.getName() << "\n");
 }