1f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
2f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
3f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//                     The LLVM Compiler Infrastructure
4f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
5f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file is distributed under the University of Illinois Open Source
6f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// License. See LICENSE.TXT for details.
7f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
8f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
9f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
10f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// This file defines two classes: AliasSetTracker and AliasSet. These interfaces
11f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// are used to classify a collection of pointer references into a maximal number
12f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
13f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot// object refers to memory disjoint from the other sets.
14f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//
15f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot//===----------------------------------------------------------------------===//
16f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
17f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
18f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#define LLVM_ANALYSIS_ALIASSETTRACKER_H
19f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
20f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/DenseMap.h"
21f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/DenseMapInfo.h"
22f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/ilist.h"
23f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/ADT/ilist_node.h"
24f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Analysis/AliasAnalysis.h"
25f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Instruction.h"
26f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/Metadata.h"
27f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/IR/ValueHandle.h"
28f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include "llvm/Support/Casting.h"
29f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <cassert>
30f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <cstddef>
31f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <cstdint>
32f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <iterator>
33f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#include <vector>
34f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
35f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotnamespace llvm {
36f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
37f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass AliasSetTracker;
38f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass BasicBlock;
39f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass LoadInst;
40f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MemSetInst;
41f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass MemTransferInst;
42f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass raw_ostream;
43f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass StoreInst;
44f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass VAArgInst;
45f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass Value;
46f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
47f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass AliasSet : public ilist_node<AliasSet> {
48f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  friend class AliasSetTracker;
49f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
50f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  class PointerRec {
51f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *Val;  // The pointer this record corresponds to.
52f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    PointerRec **PrevInList = nullptr;
53f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    PointerRec *NextInList = nullptr;
54f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    AliasSet *AS = nullptr;
55f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    uint64_t Size = 0;
56f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    AAMDNodes AAInfo;
57f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
58f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  public:
59f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    PointerRec(Value *V)
60f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : Val(V), AAInfo(DenseMapInfo<AAMDNodes>::getEmptyKey()) {}
61f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
62f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *getValue() const { return Val; }
63f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
64f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    PointerRec *getNext() const { return NextInList; }
65f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool hasAliasSet() const { return AS != nullptr; }
66f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
67f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    PointerRec** setPrevInList(PointerRec **PIL) {
68f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      PrevInList = PIL;
69f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return &NextInList;
70f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
71f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
72f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool updateSizeAndAAInfo(uint64_t NewSize, const AAMDNodes &NewAAInfo) {
73f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      bool SizeChanged = false;
74f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (NewSize > Size) {
75f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        Size = NewSize;
76f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        SizeChanged = true;
77f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
78f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
79f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey())
80f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        // We don't have a AAInfo yet. Set it to NewAAInfo.
81f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        AAInfo = NewAAInfo;
82f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      else {
83f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        AAMDNodes Intersection(AAInfo.intersect(NewAAInfo));
84f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        if (!Intersection) {
85f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          // NewAAInfo conflicts with AAInfo.
86f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          AAInfo = DenseMapInfo<AAMDNodes>::getTombstoneKey();
87f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          return SizeChanged;
88f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        }
89f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        AAInfo = Intersection;
90f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
91f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return SizeChanged;
92f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
93f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
94f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    uint64_t getSize() const { return Size; }
95f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
96f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    /// Return the AAInfo, or null if there is no information or conflicting
97f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    /// information.
98f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    AAMDNodes getAAInfo() const {
99f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      // If we have missing or conflicting AAInfo, return null.
100f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey() ||
101f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot          AAInfo == DenseMapInfo<AAMDNodes>::getTombstoneKey())
102f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        return AAMDNodes();
103f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return AAInfo;
104f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
105f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
106f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    AliasSet *getAliasSet(AliasSetTracker &AST) {
107f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(AS && "No AliasSet yet!");
108f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (AS->Forward) {
109f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        AliasSet *OldAS = AS;
110f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        AS = OldAS->getForwardedTarget(AST);
111f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        AS->addRef();
112f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        OldAS->dropRef(AST);
113f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
114f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return AS;
115f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
116f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
117f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    void setAliasSet(AliasSet *as) {
118f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(!AS && "Already have an alias set!");
119f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      AS = as;
120f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
121f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
122f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    void eraseFromList() {
123f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (NextInList) NextInList->PrevInList = PrevInList;
124f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      *PrevInList = NextInList;
125f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (AS->PtrListEnd == &NextInList) {
126f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        AS->PtrListEnd = PrevInList;
127f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        assert(*AS->PtrListEnd == nullptr && "List not terminated right!");
128f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
129f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      delete this;
130f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
131f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
132f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
133f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Doubly linked list of nodes.
134f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PointerRec *PtrList = nullptr;
135f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PointerRec **PtrListEnd;
136f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Forwarding pointer.
137f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet *Forward = nullptr;
138f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
139f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// All instructions without a specific address in this alias set.
140f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// In rare cases this vector can have a null'ed out WeakVH
141f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// instances (can happen if some other loop pass deletes an
142f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// instruction in this list).
143f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  std::vector<WeakVH> UnknownInsts;
144f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
145f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Number of nodes pointing to this AliasSet plus the number of AliasSets
146f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// forwarding to it.
147f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned RefCount : 27;
148f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
149f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Signifies that this set should be considered to alias any pointer.
150f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Use when the tracker holding this set is saturated.
151f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned AliasAny : 1;
152f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
153f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The kinds of access this alias set models.
154f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
155f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// We keep track of whether this alias set merely refers to the locations of
156f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// memory (and not any particular access), whether it modifies or references
157f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// the memory, or whether it does both. The lattice goes from "NoAccess" to
158f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// either RefAccess or ModAccess, then to ModRefAccess as necessary.
159f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  enum AccessLattice {
160f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    NoAccess = 0,
161f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    RefAccess = 1,
162f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    ModAccess = 2,
163f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    ModRefAccess = RefAccess | ModAccess
164f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
165f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned Access : 2;
166f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
167f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// The kind of alias relationship between pointers of the set.
168f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
169f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// These represent conservatively correct alias results between any members
170f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// of the set. We represent these independently of the values of alias
171f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// results in order to pack it into a single bit. Lattice goes from
172f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// MustAlias to MayAlias.
173f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  enum AliasLattice {
174f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    SetMustAlias = 0, SetMayAlias = 1
175f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
176f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned Alias : 1;
177f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
178f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// True if this alias set contains volatile loads or stores.
179f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned Volatile : 1;
180f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
181f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned SetSize = 0;
182f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
183f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void addRef() { ++RefCount; }
184f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
185f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void dropRef(AliasSetTracker &AST) {
186f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    assert(RefCount >= 1 && "Invalid reference count detected!");
187f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (--RefCount == 0)
188f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      removeFromTracker(AST);
189f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
190f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
191f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  Instruction *getUnknownInst(unsigned i) const {
192f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    assert(i < UnknownInsts.size());
193f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return cast_or_null<Instruction>(UnknownInsts[i]);
194f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
195f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
196f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
197f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet(const AliasSet &) = delete;
198f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet &operator=(const AliasSet &) = delete;
199f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
200f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Accessors...
201f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isRef() const { return Access & RefAccess; }
202f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isMod() const { return Access & ModAccess; }
203f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isMustAlias() const { return Alias == SetMustAlias; }
204f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isMayAlias()  const { return Alias == SetMayAlias; }
205f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
206f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return true if this alias set contains volatile loads or stores.
207f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isVolatile() const { return Volatile; }
208f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
209f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return true if this alias set should be ignored as part of the
210f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// AliasSetTracker object.
211f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool isForwardingAliasSet() const { return Forward; }
212f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
213f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Merge the specified alias set into this alias set.
214f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);
215f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
216f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Alias Set iteration - Allow access to all of the pointers which are part of
217f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // this alias set.
218f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  class iterator;
219f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  iterator begin() const { return iterator(PtrList); }
220f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  iterator end()   const { return iterator(); }
221f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool empty() const { return PtrList == nullptr; }
222f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
223f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Unfortunately, ilist::size() is linear, so we have to add code to keep
224f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // track of the list's exact size.
225f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned size() { return SetSize; }
226f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
227f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void print(raw_ostream &OS) const;
228f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void dump() const;
229f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
230f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Define an iterator for alias sets... this is just a forward iterator.
231f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  class iterator : public std::iterator<std::forward_iterator_tag,
232f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                        PointerRec, ptrdiff_t> {
233f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    PointerRec *CurNode;
234f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
235f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  public:
236f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {}
237f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
238f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool operator==(const iterator& x) const {
239f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return CurNode == x.CurNode;
240f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
241f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool operator!=(const iterator& x) const { return !operator==(x); }
242f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
243f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    value_type &operator*() const {
244f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(CurNode && "Dereferencing AliasSet.end()!");
245f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return *CurNode;
246f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
247f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    value_type *operator->() const { return &operator*(); }
248f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
249f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    Value *getPointer() const { return CurNode->getValue(); }
250f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    uint64_t getSize() const { return CurNode->getSize(); }
251f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    AAMDNodes getAAInfo() const { return CurNode->getAAInfo(); }
252f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
253f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    iterator& operator++() {                // Preincrement
254f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      assert(CurNode && "Advancing past AliasSet.end()!");
255f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      CurNode = CurNode->getNext();
256f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      return *this;
257f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
258f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    iterator operator++(int) { // Postincrement
259f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      iterator tmp = *this; ++*this; return tmp;
260f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
261f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
262f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
263f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
264f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Can only be created by AliasSetTracker.
265f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet()
266f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      : PtrListEnd(&PtrList), RefCount(0),  AliasAny(false), Access(NoAccess),
267f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        Alias(SetMustAlias), Volatile(false) {}
268f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
269f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PointerRec *getSomePointer() const {
270f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return PtrList;
271f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
272f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
273f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the real alias set this represents. If this has been merged with
274f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// another set and is forwarding, return the ultimate destination set. This
275f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// also implements the union-find collapsing as well.
276f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet *getForwardedTarget(AliasSetTracker &AST) {
277f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!Forward) return this;
278f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
279f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    AliasSet *Dest = Forward->getForwardedTarget(AST);
280f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (Dest != Forward) {
281f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Dest->addRef();
282f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Forward->dropRef(AST);
283f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Forward = Dest;
284f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    }
285f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return Dest;
286f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
287f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
288f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void removeFromTracker(AliasSetTracker &AST);
289f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
290f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size,
291f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                  const AAMDNodes &AAInfo,
292f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                  bool KnownMustAlias = false);
293f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void addUnknownInst(Instruction *I, AliasAnalysis &AA);
294f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
295f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void removeUnknownInst(AliasSetTracker &AST, Instruction *I) {
296f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    bool WasEmpty = UnknownInsts.empty();
297f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
298f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      if (UnknownInsts[i] == I) {
299f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        UnknownInsts[i] = UnknownInsts.back();
300f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        UnknownInsts.pop_back();
301f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot        --i; --e;  // Revisit the moved entry.
302f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      }
303f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!WasEmpty && UnknownInsts.empty())
304f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      dropRef(AST);
305f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
306f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
307f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void setVolatile() { Volatile = true; }
308f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
309f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
310f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return true if the specified pointer "may" (or must) alias one of the
311f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// members in the set.
312f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool aliasesPointer(const Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo,
313f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                      AliasAnalysis &AA) const;
314f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool aliasesUnknownInst(const Instruction *Inst, AliasAnalysis &AA) const;
315f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
316f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
317f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
318f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AS.print(OS);
319f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OS;
320f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
321f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
322f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotclass AliasSetTracker {
323f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// A CallbackVH to arrange for AliasSetTracker to be notified whenever a
324f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Value is deleted.
325f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  class ASTCallbackVH final : public CallbackVH {
326f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    AliasSetTracker *AST;
327f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
328f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    void deleted() override;
329f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    void allUsesReplacedWith(Value *) override;
330f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
331f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  public:
332f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    ASTCallbackVH(Value *V, AliasSetTracker *AST = nullptr);
333f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
334f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    ASTCallbackVH &operator=(Value *V);
335f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  };
336f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Traits to tell DenseMap that tell us how to compare and hash the value
337f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// handle.
338f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
339f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
340f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasAnalysis &AA;
341f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ilist<AliasSet> AliasSets;
342f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
343f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using PointerMapType = DenseMap<ASTCallbackVH, AliasSet::PointerRec *,
344f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                  ASTCallbackVHDenseMapInfo>;
345f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
346f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // Map from pointers to their node
347f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  PointerMapType PointerMap;
348f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
349f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotpublic:
350f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Create an empty collection of AliasSets, and use the specified alias
351f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// analysis object to disambiguate load and store addresses.
352f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
353f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ~AliasSetTracker() { clear(); }
354f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
355f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// These methods are used to add different types of instructions to the alias
356f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// sets. Adding a new instruction can result in one of three actions
357f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// happening:
358f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
359f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///   1. If the instruction doesn't alias any other sets, create a new set.
360f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///   2. If the instruction aliases exactly one set, add it to the set
361f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///   3. If the instruction aliases multiple sets, merge the sets, and add
362f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///      the instruction to the result.
363f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
364f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// These methods return true if inserting the instruction resulted in the
365f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// addition of a new alias set (i.e., the pointer did not alias anything).
366f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  ///
367f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo); // Add a loc.
368f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(LoadInst *LI);
369f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(StoreInst *SI);
370f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(VAArgInst *VAAI);
371f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(MemSetInst *MSI);
372f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(MemTransferInst *MTI);
373f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(Instruction *I);       // Dispatch to one of the other add methods...
374f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(BasicBlock &BB);       // Add all instructions in basic block
375f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void add(const AliasSetTracker &AST); // Add alias relations from another AST
376f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void addUnknown(Instruction *I);
377f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
378f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void clear();
379f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
380f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the alias sets that are active.
381f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
382f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
383f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the alias set that the specified pointer lives in. If the New
384f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// argument is non-null, this method sets the value to true if a new alias
385f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// set is created to contain the pointer (because the pointer didn't alias
386f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// anything).
387f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet &getAliasSetForPointer(Value *P, uint64_t Size,
388f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                  const AAMDNodes &AAInfo);
389f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
390f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the alias set containing the location specified if one exists,
391f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// otherwise return null.
392f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet *getAliasSetForPointerIfExists(const Value *P, uint64_t Size,
393f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                          const AAMDNodes &AAInfo) {
394f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return mergeAliasSetsForPointer(P, Size, AAInfo);
395f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
396f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
397f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return true if the specified instruction "may" (or must) alias one of the
398f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// members in any of the sets.
399f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  bool containsUnknown(const Instruction *I) const;
400f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
401f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Return the underlying alias analysis object used by this tracker.
402f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasAnalysis &getAliasAnalysis() const { return AA; }
403f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
404f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// This method is used to remove a pointer value from the AliasSetTracker
405f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// entirely. It should be used when an instruction is deleted from the
406f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// program to update the AST. If you don't use this, you would have dangling
407f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// pointers to deleted instructions.
408f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void deleteValue(Value *PtrVal);
409f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
410f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// This method should be used whenever a preexisting value in the program is
411f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// copied or cloned, introducing a new value.  Note that it is ok for clients
412f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// that use this method to introduce the same value multiple times: if the
413f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// tracker already knows about a value, it will ignore the request.
414f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void copyValue(Value *From, Value *To);
415f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
416f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using iterator = ilist<AliasSet>::iterator;
417f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  using const_iterator = ilist<AliasSet>::const_iterator;
418f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
419f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const_iterator begin() const { return AliasSets.begin(); }
420f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  const_iterator end()   const { return AliasSets.end(); }
421f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
422f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  iterator begin() { return AliasSets.begin(); }
423f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  iterator end()   { return AliasSets.end(); }
424f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
425f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void print(raw_ostream &OS) const;
426f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void dump() const;
427f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
428f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotprivate:
429f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  friend class AliasSet;
430f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
431f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // The total number of pointers contained in all "may" alias sets.
432f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  unsigned TotalMayAliasSetSize = 0;
433f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
434f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // A non-null value signifies this AST is saturated. A saturated AST lumps
435f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  // all pointers into a single "May" set.
436f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet *AliasAnyAS = nullptr;
437f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
438f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  void removeAliasSet(AliasSet *AS);
439f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
440f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Just like operator[] on the map, except that it creates an entry for the
441f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// pointer if it doesn't already exist.
442f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet::PointerRec &getEntryFor(Value *V) {
443f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
444f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    if (!Entry)
445f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot      Entry = new AliasSet::PointerRec(V);
446f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot    return *Entry;
447f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  }
448f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
449f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet &addPointer(Value *P, uint64_t Size, const AAMDNodes &AAInfo,
450f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                       AliasSet::AccessLattice E);
451f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet *mergeAliasSetsForPointer(const Value *Ptr, uint64_t Size,
452f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot                                     const AAMDNodes &AAInfo);
453f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
454f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// Merge all alias sets into a single set that is considered to alias any
455f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  /// pointer.
456f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet &mergeAllAliasSets();
457f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
458f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
459f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot};
460f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
461f3014761c955345d6e05491608e73228d014afbandroid-build-team Robotinline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
462f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  AST.print(OS);
463f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot  return OS;
464f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot}
465f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
466f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot} // end namespace llvm
467f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot
468f3014761c955345d6e05491608e73228d014afbandroid-build-team Robot#endif // LLVM_ANALYSIS_ALIASSETTRACKER_H
469