checkpoint of the new PHITransAddr code, still not done and not used by
[oota-llvm.git] / include / llvm / Analysis / AliasSetTracker.h
index d9e45ce9a1c46682360ba6a3f2b580681099c7dd..42a377e14165a0b6721339c8449e4897f2465990 100644 (file)
 #define LLVM_ANALYSIS_ALIASSETTRACKER_H
 
 #include "llvm/Support/CallSite.h"
-#include "llvm/Support/Streams.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/ADT/hash_map.h"
+#include "llvm/Support/ValueHandle.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
+#include <vector>
 
 namespace llvm {
 
 class AliasAnalysis;
 class LoadInst;
 class StoreInst;
-class FreeInst;
 class VAArgInst;
 class AliasSetTracker;
 class AliasSet;
 
-class AliasSet {
+class AliasSet : public ilist_node<AliasSet> {
   friend class AliasSetTracker;
 
-  class PointerRec;
-  typedef std::pair<Value* const, PointerRec> HashNodePair;
-
   class PointerRec {
-    HashNodePair **PrevInList, *NextInList;
+    Value *Val;  // The pointer this record corresponds to.
+    PointerRec **PrevInList, *NextInList;
     AliasSet *AS;
     unsigned Size;
   public:
-    PointerRec() : PrevInList(0), NextInList(0), AS(0), Size(0) {}
+    PointerRec(Value *V)
+      : Val(V), PrevInList(0), NextInList(0), AS(0), Size(0) {}
 
-    HashNodePair *getNext() const { return NextInList; }
+    Value *getValue() const { return Val; }
+    
+    PointerRec *getNext() const { return NextInList; }
     bool hasAliasSet() const { return AS != 0; }
 
-    HashNodePair** setPrevInList(HashNodePair **PIL) {
+    PointerRec** setPrevInList(PointerRec **PIL) {
       PrevInList = PIL;
       return &NextInList;
     }
@@ -76,21 +77,22 @@ class AliasSet {
       AS = as;
     }
 
-    void removeFromList() {
-      if (NextInList) NextInList->second.PrevInList = PrevInList;
+    void eraseFromList() {
+      if (NextInList) NextInList->PrevInList = PrevInList;
       *PrevInList = NextInList;
       if (AS->PtrListEnd == &NextInList) {
         AS->PtrListEnd = PrevInList;
         assert(*AS->PtrListEnd == 0 && "List not terminated right!");
       }
+      delete this;
     }
   };
 
-  HashNodePair *PtrList, **PtrListEnd;  // Doubly linked list of nodes
-  AliasSet *Forward;             // Forwarding pointer
-  AliasSet *Next, *Prev;         // Doubly linked list of AliasSets
+  PointerRec *PtrList, **PtrListEnd;  // Doubly linked list of nodes.
+  AliasSet *Forward;             // Forwarding pointer.
+  AliasSet *Next, *Prev;         // Doubly linked list of AliasSets.
 
-  std::vector<CallSite> CallSites; // All calls & invokes in this node
+  std::vector<CallSite> CallSites; // All calls & invokes in this alias set.
 
   // RefCount - Number of nodes pointing to this AliasSet plus the number of
   // AliasSets forwarding to it.
@@ -118,12 +120,6 @@ class AliasSet {
   // Volatile - True if this alias set contains volatile loads or stores.
   bool Volatile : 1;
 
-  friend struct ilist_traits<AliasSet>;
-  AliasSet *getPrev() const { return Prev; }
-  AliasSet *getNext() const { return Next; }
-  void setPrev(AliasSet *P) { Prev = P; }
-  void setNext(AliasSet *N) { Next = N; }
-
   void addRef() { ++RefCount; }
   void dropRef(AliasSetTracker &AST) {
     assert(RefCount >= 1 && "Invalid reference count detected!");
@@ -157,15 +153,15 @@ public:
   iterator end()   const { return iterator(); }
   bool empty() const { return PtrList == 0; }
 
-  void print(std::ostream &OS) const;
-  void print(std::ostream *OS) const { if (OS) print(*OS); }
+  void print(raw_ostream &OS) const;
   void dump() const;
 
   /// Define an iterator for alias sets... this is just a forward iterator.
-  class iterator : public forward_iterator<HashNodePair, ptrdiff_t> {
-    HashNodePair *CurNode;
+  class iterator : public std::iterator<std::forward_iterator_tag,
+                                        PointerRec, ptrdiff_t> {
+    PointerRec *CurNode;
   public:
-    explicit iterator(HashNodePair *CN = 0) : CurNode(CN) {}
+    explicit iterator(PointerRec *CN = 0) : CurNode(CN) {}
 
     bool operator==(const iterator& x) const {
       return CurNode == x.CurNode;
@@ -183,12 +179,12 @@ public:
     }
     value_type *operator->() const { return &operator*(); }
 
-    Value *getPointer() const { return CurNode->first; }
-    unsigned getSize() const { return CurNode->second.getSize(); }
+    Value *getPointer() const { return CurNode->getValue(); }
+    unsigned getSize() const { return CurNode->getSize(); }
 
     iterator& operator++() {                // Preincrement
       assert(CurNode && "Advancing past AliasSet.end()!");
-      CurNode = CurNode->second.getNext();
+      CurNode = CurNode->getNext();
       return *this;
     }
     iterator operator++(int) { // Postincrement
@@ -197,17 +193,17 @@ public:
   };
 
 private:
-  // Can only be created by AliasSetTracker
+  // Can only be created by AliasSetTracker. Also, ilist creates one
+  // to serve as a sentinel.
+  friend struct ilist_sentinel_traits<AliasSet>;
   AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
                AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
   }
 
-  AliasSet(const AliasSet &AS) {
-    assert(0 && "Copy ctor called!?!?!");
-    abort();
-  }
+  AliasSet(const AliasSet &AS);        // do not implement
+  void operator=(const AliasSet &AS);  // do not implement
 
-  HashNodePair *getSomePointer() const {
+  PointerRec *getSomePointer() const {
     return PtrList;
   }
 
@@ -228,7 +224,7 @@ private:
 
   void removeFromTracker(AliasSetTracker &AST);
 
-  void addPointer(AliasSetTracker &AST, HashNodePair &Entry, unsigned Size,
+  void addPointer(AliasSetTracker &AST, PointerRec &Entry, unsigned Size,
                   bool KnownMustAlias = false);
   void addCallSite(CallSite CS, AliasAnalysis &AA);
   void removeCallSite(CallSite CS) {
@@ -247,18 +243,38 @@ private:
   bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
 };
 
-inline std::ostream& operator<<(std::ostream &OS, const AliasSet &AS) {
+inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
   AS.print(OS);
   return OS;
 }
 
 
 class AliasSetTracker {
+  /// CallbackVH - A CallbackVH to arrange for AliasSetTracker to be
+  /// notified whenever a Value is deleted.
+  class ASTCallbackVH : public CallbackVH {
+    AliasSetTracker *AST;
+    virtual void deleted();
+  public:
+    ASTCallbackVH(Value *V, AliasSetTracker *AST = 0);
+    ASTCallbackVH &operator=(Value *V);
+  };
+  /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that ASTCallbackVH
+  /// is not a POD (it needs its destructor called).
+  struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {
+    static bool isPod() { return false; }
+  };
+
   AliasAnalysis &AA;
   ilist<AliasSet> AliasSets;
 
+  typedef DenseMap<ASTCallbackVH, AliasSet::PointerRec*,
+                   ASTCallbackVHDenseMapInfo>
+    PointerMapType;
+
   // Map from pointers to their node
-  hash_map<Value*, AliasSet::PointerRec> PointerMap;
+  PointerMapType PointerMap;
+
 public:
   /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
   /// the specified alias analysis object to disambiguate load and store
@@ -281,7 +297,6 @@ public:
   bool add(Value *Ptr, unsigned Size);  // Add a location
   bool add(LoadInst *LI);
   bool add(StoreInst *SI);
-  bool add(FreeInst *FI);
   bool add(VAArgInst *VAAI);
   bool add(CallSite CS);          // Call/Invoke instructions
   bool add(CallInst *CI)   { return add(CallSite(CI)); }
@@ -296,7 +311,6 @@ public:
   bool remove(Value *Ptr, unsigned Size);  // Remove a location
   bool remove(LoadInst *LI);
   bool remove(StoreInst *SI);
-  bool remove(FreeInst *FI);
   bool remove(VAArgInst *VAAI);
   bool remove(CallSite CS);
   bool remove(CallInst *CI)   { return remove(CallSite(CI)); }
@@ -304,10 +318,7 @@ public:
   bool remove(Instruction *I);
   void remove(AliasSet &AS);
   
-  void clear() {
-    PointerMap.clear();
-    AliasSets.clear();
-  }
+  void clear();
 
   /// getAliasSets - Return the alias sets that are active.
   ///
@@ -359,19 +370,20 @@ public:
   iterator begin() { return AliasSets.begin(); }
   iterator end()   { return AliasSets.end(); }
 
-  void print(std::ostream &OS) const;
-  void print(std::ostream *OS) const { if (OS) print(*OS); }
+  void print(raw_ostream &OS) const;
   void dump() const;
 
 private:
   friend class AliasSet;
   void removeAliasSet(AliasSet *AS);
 
-  AliasSet::HashNodePair &getEntryFor(Value *V) {
-    // Standard operator[], except that it returns the whole pair, not just
-    // ->second.
-    return *PointerMap.insert(AliasSet::HashNodePair(V,
-                                            AliasSet::PointerRec())).first;
+  // getEntryFor - Just like operator[] on the map, except that it creates an
+  // entry for the pointer if it doesn't already exist.
+  AliasSet::PointerRec &getEntryFor(Value *V) {
+    AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
+    if (Entry == 0)
+      Entry = new AliasSet::PointerRec(V);
+    return *Entry;
   }
 
   AliasSet &addPointer(Value *P, unsigned Size, AliasSet::AccessType E,
@@ -386,7 +398,7 @@ private:
   AliasSet *findAliasSetForCallSite(CallSite CS);
 };
 
-inline std::ostream& operator<<(std::ostream &OS, const AliasSetTracker &AST) {
+inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
   AST.print(OS);
   return OS;
 }