AliasSetTracker.h revision 31a9d185bfa253af2f0fece59d8b1227dad64b15
1009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
2009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//
3009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner// This file defines two classes: AliasSetTracker and AliasSet.  These interface
4009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner// are used to classify a collection of pointer references into a maximal number
5009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner// of disjoint sets.  Each AliasSet object constructed by the AliasSetTracker
6009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner// object refers to memory disjoint from the other sets.
7009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//
8009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//===----------------------------------------------------------------------===//
9009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
10009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
11009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner#define LLVM_ANALYSIS_ALIASSETTRACKER_H
12009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
139971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner#include "llvm/Support/CallSite.h"
149971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner#include "Support/iterator"
159971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner#include "Support/hash_map"
169971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner#include "Support/ilist"
17009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasAnalysis;
18009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass LoadInst;
19009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass StoreInst;
20009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSetTracker;
219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerclass AliasSet;
22009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
23009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSet {
24009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  friend class AliasSetTracker;
259971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
269971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  struct PointerRec;
279971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef std::pair<Value* const, PointerRec> HashNodePair;
289971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
299971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  class PointerRec {
309971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    HashNodePair *NextInList;
319971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *AS;
3231a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    unsigned Size;
339971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  public:
3431a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    PointerRec() : NextInList(0), AS(0), Size(0) {}
359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    HashNodePair *getNext() const { return NextInList; }
379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool hasAliasSet() const { return AS != 0; }
389971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    void updateSize(unsigned NewSize) {
4031a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner      if (NewSize > Size) Size = NewSize;
4131a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    }
4231a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner
4331a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    unsigned getSize() const { return Size; }
4431a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner
459971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *getAliasSet(AliasSetTracker &AST) {
469971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(AS && "No AliasSet yet!");
479971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      if (AS->Forward) {
489971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        AliasSet *OldAS = AS;
499971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        AS = OldAS->getForwardedTarget(AST);
509971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        if (--OldAS->RefCount == 0)
519971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner          OldAS->removeFromTracker(AST);
529971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        AS->RefCount++;
539971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      }
549971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return AS;
559971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
569971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
579971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    void setAliasSet(AliasSet *as) {
589971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(AS == 0 && "Already have an alias set!");
599971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      AS = as;
609971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
619971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    void setTail(HashNodePair *T) {
629971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(NextInList == 0 && "Already have tail!");
639971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      NextInList = T;
649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
659971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  };
669971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
679971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  HashNodePair *PtrListHead, *PtrListTail; // Singly linked list of nodes
689971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *Forward;             // Forwarding pointer
699971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *Next, *Prev;         // Doubly linked list of AliasSets
709971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
719971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  std::vector<CallSite> CallSites; // All calls & invokes in this node
729971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
739971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // RefCount - Number of nodes pointing to this AliasSet plus the number of
749971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // AliasSets forwarding to it.
759971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  unsigned RefCount : 29;
769971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
77009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AccessType - Keep track of whether this alias set merely refers to the
78009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// locations of memory, whether it modifies the memory, or whether it does
799971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// both.  The lattice goes from "NoModRef" to either Refs or Mods, then to
809971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// ModRef as neccesary.
81009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
82009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  enum AccessType {
839971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    NoModRef = 0, Refs = 1,         // Ref = bit 1
849971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    Mods     = 2, ModRef = 3        // Mod = bit 2
85009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  };
869971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  unsigned AccessTy : 2;
87009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
88009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AliasType - Keep track the relationships between the pointers in the set.
89009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// Lattice goes from MustAlias to MayAlias.
90009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
91009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  enum AliasType {
929971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    MustAlias = 0, MayAlias = 1
93009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  };
949971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  unsigned AliasTy : 1;
95009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
969971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// Define an iterator for alias sets... this is just a forward iterator.
9731a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  class iterator : public forward_iterator<HashNodePair, ptrdiff_t> {
989971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    HashNodePair *CurNode;
999971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  public:
1009971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator(HashNodePair *CN = 0) : CurNode(CN) {}
1019971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1029971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool operator==(const iterator& x) const {
1039971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return CurNode == x.CurNode;
1049971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1059971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool operator!=(const iterator& x) const { return !operator==(x); }
106009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
1079971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    const iterator &operator=(const iterator &I) {
1089971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      CurNode = I.CurNode;
1099971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return *this;
1109971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1119971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
11231a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    value_type &operator*() const {
1139971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(CurNode && "Dereferencing AliasSet.end()!");
11431a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner      return *CurNode;
1159971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
11631a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    value_type *operator->() const { return &operator*(); }
1179971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1189971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator& operator++() {                // Preincrement
1199971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(CurNode && "Advancing past AliasSet.end()!");
1209971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      CurNode = CurNode->second.getNext();
1219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return *this;
1229971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1239971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator operator++(int) { // Postincrement
1249971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      iterator tmp = *this; ++*this; return tmp;
1259971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1269971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  };
1279971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1289971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  friend class ilist_traits<AliasSet>;
1299971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *getPrev() const { return Prev; }
1309971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *getNext() const { return Next; }
1319971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void setPrev(AliasSet *P) { Prev = P; }
1329971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void setNext(AliasSet *N) { Next = N; }
1339971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1349971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerpublic:
1359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// Accessors...
1369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  bool isRef() const { return AccessTy & Refs; }
1379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  bool isMod() const { return AccessTy & Mods; }
1389971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  bool isMustAlias() const { return AliasTy == MustAlias; }
1399971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  bool isMayAlias()  const { return AliasTy == MayAlias; }
140009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
141009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// mergeSetIn - Merge the specified alias set into this alias set...
142009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
1439971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void mergeSetIn(AliasSet &AS);
144009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
1459971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Alias Set iteration - Allow access to all of the pointer which are part of
1469971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // this alias set...
1479971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator begin() const { return iterator(PtrListHead); }
1489971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator end()   const { return iterator(); }
1499971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1509971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void print(std::ostream &OS) const;
1519971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void dump() const;
152009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
153009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerprivate:
1549971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Can only be created by AliasSetTracker
1559971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet() : PtrListHead(0), PtrListTail(0), Forward(0), RefCount(0),
1569971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner               AccessTy(NoModRef), AliasTy(MustAlias) {
1579971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
15831a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  HashNodePair *getSomePointer() const {
15931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    return PtrListHead ? PtrListHead : 0;
1609971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
1619971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1629971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getForwardedTarget - Return the real alias set this represents.  If this
1639971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// has been merged with another set and is forwarding, return the ultimate
1649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// destination set.  This also implements the union-find collapsing as well.
1659971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *getForwardedTarget(AliasSetTracker &AST) {
1669971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    if (!Forward) return this;
1679971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1689971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *Dest = Forward->getForwardedTarget(AST);
1699971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    if (Dest != Forward) {
1709971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      Dest->RefCount++;
1719971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      if (--Forward->RefCount == 0)
1729971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        Forward->removeFromTracker(AST);
1739971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      Forward = Dest;
1749971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1759971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    return Dest;
1769971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
1779971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1789971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void removeFromTracker(AliasSetTracker &AST);
1799971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
18031a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  void addPointer(AliasSetTracker &AST, HashNodePair &Entry, unsigned Size);
1819971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void addCallSite(CallSite CS);
1829971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1839971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// aliasesPointer - Return true if the specified pointer "may" (or must)
1849971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// alias one of the members in the set.
1859971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  ///
18631a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  bool aliasesPointer(const Value *Ptr, unsigned Size, AliasAnalysis &AA) const;
1879971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
188009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner};
189009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
1909971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerinline std::ostream& operator<<(std::ostream &OS, const AliasSet &AS) {
1919971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AS.print(OS);
1929971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  return OS;
1939971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner}
1949971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
195009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
196009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSetTracker {
197009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  AliasAnalysis &AA;
1989971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  ilist<AliasSet> AliasSets;
1999971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2009971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Map from pointers to their node
2019971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  hash_map<Value*, AliasSet::PointerRec> PointerMap;
202009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerpublic:
203009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
204009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// the specified alias analysis object to disambiguate load and store
205009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// addresses.
206009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
207009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
208009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// add methods - These methods are used to add different types of
209009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// instructions to the alias sets.  Adding a new instruction can result in
210009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// one of three actions happening:
211009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
212009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   1. If the instruction doesn't alias any other sets, create a new set.
213009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   2. If the instruction aliases exactly one set, add it to the set
214009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   3. If the instruction aliases multiple sets, merge the sets, and add
215009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///      the instruction to the result.
216009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
217009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  void add(LoadInst *LI);
218009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  void add(StoreInst *SI);
2199971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void add(CallSite CS);       // Call/Invoke instructions
2209971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void add(CallInst *CI) { add(CallSite(CI)); }
2219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void add(InvokeInst *II) { add(CallSite(II)); }
2229971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void add(Instruction *I);  // Dispatch to one of the other add methods...
223009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
224009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// getAliasSets - Return the alias sets that are active.
2259971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
2269971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2279971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getAliasSetForPointer - Return the alias set that the specified pointer
2289971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// lives in...
22931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  AliasSet &getAliasSetForPointer(Value *P, unsigned Size);
2309971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2319971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getAliasAnalysis - Return the underlying alias analysis object used by
2329971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// this tracker.
2339971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasAnalysis &getAliasAnalysis() const { return AA; }
2349971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef ilist<AliasSet>::iterator iterator;
2369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef ilist<AliasSet>::const_iterator const_iterator;
2379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2389971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const_iterator begin() const { return AliasSets.begin(); }
2399971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const_iterator end()   const { return AliasSets.end(); }
2409971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2419971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator begin() { return AliasSets.begin(); }
2429971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator end()   { return AliasSets.end(); }
2439971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2449971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void print(std::ostream &OS) const;
2459971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void dump() const;
246009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
247009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerprivate:
2489971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  friend class AliasSet;
2499971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void removeAliasSet(AliasSet *AS);
2509971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2519971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet::HashNodePair &getEntryFor(Value *V) {
2529971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    // Standard operator[], except that it returns the whole pair, not just
2539971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    // ->second.
2549971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    return *PointerMap.insert(AliasSet::HashNodePair(V,
2559971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner                                            AliasSet::PointerRec())).first;
2569971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
2579971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
25831a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  void addPointer(Value *P, unsigned Size, AliasSet::AccessType E) {
25931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    AliasSet &AS = getAliasSetForPointer(P, Size);
2609971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AS.AccessTy |= E;
2619971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
26231a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  AliasSet *findAliasSetForPointer(const Value *Ptr, unsigned Size);
2639971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *findAliasSetForCallSite(CallSite CS);
265009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner};
266009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
2679971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerinline std::ostream& operator<<(std::ostream &OS, const AliasSetTracker &AST) {
2689971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AST.print(OS);
2699971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  return OS;
2709971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner}
2719971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
272009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner#endif
273