AliasSetTracker.h revision 558cb5f4a131be8de67dd66d06f5c053cbf7403e
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;
305c88260f70d5286adeca61c31bdf51f8debaccbcChris Lattnerclass FreeInst;
31009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSetTracker;
329971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerclass AliasSet;
33009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
34009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSet {
35009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  friend class AliasSetTracker;
369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  struct 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
619971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    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;
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
121b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner  void addRef() { ++RefCount; }
122b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner  void dropRef(AliasSetTracker &AST) {
123b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner    assert(RefCount >= 1 && "Invalid reference count detected!");
124b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner    if (--RefCount == 0)
125b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner      removeFromTracker(AST);
126b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner  }
127b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner
128b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattnerpublic:
129b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// Accessors...
130b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isRef() const { return AccessTy & Refs; }
131b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMod() const { return AccessTy & Mods; }
132b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMustAlias() const { return AliasTy == MustAlias; }
133b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isMayAlias()  const { return AliasTy == MayAlias; }
134b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
135bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  // isVolatile - Return true if this alias set contains volatile loads or
136bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  // stores.
137bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  bool isVolatile() const { return Volatile; }
138bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner
139b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// isForwardingAliasSet - Return true if this alias set should be ignored as
140b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// part of the AliasSetTracker object.
141b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  bool isForwardingAliasSet() const { return Forward; }
142b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
143b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  /// mergeSetIn - Merge the specified alias set into this alias set...
144b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  ///
145b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void mergeSetIn(AliasSet &AS);
146b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
147b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  // Alias Set iteration - Allow access to all of the pointer which are part of
148b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  // this alias set...
149b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  class iterator;
1502cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  iterator begin() const { return iterator(PtrList); }
151b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  iterator end()   const { return iterator(); }
152877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool empty() const { return PtrList == 0; }
153b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
154b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void print(std::ostream &OS) const;
155b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void dump() const;
156b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner
1579971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// Define an iterator for alias sets... this is just a forward iterator.
15831a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  class iterator : public forward_iterator<HashNodePair, ptrdiff_t> {
1599971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    HashNodePair *CurNode;
1609971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  public:
1619971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator(HashNodePair *CN = 0) : CurNode(CN) {}
1629971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1639971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool operator==(const iterator& x) const {
1649971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return CurNode == x.CurNode;
1659971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1669971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    bool operator!=(const iterator& x) const { return !operator==(x); }
167009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
1689971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    const iterator &operator=(const iterator &I) {
1699971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      CurNode = I.CurNode;
1709971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return *this;
1719971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1729971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
17331a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    value_type &operator*() const {
1749971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(CurNode && "Dereferencing AliasSet.end()!");
17531a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner      return *CurNode;
1769971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
17731a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner    value_type *operator->() const { return &operator*(); }
178877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner
179877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner    Value *getPointer() const { return CurNode->first; }
180877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner    unsigned getSize() const { return CurNode->second.getSize(); }
1819971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
1829971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator& operator++() {                // Preincrement
1839971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      assert(CurNode && "Advancing past AliasSet.end()!");
1849971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      CurNode = CurNode->second.getNext();
1859971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      return *this;
1869971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1879971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    iterator operator++(int) { // Postincrement
1889971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      iterator tmp = *this; ++*this; return tmp;
1899971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
1909971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  };
1919971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
192009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerprivate:
1939971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Can only be created by AliasSetTracker
1942cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
195bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner               AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
1969971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
197b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner
1982cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  AliasSet(const AliasSet &AS) {
199b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner    assert(0 && "Copy ctor called!?!?!");
200b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner    abort();
2012cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  }
2022cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner
20331a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  HashNodePair *getSomePointer() const {
2042cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner    return PtrList;
2059971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
2069971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2079971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getForwardedTarget - Return the real alias set this represents.  If this
2089971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// has been merged with another set and is forwarding, return the ultimate
2099971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// destination set.  This also implements the union-find collapsing as well.
2109971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *getForwardedTarget(AliasSetTracker &AST) {
2119971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    if (!Forward) return this;
2129971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2139971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AliasSet *Dest = Forward->getForwardedTarget(AST);
2149971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    if (Dest != Forward) {
215b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner      Dest->addRef();
216b8a31ace2c49af703cf7b1f1bda408a361f53447Chris Lattner      Forward->dropRef(AST);
2179971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner      Forward = Dest;
2189971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    }
2199971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    return Dest;
2209971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
2219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2229971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void removeFromTracker(AliasSetTracker &AST);
2239971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
22431a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  void addPointer(AliasSetTracker &AST, HashNodePair &Entry, unsigned Size);
225c87f0bb345642b7c278b42fa93fb3dc3c8849688Chris Lattner  void addCallSite(CallSite CS, AliasAnalysis &AA);
226bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner  void setVolatile() { Volatile = true; }
2279971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2289971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// aliasesPointer - Return true if the specified pointer "may" (or must)
2299971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// alias one of the members in the set.
2309971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  ///
23131a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  bool aliasesPointer(const Value *Ptr, unsigned Size, AliasAnalysis &AA) const;
2329971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
233009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner};
234009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
2359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerinline std::ostream& operator<<(std::ostream &OS, const AliasSet &AS) {
2369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AS.print(OS);
2379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  return OS;
2389971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner}
2399971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
240009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
241009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerclass AliasSetTracker {
242009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  AliasAnalysis &AA;
2439971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  ilist<AliasSet> AliasSets;
2449971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
2459971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  // Map from pointers to their node
2469971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  hash_map<Value*, AliasSet::PointerRec> PointerMap;
247009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerpublic:
248009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
249009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// the specified alias analysis object to disambiguate load and store
250009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// addresses.
251009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
252009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
253009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// add methods - These methods are used to add different types of
254009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// instructions to the alias sets.  Adding a new instruction can result in
255009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// one of three actions happening:
256009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
257009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   1. If the instruction doesn't alias any other sets, create a new set.
258009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   2. If the instruction aliases exactly one set, add it to the set
259009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///   3. If the instruction aliases multiple sets, merge the sets, and add
260009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///      the instruction to the result.
261009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  ///
26212c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// These methods return true if inserting the instruction resulted in the
26312c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// addition of a new alias set (i.e., the pointer did not alias anything).
26412c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  ///
265558cb5f4a131be8de67dd66d06f5c053cbf7403eChris Lattner  bool add(Value *Ptr, unsigned Size);  // Add a location
26612c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(LoadInst *LI);
26712c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(StoreInst *SI);
2685c88260f70d5286adeca61c31bdf51f8debaccbcChris Lattner  bool add(FreeInst *FI);
26912c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(CallSite CS);          // Call/Invoke instructions
27012c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(CallInst *CI)   { return add(CallSite(CI)); }
27112c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(InvokeInst *II) { return add(CallSite(II)); }
27212c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  bool add(Instruction *I);       // Dispatch to one of the other add methods...
273b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(BasicBlock &BB);       // Add all instructions in basic block
274b75f9dda9e436b346c684c3694fbef6b14a00795Chris Lattner  void add(const AliasSetTracker &AST); // Add alias relations from another AST
275009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
276877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// remove methods - These methods are used to remove all entries that might
277877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// be aliased by the specified instruction.  These methods return true if any
278877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// alias sets were eliminated.
279558cb5f4a131be8de67dd66d06f5c053cbf7403eChris Lattner  bool remove(Value *Ptr, unsigned Size);  // Remove a location
280877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(LoadInst *LI);
281877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(StoreInst *SI);
2825c88260f70d5286adeca61c31bdf51f8debaccbcChris Lattner  bool remove(FreeInst *FI);
283877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(CallSite CS);
284877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(CallInst *CI)   { return remove(CallSite(CI)); }
285877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(InvokeInst *II) { return remove(CallSite(II)); }
286877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  bool remove(Instruction *I);
287877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  void remove(AliasSet &AS);
288877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner
289877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner
290c43e0ae35094266028c3900116a4dfbee5769388Chris Lattner  /// deleteValue method - This method is used to remove a pointer value from
291c43e0ae35094266028c3900116a4dfbee5769388Chris Lattner  /// the AliasSetTracker entirely.  It should be used when an instruction is
2922cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  /// deleted from the program to update the AST.  If you don't use this, you
2932cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  /// would have dangling pointers to deleted instructions.
2942cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner  ///
295c43e0ae35094266028c3900116a4dfbee5769388Chris Lattner  void deleteValue(Value *PtrVal);
2962cffeec014537a5f4d2313a5c21c3aa6fcf33288Chris Lattner
297009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner  /// getAliasSets - Return the alias sets that are active.
2989971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
2999971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3009971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getAliasSetForPointer - Return the alias set that the specified pointer
30112c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// lives in.  If the New argument is non-null, this method sets the value to
30212c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// true if a new alias set is created to contain the pointer (because the
30312c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  /// pointer didn't alias anything).
30412c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  AliasSet &getAliasSetForPointer(Value *P, unsigned Size, bool *New = 0);
3059971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
306877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// getAliasSetForPointerIfExists - Return the alias set containing the
307877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  /// location specified if one exists, otherwise return null.
308877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  AliasSet *getAliasSetForPointerIfExists(Value *P, unsigned Size) {
309877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner    return findAliasSetForPointer(P, Size);
310877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner  }
311877ad7d80b3eac84f9f61294bc1b78817bbca530Chris Lattner
3129971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// getAliasAnalysis - Return the underlying alias analysis object used by
3139971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  /// this tracker.
3149971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasAnalysis &getAliasAnalysis() const { return AA; }
3159971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3169971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef ilist<AliasSet>::iterator iterator;
3179971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  typedef ilist<AliasSet>::const_iterator const_iterator;
3189971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3199971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const_iterator begin() const { return AliasSets.begin(); }
3209971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  const_iterator end()   const { return AliasSets.end(); }
3219971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3229971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator begin() { return AliasSets.begin(); }
3239971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  iterator end()   { return AliasSets.end(); }
3249971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3259971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void print(std::ostream &OS) const;
3269971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void dump() const;
327009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
328009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattnerprivate:
3299971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  friend class AliasSet;
3309971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  void removeAliasSet(AliasSet *AS);
3319971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3329971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet::HashNodePair &getEntryFor(Value *V) {
3339971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    // Standard operator[], except that it returns the whole pair, not just
3349971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    // ->second.
3359971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    return *PointerMap.insert(AliasSet::HashNodePair(V,
3369971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner                                            AliasSet::PointerRec())).first;
3379971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
3389971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
33912c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner  AliasSet &addPointer(Value *P, unsigned Size, AliasSet::AccessType E,
34012c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner                       bool &NewSet) {
34112c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner    NewSet = false;
34212c1155403fd2dbd3a24e3748e7d80bbaa27c7f6Chris Lattner    AliasSet &AS = getAliasSetForPointer(P, Size, &NewSet);
3439971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner    AS.AccessTy |= E;
344bb8f4769a2ee48b82c30de52083942781e920dd9Chris Lattner    return AS;
3459971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  }
34631a9d185bfa253af2f0fece59d8b1227dad64b15Chris Lattner  AliasSet *findAliasSetForPointer(const Value *Ptr, unsigned Size);
3479971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
3489971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AliasSet *findAliasSetForCallSite(CallSite CS);
349009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner};
350009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner
3519971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattnerinline std::ostream& operator<<(std::ostream &OS, const AliasSetTracker &AST) {
3529971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  AST.print(OS);
3539971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner  return OS;
3549971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner}
3559971ac4a36c54488bcdf55d7e493ac0cd6dc168aChris Lattner
356d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke} // End llvm namespace
357d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
358009cc3d2e85674f01f70d915e0c802d89d0b672fChris Lattner#endif
359