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