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