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