* Make contained ostream not public.
[oota-llvm.git] / include / llvm / Analysis / DSSupport.h
index 1e886fe7c26da97cafa5e16dd2afabed4aea2490..fdbb43236ee51bb17c3bf0790f7a9b63c4a64975 100644 (file)
@@ -1,4 +1,11 @@
 //===- DSSupport.h - Support for datastructure graphs -----------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // Support for graph nodes, call sites, and types.
 //
 #ifndef LLVM_ANALYSIS_DSSUPPORT_H
 #define LLVM_ANALYSIS_DSSUPPORT_H
 
-#include <vector>
 #include <functional>
-#include <string>
-#include <assert.h>
-#include "Support/HashExtras.h"
 #include "Support/hash_set"
+#include "llvm/Support/CallSite.h"
+
+namespace llvm {
 
 class Function;
 class CallInst;
@@ -22,15 +28,16 @@ class Type;
 
 class DSNode;                  // Each node in the graph
 class DSGraph;                 // A graph for a function
+class ReachabilityCloner;
 
 namespace DS { // FIXME: After the paper, this should get cleaned up
-  enum { PointerShift = 3,     // 64bit ptrs = 3, 32 bit ptrs = 2
+  enum { PointerShift = 2,     // 64bit ptrs = 3, 32 bit ptrs = 2
          PointerSize = 1 << PointerShift
   };
 
-  // isPointerType - Return true if this first class type is big enough to hold
-  // a pointer.
-  //
+  /// isPointerType - Return true if this first class type is big enough to hold
+  /// a pointer.
+  ///
   bool isPointerType(const Type *Ty);
 };
 
@@ -60,6 +67,7 @@ public:
   }
   ~DSNodeHandle() { setNode((DSNode*)0); }
   DSNodeHandle &operator=(const DSNodeHandle &H) {
+    if (&H == this) return *this;  // Don't set offset to 0 if self assigning.
     Offset = 0; setNode(H.getNode()); Offset = H.Offset;
     return *this;
   }
@@ -69,6 +77,7 @@ public:
   }
   bool operator>(const DSNodeHandle &H) const { return H < *this; }
   bool operator==(const DSNodeHandle &H) const { // Allow comparison
+    // getNode can change the offset, so we must call getNode() first.
     return getNode() == H.getNode() && Offset == H.Offset;
   }
   bool operator!=(const DSNodeHandle &H) const { return !operator==(H); }
@@ -80,13 +89,14 @@ public:
 
   /// isNull - Check to see if getNode() == 0, without going through the trouble
   /// of checking to see if we are forwarding...
+  ///
   bool isNull() const { return N == 0; }
 
   // Allow explicit conversion to DSNode...
   inline DSNode *getNode() const;  // Defined inline in DSNode.h
   unsigned getOffset() const { return Offset; }
 
-  inline void setNode(DSNode *N);  // Defined inline in DSNode.h
+  inline void setNode(DSNode *N) const;  // Defined inline in DSNode.h
   void setOffset(unsigned O) {
     //assert((!N || Offset < N->Size || (N->Size == 0 && Offset == 0) ||
     //       !N->ForwardNH.isNull()) && "Node handle offset out of range!");
@@ -101,9 +111,10 @@ public:
   /// mergeWith - Merge the logical node pointed to by 'this' with the node
   /// pointed to by 'N'.
   ///
-  void mergeWith(const DSNodeHandle &N);
+  void mergeWith(const DSNodeHandle &N) const;
 
-  // hasLink - Return true if there is a link at the specified offset...
+  /// hasLink - Return true if there is a link at the specified offset...
+  ///
   inline bool hasLink(unsigned Num) const;
 
   /// getLink - Treat this current node pointer as a pointer to a structure of
@@ -117,17 +128,22 @@ private:
   DSNode *HandleForwarding() const;
 };
 
+} // End llvm namespace
+
 namespace std {
-  inline void swap(DSNodeHandle &NH1, DSNodeHandle &NH2) { NH1.swap(NH2); }
+  template<>
+  inline void swap<llvm::DSNodeHandle>(llvm::DSNodeHandle &NH1, llvm::DSNodeHandle &NH2) { NH1.swap(NH2); }
 }
 
+namespace llvm {
+
 //===----------------------------------------------------------------------===//
 /// DSCallSite - Representation of a call site via its call instruction,
 /// the DSNode handle for the callee function (or function pointer), and
 /// the DSNode handles for the function arguments.
 /// 
 class DSCallSite {
-  CallInst    *Inst;                 // Actual call site
+  CallSite     Site;                 // Actual call site
   Function    *CalleeF;              // The function called (direct call)
   DSNodeHandle CalleeN;              // The function node called (indirect call)
   DSNodeHandle RetVal;               // Returned value
@@ -137,7 +153,7 @@ class DSCallSite {
                      const hash_map<const DSNode*, DSNode*> &NodeMap) {
     if (DSNode *N = Src.getNode()) {
       hash_map<const DSNode*, DSNode*>::const_iterator I = NodeMap.find(N);
-      assert(I != NodeMap.end() && "Not not in mapping!");
+      assert(I != NodeMap.end() && "Node not in mapping!");
 
       NH.setOffset(Src.getOffset());
       NH.setNode(I->second);
@@ -148,33 +164,37 @@ class DSCallSite {
                      const hash_map<const DSNode*, DSNodeHandle> &NodeMap) {
     if (DSNode *N = Src.getNode()) {
       hash_map<const DSNode*, DSNodeHandle>::const_iterator I = NodeMap.find(N);
-      assert(I != NodeMap.end() && "Not not in mapping!");
+      assert(I != NodeMap.end() && "Node not in mapping!");
 
       NH.setOffset(Src.getOffset()+I->second.getOffset());
       NH.setNode(I->second.getNode());
     }
   }
 
+  static void InitNH(DSNodeHandle &NH, const DSNodeHandle &Src,
+                     ReachabilityCloner &RC);
+
+
   DSCallSite();                         // DO NOT IMPLEMENT
 public:
   /// Constructor.  Note - This ctor destroys the argument vector passed in.  On
   /// exit, the argument vector is empty.
   ///
-  DSCallSite(CallInst &inst, const DSNodeHandle &rv, DSNode *Callee,
+  DSCallSite(CallSite CS, const DSNodeHandle &rv, DSNode *Callee,
              std::vector<DSNodeHandle> &Args)
-    : Inst(&inst), CalleeF(0), CalleeN(Callee), RetVal(rv) {
+    : Site(CS), CalleeF(0), CalleeN(Callee), RetVal(rv) {
     assert(Callee && "Null callee node specified for call site!");
     Args.swap(CallArgs);
   }
-  DSCallSite(CallInst &inst, const DSNodeHandle &rv, Function *Callee,
+  DSCallSite(CallSite CS, const DSNodeHandle &rv, Function *Callee,
              std::vector<DSNodeHandle> &Args)
-    : Inst(&inst), CalleeF(Callee), RetVal(rv) {
+    : Site(CS), CalleeF(Callee), RetVal(rv) {
     assert(Callee && "Null callee function specified for call site!");
     Args.swap(CallArgs);
   }
 
   DSCallSite(const DSCallSite &DSCS)   // Simple copy ctor
-    : Inst(DSCS.Inst), CalleeF(DSCS.CalleeF), CalleeN(DSCS.CalleeN),
+    : Site(DSCS.Site), CalleeF(DSCS.CalleeF), CalleeN(DSCS.CalleeN),
       RetVal(DSCS.RetVal), CallArgs(DSCS.CallArgs) {}
 
   /// Mapping copy constructor - This constructor takes a preexisting call site
@@ -182,8 +202,8 @@ public:
   /// This is useful when moving a call site from one graph to another.
   ///
   template<typename MapTy>
-  DSCallSite(const DSCallSite &FromCall, const MapTy &NodeMap) {
-    Inst = FromCall.Inst;
+  DSCallSite(const DSCallSite &FromCall, MapTy &NodeMap) {
+    Site = FromCall.Site;
     InitNH(RetVal, FromCall.RetVal, NodeMap);
     InitNH(CalleeN, FromCall.CalleeN, NodeMap);
     CalleeF = FromCall.CalleeF;
@@ -193,6 +213,15 @@ public:
       InitNH(CallArgs[i], FromCall.CallArgs[i], NodeMap);
   }
 
+  const DSCallSite &operator=(const DSCallSite &RHS) {
+    Site     = RHS.Site;
+    CalleeF  = RHS.CalleeF;
+    CalleeN  = RHS.CalleeN;
+    RetVal   = RHS.RetVal;
+    CallArgs = RHS.CallArgs;
+    return *this;
+  }
+
   /// isDirectCall - Return true if this call site is a direct call of the
   /// function specified by getCalleeFunc.  If not, it is an indirect call to
   /// the node specified by getCalleeNode.
@@ -203,7 +232,7 @@ public:
 
   // Accessor functions...
   Function           &getCaller()     const;
-  CallInst           &getCallInst()   const { return *Inst; }
+  CallSite            getCallSite()   const { return Site; }
         DSNodeHandle &getRetVal()           { return RetVal; }
   const DSNodeHandle &getRetVal()     const { return RetVal; }
 
@@ -214,7 +243,7 @@ public:
     assert(!CalleeN.getNode() && CalleeF); return CalleeF;
   }
 
-  unsigned            getNumPtrArgs() const { return CallArgs.size(); }
+  unsigned getNumPtrArgs() const { return CallArgs.size(); }
 
   DSNodeHandle &getPtrArg(unsigned i) {
     assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!");
@@ -227,7 +256,7 @@ public:
 
   void swap(DSCallSite &CS) {
     if (this != &CS) {
-      std::swap(Inst, CS.Inst);
+      std::swap(Site, CS.Site);
       std::swap(RetVal, CS.RetVal);
       std::swap(CalleeN, CS.CalleeN);
       std::swap(CalleeF, CS.CalleeF);
@@ -235,8 +264,9 @@ public:
     }
   }
 
-  // MergeWith - Merge the return value and parameters of the these two call
-  // sites.
+  /// mergeWith - Merge the return value and parameters of the these two call
+  /// sites.
+  ///
   void mergeWith(DSCallSite &CS) {
     getRetVal().mergeWith(CS.getRetVal());
     unsigned MinArgs = getNumPtrArgs();
@@ -268,12 +298,16 @@ public:
   }
 
   bool operator==(const DSCallSite &CS) const {
-    return RetVal == CS.RetVal && CalleeN == CS.CalleeN &&
-           CalleeF == CS.CalleeF && CallArgs == CS.CallArgs;
+    return CalleeF == CS.CalleeF && CalleeN == CS.CalleeN &&
+           RetVal == CS.RetVal && CallArgs == CS.CallArgs;
   }
 };
 
+} // End llvm namespace
+
 namespace std {
-  inline void swap(DSCallSite &CS1, DSCallSite &CS2) { CS1.swap(CS2); }
+  template<>
+  inline void swap<llvm::DSCallSite>(llvm::DSCallSite &CS1,
+                                     llvm::DSCallSite &CS2) { CS1.swap(CS2); }
 }
 #endif