AliasSetTracker.h revision 2cffeec014537a5f4d2313a5c21c3aa6fcf33288
1009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
26fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//
36fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//                     The LLVM Compiler Infrastructure
46fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//
56fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell// This file was developed by the LLVM research group and is distributed under
66fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details.
76fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//
86fbcc26f1460eaee4e0eb8b426fc1ff0c7af11beJohn Criswell//===----------------------------------------------------------------------===//
9009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//
10009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner// This file defines two classes: AliasSetTracker and AliasSet.  These interface
11009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner// are used to classify a collection of pointer references into a maximal number
12009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner// of disjoint sets.  Each AliasSet object constructed by the AliasSetTracker
13009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner// object refers to memory disjoint from the other sets.
14009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//
15009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//===----------------------------------------------------------------------===//
16009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
17009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
18009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner#define LLVM_ANALYSIS_ALIASSETTRACKER_H
19009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
209971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner#include "llvm/Support/CallSite.h"
219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner#include "Support/iterator"
229971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner#include "Support/hash_map"
239971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner#include "Support/ilist"
24d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
27009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasAnalysis;
28009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass LoadInst;
29009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass StoreInst;
30009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSetTracker;
319971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerclass AliasSet;
32009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
33009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSet {
34009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  friend class AliasSetTracker;
359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  struct PointerRec;
379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef std::pair<Value* const, PointerRec> HashNodePair;
389971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
399971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  class PointerRec {
402cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    HashNodePair **PrevInList, *NextInList;
419971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *AS;
4231a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    unsigned Size;
439971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  public:
442cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    PointerRec() : PrevInList(0), NextInList(0), AS(0), Size(0) {}
459971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
469971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    HashNodePair *getNext() const { return NextInList; }
479971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool hasAliasSet() const { return AS != 0; }
489971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
492cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    HashNodePair** setPrevInList(HashNodePair **PIL) {
502cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner      PrevInList = PIL;
512cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner      return &NextInList;
522cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    }
532cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner
5431a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    void updateSize(unsigned NewSize) {
5531a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner      if (NewSize > Size) Size = NewSize;
5631a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    }
5731a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner
5831a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    unsigned getSize() const { return Size; }
5931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner
609971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *getAliasSet(AliasSetTracker &AST) {
619971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(AS && "No AliasSet yet!");
629971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      if (AS->Forward) {
639971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        AliasSet *OldAS = AS;
649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        AS = OldAS->getForwardedTarget(AST);
659971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        if (--OldAS->RefCount == 0)
669971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner          OldAS->removeFromTracker(AST);
679971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        AS->RefCount++;
689971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      }
699971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return AS;
709971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
719971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
729971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    void setAliasSet(AliasSet *as) {
739971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(AS == 0 && "Already have an alias set!");
749971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      AS = as;
759971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
762cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner
772cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    void removeFromList() {
782cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner      if (NextInList) NextInList->second.PrevInList = PrevInList;
792cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner      *PrevInList = NextInList;
809971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
819971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  };
829971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
832cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  HashNodePair *PtrList, **PtrListEnd;  // Doubly linked list of nodes
849971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *Forward;             // Forwarding pointer
859971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *Next, *Prev;         // Doubly linked list of AliasSets
869971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
879971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  std::vector<CallSite> CallSites; // All calls & invokes in this node
889971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
899971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // RefCount - Number of nodes pointing to this AliasSet plus the number of
909971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // AliasSets forwarding to it.
91bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  unsigned RefCount : 28;
929971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
93009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AccessType - Keep track of whether this alias set merely refers to the
94009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// locations of memory, whether it modifies the memory, or whether it does
959971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// both.  The lattice goes from "NoModRef" to either Refs or Mods, then to
965560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman  /// ModRef as necessary.
97009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
98009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  enum AccessType {
999971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    NoModRef = 0, Refs = 1,         // Ref = bit 1
1009971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    Mods     = 2, ModRef = 3        // Mod = bit 2
101009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  };
1029971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  unsigned AccessTy : 2;
103009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
104009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AliasType - Keep track the relationships between the pointers in the set.
105009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// Lattice goes from MustAlias to MayAlias.
106009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
107009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  enum AliasType {
1089971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    MustAlias = 0, MayAlias = 1
109009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  };
1109971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  unsigned AliasTy : 1;
111009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
112bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  // Volatile - True if this alias set contains volatile loads or stores.
113bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  bool Volatile : 1;
114bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner
115b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  friend class ilist_traits<AliasSet>;
116b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  AliasSet *getPrev() const { return Prev; }
117b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  AliasSet *getNext() const { return Next; }
118b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void setPrev(AliasSet *P) { Prev = P; }
119b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void setNext(AliasSet *N) { Next = N; }
120b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
121b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattnerpublic:
122b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// Accessors...
123b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isRef() const { return AccessTy & Refs; }
124b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMod() const { return AccessTy & Mods; }
125b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMustAlias() const { return AliasTy == MustAlias; }
126b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMayAlias()  const { return AliasTy == MayAlias; }
127b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
128bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  // isVolatile - Return true if this alias set contains volatile loads or
129bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  // stores.
130bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  bool isVolatile() const { return Volatile; }
131bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner
132bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner
133b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// isForwardingAliasSet - Return true if this alias set should be ignored as
134b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// part of the AliasSetTracker object.
135b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isForwardingAliasSet() const { return Forward; }
136b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
137b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// mergeSetIn - Merge the specified alias set into this alias set...
138b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  ///
139b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void mergeSetIn(AliasSet &AS);
140b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
141b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  // Alias Set iteration - Allow access to all of the pointer which are part of
142b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  // this alias set...
143b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  class iterator;
1442cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  iterator begin() const { return iterator(PtrList); }
145b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  iterator end()   const { return iterator(); }
146b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
147b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void print(std::ostream &OS) const;
148b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void dump() const;
149b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
1509971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// Define an iterator for alias sets... this is just a forward iterator.
15131a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  class iterator : public forward_iterator<HashNodePair, ptrdiff_t> {
1529971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    HashNodePair *CurNode;
1539971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  public:
1549971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator(HashNodePair *CN = 0) : CurNode(CN) {}
1559971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1569971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool operator==(const iterator& x) const {
1579971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return CurNode == x.CurNode;
1589971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1599971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool operator!=(const iterator& x) const { return !operator==(x); }
160009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
1619971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    const iterator &operator=(const iterator &I) {
1629971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      CurNode = I.CurNode;
1639971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return *this;
1649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1659971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
16631a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    value_type &operator*() const {
1679971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(CurNode && "Dereferencing AliasSet.end()!");
16831a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner      return *CurNode;
1699971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
17031a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    value_type *operator->() const { return &operator*(); }
1719971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1729971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator& operator++() {                // Preincrement
1739971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(CurNode && "Advancing past AliasSet.end()!");
1749971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      CurNode = CurNode->second.getNext();
1759971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return *this;
1769971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1779971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator operator++(int) { // Postincrement
1789971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      iterator tmp = *this; ++*this; return tmp;
1799971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1809971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  };
1819971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
182009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerprivate:
1839971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Can only be created by AliasSetTracker
1842cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
185bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner               AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
1869971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
1872cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  AliasSet(const AliasSet &AS) {
1882cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    // AliasSet's only get copy constructed in simple circumstances.  In
1892cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    // particular, they cannot have any pointers in their list.  Despite this,
1902cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    // we have to be sure to update the PtrListEnd to not point to the source
1912cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    // AliasSet's list.
1922cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    assert(AS.PtrList == 0 && "AliasSet has pointers in it!");
1932cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    PtrList = 0; PtrListEnd = &PtrList;
1942cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    Forward = AS.Forward; RefCount = AS.RefCount;
1952cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    AccessTy = AS.AccessTy; AliasTy = AS.AliasTy; Volatile = AS.Volatile;
1962cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  }
1972cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner
19831a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  HashNodePair *getSomePointer() const {
1992cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    return PtrList;
2009971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
2019971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2029971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getForwardedTarget - Return the real alias set this represents.  If this
2039971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// has been merged with another set and is forwarding, return the ultimate
2049971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// destination set.  This also implements the union-find collapsing as well.
2059971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *getForwardedTarget(AliasSetTracker &AST) {
2069971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    if (!Forward) return this;
2079971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2089971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *Dest = Forward->getForwardedTarget(AST);
2099971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    if (Dest != Forward) {
2109971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      Dest->RefCount++;
2119971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      if (--Forward->RefCount == 0)
2129971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        Forward->removeFromTracker(AST);
2139971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      Forward = Dest;
2149971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
2159971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    return Dest;
2169971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
2179971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2189971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void removeFromTracker(AliasSetTracker &AST);
2199971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
22031a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  void addPointer(AliasSetTracker &AST, HashNodePair &Entry, unsigned Size);
2219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void addCallSite(CallSite CS);
222bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  void setVolatile() { Volatile = true; }
2239971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2249971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// aliasesPointer - Return true if the specified pointer "may" (or must)
2259971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// alias one of the members in the set.
2269971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  ///
22731a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  bool aliasesPointer(const Value *Ptr, unsigned Size, AliasAnalysis &AA) const;
2289971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
229009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner};
230009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
2319971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerinline std::ostream& operator<<(std::ostream &OS, const AliasSet &AS) {
2329971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AS.print(OS);
2339971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  return OS;
2349971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner}
2359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
236009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
237009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSetTracker {
238009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  AliasAnalysis &AA;
2399971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  ilist<AliasSet> AliasSets;
2409971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2419971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Map from pointers to their node
2429971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  hash_map<Value*, AliasSet::PointerRec> PointerMap;
243009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerpublic:
244009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
245009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// the specified alias analysis object to disambiguate load and store
246009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// addresses.
247009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
248009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
249009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// add methods - These methods are used to add different types of
250009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// instructions to the alias sets.  Adding a new instruction can result in
251009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// one of three actions happening:
252009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
253009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   1. If the instruction doesn't alias any other sets, create a new set.
254009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   2. If the instruction aliases exactly one set, add it to the set
255009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   3. If the instruction aliases multiple sets, merge the sets, and add
256009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///      the instruction to the result.
257009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
258009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  void add(LoadInst *LI);
259009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  void add(StoreInst *SI);
260b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(CallSite CS);          // Call/Invoke instructions
261b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(CallInst *CI)   { add(CallSite(CI)); }
2629971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void add(InvokeInst *II) { add(CallSite(II)); }
263b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(Instruction *I);       // Dispatch to one of the other add methods...
264b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(BasicBlock &BB);       // Add all instructions in basic block
265b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(const AliasSetTracker &AST); // Add alias relations from another AST
266009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
2672cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  /// remove method - This method is used to remove a pointer value from the
2682cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  /// AliasSetTracker entirely.  It should be used when an instruction is
2692cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  /// deleted from the program to update the AST.  If you don't use this, you
2702cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  /// would have dangling pointers to deleted instructions.
2712cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  ///
2722cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  void remove(Value *PtrVal);
2732cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner
274009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// getAliasSets - Return the alias sets that are active.
2759971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
2769971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2779971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getAliasSetForPointer - Return the alias set that the specified pointer
2789971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// lives in...
27931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  AliasSet &getAliasSetForPointer(Value *P, unsigned Size);
2809971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2819971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getAliasAnalysis - Return the underlying alias analysis object used by
2829971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// this tracker.
2839971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasAnalysis &getAliasAnalysis() const { return AA; }
2849971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2859971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef ilist<AliasSet>::iterator iterator;
2869971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef ilist<AliasSet>::const_iterator const_iterator;
2879971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2889971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const_iterator begin() const { return AliasSets.begin(); }
2899971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const_iterator end()   const { return AliasSets.end(); }
2909971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2919971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator begin() { return AliasSets.begin(); }
2929971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator end()   { return AliasSets.end(); }
2939971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2949971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void print(std::ostream &OS) const;
2959971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void dump() const;
296009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
297009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerprivate:
2989971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  friend class AliasSet;
2999971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void removeAliasSet(AliasSet *AS);
3009971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3019971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet::HashNodePair &getEntryFor(Value *V) {
3029971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    // Standard operator[], except that it returns the whole pair, not just
3039971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    // ->second.
3049971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    return *PointerMap.insert(AliasSet::HashNodePair(V,
3059971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner                                            AliasSet::PointerRec())).first;
3069971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
3079971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
308bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  AliasSet &addPointer(Value *P, unsigned Size, AliasSet::AccessType E) {
30931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    AliasSet &AS = getAliasSetForPointer(P, Size);
3109971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AS.AccessTy |= E;
311bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner    return AS;
3129971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
31331a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  AliasSet *findAliasSetForPointer(const Value *Ptr, unsigned Size);
3149971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3159971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *findAliasSetForCallSite(CallSite CS);
316009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner};
317009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
3189971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerinline std::ostream& operator<<(std::ostream &OS, const AliasSetTracker &AST) {
3199971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AST.print(OS);
3209971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  return OS;
3219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner}
3229971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
323d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
324d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
325009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner#endif
326