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