AliasSetTracker.h revision 9769ab22265b313171d201b5928688524a01bd87
1009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
29769ab22265b313171d201b5928688524a01bd87Misha Brukman//
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.
79769ab22265b313171d201b5928688524a01bd87Misha Brukman//
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.
149769ab22265b313171d201b5928688524a01bd87Misha Brukman//
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"
21551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/iterator"
22551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/hash_map"
23551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/ilist"
24d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
27009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasAnalysis;
28009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass LoadInst;
29009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass StoreInst;
305c88260f70d5286adeca61c31bdf51f8debaccbcChris Lattnerclass FreeInst;
31009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSetTracker;
329971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerclass AliasSet;
33009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
34009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSet {
35009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  friend class AliasSetTracker;
369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
371fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner  class PointerRec;
389971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef std::pair<Value* const, PointerRec> HashNodePair;
399971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
409971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  class PointerRec {
412cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    HashNodePair **PrevInList, *NextInList;
429971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *AS;
4331a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    unsigned Size;
449971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  public:
452cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    PointerRec() : PrevInList(0), NextInList(0), AS(0), Size(0) {}
469971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
479971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    HashNodePair *getNext() const { return NextInList; }
489971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool hasAliasSet() const { return AS != 0; }
499971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
502cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    HashNodePair** setPrevInList(HashNodePair **PIL) {
512cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner      PrevInList = PIL;
522cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner      return &NextInList;
532cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    }
542cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner
5531a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    void updateSize(unsigned NewSize) {
5631a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner      if (NewSize > Size) Size = NewSize;
5731a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    }
5831a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner
5931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    unsigned getSize() const { return Size; }
6031a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner
619769ab22265b313171d201b5928688524a01bd87Misha Brukman    AliasSet *getAliasSet(AliasSetTracker &AST) {
629971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(AS && "No AliasSet yet!");
639971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      if (AS->Forward) {
649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        AliasSet *OldAS = AS;
659971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner        AS = OldAS->getForwardedTarget(AST);
66b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner        AS->addRef();
67b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner        OldAS->dropRef(AST);
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;
807e0e9c635f5439426252bd1ccbfa90b878ba0ca6Chris Lattner      if (AS->PtrListEnd == &NextInList) {
817e0e9c635f5439426252bd1ccbfa90b878ba0ca6Chris Lattner        AS->PtrListEnd = PrevInList;
827e0e9c635f5439426252bd1ccbfa90b878ba0ca6Chris Lattner        assert(*AS->PtrListEnd == 0 && "List not terminated right!");
837e0e9c635f5439426252bd1ccbfa90b878ba0ca6Chris Lattner      }
849971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
859971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  };
869971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
872cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  HashNodePair *PtrList, **PtrListEnd;  // Doubly linked list of nodes
889971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *Forward;             // Forwarding pointer
899971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *Next, *Prev;         // Doubly linked list of AliasSets
909971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
919971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  std::vector<CallSite> CallSites; // All calls & invokes in this node
929971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
939971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // RefCount - Number of nodes pointing to this AliasSet plus the number of
949971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // AliasSets forwarding to it.
95bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  unsigned RefCount : 28;
969971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
97009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AccessType - Keep track of whether this alias set merely refers to the
98009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// locations of memory, whether it modifies the memory, or whether it does
999971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// both.  The lattice goes from "NoModRef" to either Refs or Mods, then to
1005560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman  /// ModRef as necessary.
101009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
102009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  enum AccessType {
1039971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    NoModRef = 0, Refs = 1,         // Ref = bit 1
1049971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    Mods     = 2, ModRef = 3        // Mod = bit 2
105009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  };
1069971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  unsigned AccessTy : 2;
107009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
108009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AliasType - Keep track the relationships between the pointers in the set.
109009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// Lattice goes from MustAlias to MayAlias.
110009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
111009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  enum AliasType {
1129971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    MustAlias = 0, MayAlias = 1
113009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  };
1149971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  unsigned AliasTy : 1;
115009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
116bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  // Volatile - True if this alias set contains volatile loads or stores.
117bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  bool Volatile : 1;
118bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner
1191fca5ff62bb2ecb5bfc8974f4dbfc56e9d3ca721Chris Lattner  friend struct ilist_traits<AliasSet>;
120b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  AliasSet *getPrev() const { return Prev; }
121b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  AliasSet *getNext() const { return Next; }
122b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void setPrev(AliasSet *P) { Prev = P; }
123b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void setNext(AliasSet *N) { Next = N; }
124b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
125b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner  void addRef() { ++RefCount; }
126b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner  void dropRef(AliasSetTracker &AST) {
127b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner    assert(RefCount >= 1 && "Invalid reference count detected!");
128b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner    if (--RefCount == 0)
129b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner      removeFromTracker(AST);
130b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner  }
131b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner
132b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattnerpublic:
133b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// Accessors...
134b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isRef() const { return AccessTy & Refs; }
135b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMod() const { return AccessTy & Mods; }
136b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMustAlias() const { return AliasTy == MustAlias; }
137b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMayAlias()  const { return AliasTy == MayAlias; }
138b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
139bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  // isVolatile - Return true if this alias set contains volatile loads or
140bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  // stores.
141bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  bool isVolatile() const { return Volatile; }
142bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner
143b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// isForwardingAliasSet - Return true if this alias set should be ignored as
144b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// part of the AliasSetTracker object.
145b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isForwardingAliasSet() const { return Forward; }
146b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
147b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// mergeSetIn - Merge the specified alias set into this alias set...
148b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  ///
149276636c93b35786d5719e2eda335c79d38d92632Chris Lattner  void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);
150b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
151b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  // Alias Set iteration - Allow access to all of the pointer which are part of
152b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  // this alias set...
153b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  class iterator;
1542cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  iterator begin() const { return iterator(PtrList); }
155b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  iterator end()   const { return iterator(); }
156877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool empty() const { return PtrList == 0; }
157b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
158b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void print(std::ostream &OS) const;
159b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void dump() const;
160b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
1619971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// Define an iterator for alias sets... this is just a forward iterator.
16231a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  class iterator : public forward_iterator<HashNodePair, ptrdiff_t> {
1639971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    HashNodePair *CurNode;
1649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  public:
1659971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator(HashNodePair *CN = 0) : CurNode(CN) {}
1669769ab22265b313171d201b5928688524a01bd87Misha Brukman
1679971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool operator==(const iterator& x) const {
1689971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return CurNode == x.CurNode;
1699971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1709971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool operator!=(const iterator& x) const { return !operator==(x); }
171009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
1729971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    const iterator &operator=(const iterator &I) {
1739971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      CurNode = I.CurNode;
1749971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return *this;
1759971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1769769ab22265b313171d201b5928688524a01bd87Misha Brukman
17731a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    value_type &operator*() const {
1789971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(CurNode && "Dereferencing AliasSet.end()!");
17931a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner      return *CurNode;
1809971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
18131a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    value_type *operator->() const { return &operator*(); }
182877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner
183877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner    Value *getPointer() const { return CurNode->first; }
184877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner    unsigned getSize() const { return CurNode->second.getSize(); }
1859769ab22265b313171d201b5928688524a01bd87Misha Brukman
1869971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator& operator++() {                // Preincrement
1879971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(CurNode && "Advancing past AliasSet.end()!");
1889971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      CurNode = CurNode->second.getNext();
1899971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return *this;
1909971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1919971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator operator++(int) { // Postincrement
1929769ab22265b313171d201b5928688524a01bd87Misha Brukman      iterator tmp = *this; ++*this; return tmp;
1939971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1949971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  };
1959971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
196009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerprivate:
1979971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Can only be created by AliasSetTracker
1982cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
199bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner               AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
2009971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
201b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner
2022cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  AliasSet(const AliasSet &AS) {
203b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner    assert(0 && "Copy ctor called!?!?!");
204b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner    abort();
2052cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  }
2062cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner
20731a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  HashNodePair *getSomePointer() const {
2082cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    return PtrList;
2099971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
2109971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2119971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getForwardedTarget - Return the real alias set this represents.  If this
2129971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// has been merged with another set and is forwarding, return the ultimate
2139971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// destination set.  This also implements the union-find collapsing as well.
2149971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *getForwardedTarget(AliasSetTracker &AST) {
2159971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    if (!Forward) return this;
2169971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2179971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *Dest = Forward->getForwardedTarget(AST);
2189971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    if (Dest != Forward) {
219b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner      Dest->addRef();
220b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner      Forward->dropRef(AST);
2219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      Forward = Dest;
2229971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
2239971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    return Dest;
2249971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
2259971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2269971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void removeFromTracker(AliasSetTracker &AST);
2279971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
228e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  void addPointer(AliasSetTracker &AST, HashNodePair &Entry, unsigned Size,
229e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner                  bool KnownMustAlias = false);
230c87f0bb345642b7c278b42fa93fb3dc3c8849688Chris Lattner  void addCallSite(CallSite CS, AliasAnalysis &AA);
231bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  void setVolatile() { Volatile = true; }
2329971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2339971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// aliasesPointer - Return true if the specified pointer "may" (or must)
2349971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// alias one of the members in the set.
2359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  ///
23631a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  bool aliasesPointer(const Value *Ptr, unsigned Size, AliasAnalysis &AA) const;
2379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
238009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner};
239009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
2409971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerinline std::ostream& operator<<(std::ostream &OS, const AliasSet &AS) {
2419971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AS.print(OS);
2429971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  return OS;
2439971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner}
2449971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
245009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
246009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSetTracker {
247009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  AliasAnalysis &AA;
2489971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  ilist<AliasSet> AliasSets;
2499971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2509971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Map from pointers to their node
2519971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  hash_map<Value*, AliasSet::PointerRec> PointerMap;
252009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerpublic:
253009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
254009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// the specified alias analysis object to disambiguate load and store
255009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// addresses.
256009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
257009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
258009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// add methods - These methods are used to add different types of
259009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// instructions to the alias sets.  Adding a new instruction can result in
260009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// one of three actions happening:
261009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
262009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   1. If the instruction doesn't alias any other sets, create a new set.
263009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   2. If the instruction aliases exactly one set, add it to the set
264009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   3. If the instruction aliases multiple sets, merge the sets, and add
265009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///      the instruction to the result.
266009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
26712c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// These methods return true if inserting the instruction resulted in the
26812c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// addition of a new alias set (i.e., the pointer did not alias anything).
26912c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  ///
270558cb5f4a131be8de67dd66d06f5c053cbf7403eChris Lattner  bool add(Value *Ptr, unsigned Size);  // Add a location
27112c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(LoadInst *LI);
27212c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(StoreInst *SI);
2735c88260f70d5286adeca61c31bdf51f8debaccbcChris Lattner  bool add(FreeInst *FI);
27412c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(CallSite CS);          // Call/Invoke instructions
27512c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(CallInst *CI)   { return add(CallSite(CI)); }
27612c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(InvokeInst *II) { return add(CallSite(II)); }
27712c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(Instruction *I);       // Dispatch to one of the other add methods...
278b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(BasicBlock &BB);       // Add all instructions in basic block
279b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(const AliasSetTracker &AST); // Add alias relations from another AST
280009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
281877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// remove methods - These methods are used to remove all entries that might
282877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// be aliased by the specified instruction.  These methods return true if any
283877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// alias sets were eliminated.
284558cb5f4a131be8de67dd66d06f5c053cbf7403eChris Lattner  bool remove(Value *Ptr, unsigned Size);  // Remove a location
285877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(LoadInst *LI);
286877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(StoreInst *SI);
2875c88260f70d5286adeca61c31bdf51f8debaccbcChris Lattner  bool remove(FreeInst *FI);
288877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(CallSite CS);
289877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(CallInst *CI)   { return remove(CallSite(CI)); }
290877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(InvokeInst *II) { return remove(CallSite(II)); }
291877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(Instruction *I);
292877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  void remove(AliasSet &AS);
293877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner
294009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// getAliasSets - Return the alias sets that are active.
295e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  ///
2969971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
2979971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2989971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getAliasSetForPointer - Return the alias set that the specified pointer
29912c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// lives in.  If the New argument is non-null, this method sets the value to
30012c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// true if a new alias set is created to contain the pointer (because the
30112c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// pointer didn't alias anything).
30212c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  AliasSet &getAliasSetForPointer(Value *P, unsigned Size, bool *New = 0);
3039971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
304877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// getAliasSetForPointerIfExists - Return the alias set containing the
305877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// location specified if one exists, otherwise return null.
306877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  AliasSet *getAliasSetForPointerIfExists(Value *P, unsigned Size) {
307877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner    return findAliasSetForPointer(P, Size);
308877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  }
3099769ab22265b313171d201b5928688524a01bd87Misha Brukman
31007bfa52405feb99155304c1a28b71e69d046589cChris Lattner  /// containsPointer - Return true if the specified location is represented by
31107bfa52405feb99155304c1a28b71e69d046589cChris Lattner  /// this alias set, false otherwise.  This does not modify the AST object or
31207bfa52405feb99155304c1a28b71e69d046589cChris Lattner  /// alias sets.
31307bfa52405feb99155304c1a28b71e69d046589cChris Lattner  bool containsPointer(Value *P, unsigned Size) const;
314877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner
3159971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getAliasAnalysis - Return the underlying alias analysis object used by
3169971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// this tracker.
3179971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasAnalysis &getAliasAnalysis() const { return AA; }
3189971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
319e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// deleteValue method - This method is used to remove a pointer value from
320e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// the AliasSetTracker entirely.  It should be used when an instruction is
321e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// deleted from the program to update the AST.  If you don't use this, you
322e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// would have dangling pointers to deleted instructions.
323e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  ///
324e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  void deleteValue(Value *PtrVal);
325e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner
326e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// copyValue - This method should be used whenever a preexisting value in the
327e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// program is copied or cloned, introducing a new value.  Note that it is ok
328e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// for clients that use this method to introduce the same value multiple
329e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// times: if the tracker already knows about a value, it will ignore the
330e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  /// request.
331e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  ///
332e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner  void copyValue(Value *From, Value *To);
333e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner
334e2fe784500ee910536bfc7332eae82ab0fdd1bc7Chris Lattner
3359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef ilist<AliasSet>::iterator iterator;
3369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef ilist<AliasSet>::const_iterator const_iterator;
3379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3389971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const_iterator begin() const { return AliasSets.begin(); }
3399971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const_iterator end()   const { return AliasSets.end(); }
3409971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3419971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator begin() { return AliasSets.begin(); }
3429971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator end()   { return AliasSets.end(); }
3439971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3449971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void print(std::ostream &OS) const;
3459971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void dump() const;
346009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
347009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerprivate:
3489971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  friend class AliasSet;
3499971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void removeAliasSet(AliasSet *AS);
3509971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3519971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet::HashNodePair &getEntryFor(Value *V) {
3529971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    // Standard operator[], except that it returns the whole pair, not just
3539971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    // ->second.
3549971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    return *PointerMap.insert(AliasSet::HashNodePair(V,
3559971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner                                            AliasSet::PointerRec())).first;
3569971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
3579971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
35812c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  AliasSet &addPointer(Value *P, unsigned Size, AliasSet::AccessType E,
35912c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner                       bool &NewSet) {
36012c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner    NewSet = false;
36112c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner    AliasSet &AS = getAliasSetForPointer(P, Size, &NewSet);
3629971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AS.AccessTy |= E;
363bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner    return AS;
3649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
36531a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  AliasSet *findAliasSetForPointer(const Value *Ptr, unsigned Size);
3669971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3679971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *findAliasSetForCallSite(CallSite CS);
368009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner};
369009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
3709971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerinline std::ostream& operator<<(std::ostream &OS, const AliasSetTracker &AST) {
3719971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AST.print(OS);
3729971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  return OS;
3739971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner}
3749971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
375d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
376d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
377009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner#endif
378