Expand the pass to unify all of the unwind blocks as well
[oota-llvm.git] / include / llvm / Analysis / DataStructure.h
index 4551b16592a15a0b7d877176300351033dfb3efc..d8f30d25d09f9f92f30ed51a181f256b7a42672c 100644 (file)
@@ -7,24 +7,14 @@
 #ifndef LLVM_ANALYSIS_DATA_STRUCTURE_H
 #define LLVM_ANALYSIS_DATA_STRUCTURE_H
 
-#include "llvm/Analysis/DSGraph.h"
 #include "llvm/Pass.h"
-#if 0
-#include "llvm/GlobalValue.h"
-#include "Support/HashExtras.h"
 #include "Support/hash_set"
-#endif
-#include <set>
 
 class Type;
-class GlobalValue;
-#if 0
-class GlobalDSGraph;           // A common graph for globals in a program 
-#endif
-class LocalDataStructures;     // A collection of local graphs for a program
-class BUDataStructures;        // A collection of bu graphs for a program
-class TDDataStructures;        // A collection of td graphs for a program
-
+class CallInst;
+class DSGraph;
+class DSNode;
+class DSCallSite;
 
 // FIXME: move this stuff to a private header
 namespace DataStructureAnalysis {
@@ -35,34 +25,6 @@ namespace DataStructureAnalysis {
 }
 
 
-#if 0
-// GlobalDSGraph - A common graph for all the globals and their outgoing links
-// to externally visible nodes.  This includes GlobalValues, New nodes,
-// Cast nodes, and Calls.  This graph can only be used by one of the
-// individual function graphs, and it goes away when they all go away.
-// 
-class GlobalDSGraph : public DSGraph {
-  hash_set<const DSGraph*> Referrers;
-  void addReference(const DSGraph* referrer);
-  void removeReference(const DSGraph* referrer);
-  friend class DSGraph;                           // give access to Referrers
-  
-  GlobalDSGraph(const GlobalDSGraph &GlobalDSG);  // Do not implement
-
-  // Helper function for cloneGlobals and cloneCalls
-  DSNode* cloneNodeInto(DSNode *OldNode,
-                        std::map<const DSNode*, DSNode*> &NodeCache,
-                        bool GlobalsAreFinal = false);
-
-public:
-  GlobalDSGraph();                                // Create an empty DSGraph
-  virtual ~GlobalDSGraph();
-
-  void    cloneGlobals(DSGraph& Graph, bool CloneCalls = false);
-  void    cloneCalls  (DSGraph& Graph);
-};
-#endif
-
 // LocalDataStructures - The analysis that computes the local data structure
 // graphs for all of the functions in the program.
 //
@@ -71,19 +33,27 @@ public:
 //
 class LocalDataStructures : public Pass {
   // DSInfo, one graph for each function
-  std::map<const Function*, DSGraph*> DSInfo;
+  hash_map<Function*, DSGraph*> DSInfo;
+  DSGraph *GlobalsGraph;
 public:
   ~LocalDataStructures() { releaseMemory(); }
 
   virtual bool run(Module &M);
 
+  bool hasGraph(const Function &F) const {
+    return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
+  }
+
   // getDSGraph - Return the data structure graph for the specified function.
   DSGraph &getDSGraph(const Function &F) const {
-    std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
+    hash_map<Function*, DSGraph*>::const_iterator I =
+      DSInfo.find(const_cast<Function*>(&F));
     assert(I != DSInfo.end() && "Function not in module!");
     return *I->second;
   }
 
+  DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
+
   // print - Print out the analysis results...
   void print(std::ostream &O, const Module *M) const;
 
@@ -96,39 +66,62 @@ public:
   }
 };
 
-#if 0
+
 // BUDataStructures - The analysis that computes the interprocedurally closed
 // data structure graphs for all of the functions in the program.  This pass
-// only performs a "Bottom Up" propogation (hence the name).
+// only performs a "Bottom Up" propagation (hence the name).
 //
 class BUDataStructures : public Pass {
   // DSInfo, one graph for each function
-  std::map<const Function*, DSGraph*> DSInfo;
+  hash_map<Function*, DSGraph*> DSInfo;
+  DSGraph *GlobalsGraph;
+  hash_multimap<CallInst*, Function*> ActualCallees;
 public:
   ~BUDataStructures() { releaseMemory(); }
 
   virtual bool run(Module &M);
 
+  bool hasGraph(const Function &F) const {
+    return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
+  }
+
   // getDSGraph - Return the data structure graph for the specified function.
   DSGraph &getDSGraph(const Function &F) const {
-    std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
+    hash_map<Function*, DSGraph*>::const_iterator I =
+      DSInfo.find(const_cast<Function*>(&F));
     assert(I != DSInfo.end() && "Function not in module!");
     return *I->second;
   }
 
+  DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
+
   // print - Print out the analysis results...
   void print(std::ostream &O, const Module *M) const;
 
   // If the pass pipeline is done with this pass, we can release our memory...
   virtual void releaseMemory();
 
-  // getAnalysisUsage - This obviously provides a data structure graph.
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
     AU.addRequired<LocalDataStructures>();
   }
+
+  typedef hash_multimap<CallInst*, Function*> ActualCalleesTy;
+  const ActualCalleesTy &getActualCallees() const {
+    return ActualCallees;
+  }
+
 private:
-  DSGraph &calculateGraph(Function &F);
+  void calculateGraph(DSGraph &G);
+
+  void calculateReachableGraphs(Function *F);
+
+
+  DSGraph &getOrCreateGraph(Function *F);
+
+  unsigned calculateGraphs(Function *F, std::vector<Function*> &Stack,
+                           unsigned &NextID, 
+                           hash_map<Function*, unsigned> &ValMap);
 };
 
 
@@ -138,36 +131,46 @@ private:
 //
 class TDDataStructures : public Pass {
   // DSInfo, one graph for each function
-  std::map<const Function*, DSGraph*> DSInfo;
+  hash_map<Function*, DSGraph*> DSInfo;
+  hash_set<Function*> ArgsRemainIncomplete;
+  DSGraph *GlobalsGraph;
 public:
-  ~TDDataStructures() { releaseMemory(); }
+  ~TDDataStructures() { releaseMyMemory(); }
 
   virtual bool run(Module &M);
 
+  bool hasGraph(const Function &F) const {
+    return DSInfo.find(const_cast<Function*>(&F)) != DSInfo.end();
+  }
+
   // getDSGraph - Return the data structure graph for the specified function.
   DSGraph &getDSGraph(const Function &F) const {
-    std::map<const Function*, DSGraph*>::const_iterator I = DSInfo.find(&F);
+    hash_map<Function*, DSGraph*>::const_iterator I =
+      DSInfo.find(const_cast<Function*>(&F));
     assert(I != DSInfo.end() && "Function not in module!");
     return *I->second;
   }
 
+  DSGraph &getGlobalsGraph() const { return *GlobalsGraph; }
+
   // print - Print out the analysis results...
   void print(std::ostream &O, const Module *M) const;
 
   // If the pass pipeline is done with this pass, we can release our memory...
-  virtual void releaseMemory();
+  virtual void releaseMyMemory();
 
   // getAnalysisUsage - This obviously provides a data structure graph.
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
     AU.addRequired<BUDataStructures>();
   }
+
 private:
-  DSGraph &calculateGraph(Function &F);
-  void pushGraphIntoCallee(DSGraph &callerGraph, DSGraph &calleeGraph,
-                           std::map<Value*, DSNodeHandle> &OldValMap,
-                           std::map<const DSNode*, DSNode*> &OldNodeMap);
+  void inlineGraphIntoCallees(DSGraph &G);
+  DSGraph &getOrCreateDSGraph(Function &F);
+  void ComputePostOrder(Function &F, hash_set<DSGraph*> &Visited,
+                        std::vector<DSGraph*> &PostOrder,
+                        const BUDataStructures::ActualCalleesTy &ActualCallees);
 };
-#endif
 
 #endif