LLVM API Documentation
00001 //===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines two classes: AliasSetTracker and AliasSet. These interface 00011 // are used to classify a collection of pointer references into a maximal number 00012 // of disjoint sets. Each AliasSet object constructed by the AliasSetTracker 00013 // object refers to memory disjoint from the other sets. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H 00018 #define LLVM_ANALYSIS_ALIASSETTRACKER_H 00019 00020 #include "llvm/ADT/DenseMap.h" 00021 #include "llvm/ADT/ilist.h" 00022 #include "llvm/ADT/ilist_node.h" 00023 #include "llvm/IR/Metadata.h" 00024 #include "llvm/IR/ValueHandle.h" 00025 #include <vector> 00026 00027 namespace llvm { 00028 00029 class AliasAnalysis; 00030 class LoadInst; 00031 class StoreInst; 00032 class VAArgInst; 00033 class AliasSetTracker; 00034 class AliasSet; 00035 00036 class AliasSet : public ilist_node<AliasSet> { 00037 friend class AliasSetTracker; 00038 00039 class PointerRec { 00040 Value *Val; // The pointer this record corresponds to. 00041 PointerRec **PrevInList, *NextInList; 00042 AliasSet *AS; 00043 uint64_t Size; 00044 AAMDNodes AAInfo; 00045 public: 00046 PointerRec(Value *V) 00047 : Val(V), PrevInList(nullptr), NextInList(nullptr), AS(nullptr), Size(0), 00048 AAInfo(DenseMapInfo<AAMDNodes>::getEmptyKey()) {} 00049 00050 Value *getValue() const { return Val; } 00051 00052 PointerRec *getNext() const { return NextInList; } 00053 bool hasAliasSet() const { return AS != nullptr; } 00054 00055 PointerRec** setPrevInList(PointerRec **PIL) { 00056 PrevInList = PIL; 00057 return &NextInList; 00058 } 00059 00060 void updateSizeAndAAInfo(uint64_t NewSize, const AAMDNodes &NewAAInfo) { 00061 if (NewSize > Size) Size = NewSize; 00062 00063 if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey()) 00064 // We don't have a AAInfo yet. Set it to NewAAInfo. 00065 AAInfo = NewAAInfo; 00066 else if (AAInfo != NewAAInfo) 00067 // NewAAInfo conflicts with AAInfo. 00068 AAInfo = DenseMapInfo<AAMDNodes>::getTombstoneKey(); 00069 } 00070 00071 uint64_t getSize() const { return Size; } 00072 00073 /// getAAInfo - Return the AAInfo, or null if there is no 00074 /// information or conflicting information. 00075 AAMDNodes getAAInfo() const { 00076 // If we have missing or conflicting AAInfo, return null. 00077 if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey() || 00078 AAInfo == DenseMapInfo<AAMDNodes>::getTombstoneKey()) 00079 return AAMDNodes(); 00080 return AAInfo; 00081 } 00082 00083 AliasSet *getAliasSet(AliasSetTracker &AST) { 00084 assert(AS && "No AliasSet yet!"); 00085 if (AS->Forward) { 00086 AliasSet *OldAS = AS; 00087 AS = OldAS->getForwardedTarget(AST); 00088 AS->addRef(); 00089 OldAS->dropRef(AST); 00090 } 00091 return AS; 00092 } 00093 00094 void setAliasSet(AliasSet *as) { 00095 assert(!AS && "Already have an alias set!"); 00096 AS = as; 00097 } 00098 00099 void eraseFromList() { 00100 if (NextInList) NextInList->PrevInList = PrevInList; 00101 *PrevInList = NextInList; 00102 if (AS->PtrListEnd == &NextInList) { 00103 AS->PtrListEnd = PrevInList; 00104 assert(*AS->PtrListEnd == nullptr && "List not terminated right!"); 00105 } 00106 delete this; 00107 } 00108 }; 00109 00110 PointerRec *PtrList, **PtrListEnd; // Doubly linked list of nodes. 00111 AliasSet *Forward; // Forwarding pointer. 00112 00113 // All instructions without a specific address in this alias set. 00114 std::vector<AssertingVH<Instruction> > UnknownInsts; 00115 00116 // RefCount - Number of nodes pointing to this AliasSet plus the number of 00117 // AliasSets forwarding to it. 00118 unsigned RefCount : 28; 00119 00120 /// AccessType - Keep track of whether this alias set merely refers to the 00121 /// locations of memory, whether it modifies the memory, or whether it does 00122 /// both. The lattice goes from "NoModRef" to either Refs or Mods, then to 00123 /// ModRef as necessary. 00124 /// 00125 enum AccessType { 00126 NoModRef = 0, Refs = 1, // Ref = bit 1 00127 Mods = 2, ModRef = 3 // Mod = bit 2 00128 }; 00129 unsigned AccessTy : 2; 00130 00131 /// AliasType - Keep track the relationships between the pointers in the set. 00132 /// Lattice goes from MustAlias to MayAlias. 00133 /// 00134 enum AliasType { 00135 MustAlias = 0, MayAlias = 1 00136 }; 00137 unsigned AliasTy : 1; 00138 00139 // Volatile - True if this alias set contains volatile loads or stores. 00140 bool Volatile : 1; 00141 00142 void addRef() { ++RefCount; } 00143 void dropRef(AliasSetTracker &AST) { 00144 assert(RefCount >= 1 && "Invalid reference count detected!"); 00145 if (--RefCount == 0) 00146 removeFromTracker(AST); 00147 } 00148 00149 Instruction *getUnknownInst(unsigned i) const { 00150 assert(i < UnknownInsts.size()); 00151 return UnknownInsts[i]; 00152 } 00153 00154 public: 00155 /// Accessors... 00156 bool isRef() const { return AccessTy & Refs; } 00157 bool isMod() const { return AccessTy & Mods; } 00158 bool isMustAlias() const { return AliasTy == MustAlias; } 00159 bool isMayAlias() const { return AliasTy == MayAlias; } 00160 00161 // isVolatile - Return true if this alias set contains volatile loads or 00162 // stores. 00163 bool isVolatile() const { return Volatile; } 00164 00165 /// isForwardingAliasSet - Return true if this alias set should be ignored as 00166 /// part of the AliasSetTracker object. 00167 bool isForwardingAliasSet() const { return Forward; } 00168 00169 /// mergeSetIn - Merge the specified alias set into this alias set... 00170 /// 00171 void mergeSetIn(AliasSet &AS, AliasSetTracker &AST); 00172 00173 // Alias Set iteration - Allow access to all of the pointer which are part of 00174 // this alias set... 00175 class iterator; 00176 iterator begin() const { return iterator(PtrList); } 00177 iterator end() const { return iterator(); } 00178 bool empty() const { return PtrList == nullptr; } 00179 00180 void print(raw_ostream &OS) const; 00181 void dump() const; 00182 00183 /// Define an iterator for alias sets... this is just a forward iterator. 00184 class iterator : public std::iterator<std::forward_iterator_tag, 00185 PointerRec, ptrdiff_t> { 00186 PointerRec *CurNode; 00187 public: 00188 explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {} 00189 00190 bool operator==(const iterator& x) const { 00191 return CurNode == x.CurNode; 00192 } 00193 bool operator!=(const iterator& x) const { return !operator==(x); } 00194 00195 const iterator &operator=(const iterator &I) { 00196 CurNode = I.CurNode; 00197 return *this; 00198 } 00199 00200 value_type &operator*() const { 00201 assert(CurNode && "Dereferencing AliasSet.end()!"); 00202 return *CurNode; 00203 } 00204 value_type *operator->() const { return &operator*(); } 00205 00206 Value *getPointer() const { return CurNode->getValue(); } 00207 uint64_t getSize() const { return CurNode->getSize(); } 00208 AAMDNodes getAAInfo() const { return CurNode->getAAInfo(); } 00209 00210 iterator& operator++() { // Preincrement 00211 assert(CurNode && "Advancing past AliasSet.end()!"); 00212 CurNode = CurNode->getNext(); 00213 return *this; 00214 } 00215 iterator operator++(int) { // Postincrement 00216 iterator tmp = *this; ++*this; return tmp; 00217 } 00218 }; 00219 00220 private: 00221 // Can only be created by AliasSetTracker. Also, ilist creates one 00222 // to serve as a sentinel. 00223 friend struct ilist_sentinel_traits<AliasSet>; 00224 AliasSet() 00225 : PtrList(nullptr), PtrListEnd(&PtrList), Forward(nullptr), RefCount(0), 00226 AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) { 00227 } 00228 00229 AliasSet(const AliasSet &AS) LLVM_DELETED_FUNCTION; 00230 void operator=(const AliasSet &AS) LLVM_DELETED_FUNCTION; 00231 00232 PointerRec *getSomePointer() const { 00233 return PtrList; 00234 } 00235 00236 /// getForwardedTarget - Return the real alias set this represents. If this 00237 /// has been merged with another set and is forwarding, return the ultimate 00238 /// destination set. This also implements the union-find collapsing as well. 00239 AliasSet *getForwardedTarget(AliasSetTracker &AST) { 00240 if (!Forward) return this; 00241 00242 AliasSet *Dest = Forward->getForwardedTarget(AST); 00243 if (Dest != Forward) { 00244 Dest->addRef(); 00245 Forward->dropRef(AST); 00246 Forward = Dest; 00247 } 00248 return Dest; 00249 } 00250 00251 void removeFromTracker(AliasSetTracker &AST); 00252 00253 void addPointer(AliasSetTracker &AST, PointerRec &Entry, uint64_t Size, 00254 const AAMDNodes &AAInfo, 00255 bool KnownMustAlias = false); 00256 void addUnknownInst(Instruction *I, AliasAnalysis &AA); 00257 void removeUnknownInst(Instruction *I) { 00258 for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i) 00259 if (UnknownInsts[i] == I) { 00260 UnknownInsts[i] = UnknownInsts.back(); 00261 UnknownInsts.pop_back(); 00262 --i; --e; // Revisit the moved entry. 00263 } 00264 } 00265 void setVolatile() { Volatile = true; } 00266 00267 public: 00268 /// aliasesPointer - Return true if the specified pointer "may" (or must) 00269 /// alias one of the members in the set. 00270 /// 00271 bool aliasesPointer(const Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo, 00272 AliasAnalysis &AA) const; 00273 bool aliasesUnknownInst(Instruction *Inst, AliasAnalysis &AA) const; 00274 }; 00275 00276 inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) { 00277 AS.print(OS); 00278 return OS; 00279 } 00280 00281 00282 class AliasSetTracker { 00283 /// CallbackVH - A CallbackVH to arrange for AliasSetTracker to be 00284 /// notified whenever a Value is deleted. 00285 class ASTCallbackVH : public CallbackVH { 00286 AliasSetTracker *AST; 00287 void deleted() override; 00288 void allUsesReplacedWith(Value *) override; 00289 public: 00290 ASTCallbackVH(Value *V, AliasSetTracker *AST = nullptr); 00291 ASTCallbackVH &operator=(Value *V); 00292 }; 00293 /// ASTCallbackVHDenseMapInfo - Traits to tell DenseMap that tell us how to 00294 /// compare and hash the value handle. 00295 struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {}; 00296 00297 AliasAnalysis &AA; 00298 ilist<AliasSet> AliasSets; 00299 00300 typedef DenseMap<ASTCallbackVH, AliasSet::PointerRec*, 00301 ASTCallbackVHDenseMapInfo> 00302 PointerMapType; 00303 00304 // Map from pointers to their node 00305 PointerMapType PointerMap; 00306 00307 public: 00308 /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use 00309 /// the specified alias analysis object to disambiguate load and store 00310 /// addresses. 00311 explicit AliasSetTracker(AliasAnalysis &aa) : AA(aa) {} 00312 ~AliasSetTracker() { clear(); } 00313 00314 /// add methods - These methods are used to add different types of 00315 /// instructions to the alias sets. Adding a new instruction can result in 00316 /// one of three actions happening: 00317 /// 00318 /// 1. If the instruction doesn't alias any other sets, create a new set. 00319 /// 2. If the instruction aliases exactly one set, add it to the set 00320 /// 3. If the instruction aliases multiple sets, merge the sets, and add 00321 /// the instruction to the result. 00322 /// 00323 /// These methods return true if inserting the instruction resulted in the 00324 /// addition of a new alias set (i.e., the pointer did not alias anything). 00325 /// 00326 bool add(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo); // Add a loc. 00327 bool add(LoadInst *LI); 00328 bool add(StoreInst *SI); 00329 bool add(VAArgInst *VAAI); 00330 bool add(Instruction *I); // Dispatch to one of the other add methods... 00331 void add(BasicBlock &BB); // Add all instructions in basic block 00332 void add(const AliasSetTracker &AST); // Add alias relations from another AST 00333 bool addUnknown(Instruction *I); 00334 00335 /// remove methods - These methods are used to remove all entries that might 00336 /// be aliased by the specified instruction. These methods return true if any 00337 /// alias sets were eliminated. 00338 // Remove a location 00339 bool remove(Value *Ptr, uint64_t Size, const AAMDNodes &AAInfo); 00340 bool remove(LoadInst *LI); 00341 bool remove(StoreInst *SI); 00342 bool remove(VAArgInst *VAAI); 00343 bool remove(Instruction *I); 00344 void remove(AliasSet &AS); 00345 bool removeUnknown(Instruction *I); 00346 00347 void clear(); 00348 00349 /// getAliasSets - Return the alias sets that are active. 00350 /// 00351 const ilist<AliasSet> &getAliasSets() const { return AliasSets; } 00352 00353 /// getAliasSetForPointer - Return the alias set that the specified pointer 00354 /// lives in. If the New argument is non-null, this method sets the value to 00355 /// true if a new alias set is created to contain the pointer (because the 00356 /// pointer didn't alias anything). 00357 AliasSet &getAliasSetForPointer(Value *P, uint64_t Size, 00358 const AAMDNodes &AAInfo, 00359 bool *New = nullptr); 00360 00361 /// getAliasSetForPointerIfExists - Return the alias set containing the 00362 /// location specified if one exists, otherwise return null. 00363 AliasSet *getAliasSetForPointerIfExists(Value *P, uint64_t Size, 00364 const AAMDNodes &AAInfo) { 00365 return findAliasSetForPointer(P, Size, AAInfo); 00366 } 00367 00368 /// containsPointer - Return true if the specified location is represented by 00369 /// this alias set, false otherwise. This does not modify the AST object or 00370 /// alias sets. 00371 bool containsPointer(Value *P, uint64_t Size, const AAMDNodes &AAInfo) const; 00372 00373 /// getAliasAnalysis - Return the underlying alias analysis object used by 00374 /// this tracker. 00375 AliasAnalysis &getAliasAnalysis() const { return AA; } 00376 00377 /// deleteValue method - This method is used to remove a pointer value from 00378 /// the AliasSetTracker entirely. It should be used when an instruction is 00379 /// deleted from the program to update the AST. If you don't use this, you 00380 /// would have dangling pointers to deleted instructions. 00381 /// 00382 void deleteValue(Value *PtrVal); 00383 00384 /// copyValue - This method should be used whenever a preexisting value in the 00385 /// program is copied or cloned, introducing a new value. Note that it is ok 00386 /// for clients that use this method to introduce the same value multiple 00387 /// times: if the tracker already knows about a value, it will ignore the 00388 /// request. 00389 /// 00390 void copyValue(Value *From, Value *To); 00391 00392 00393 typedef ilist<AliasSet>::iterator iterator; 00394 typedef ilist<AliasSet>::const_iterator const_iterator; 00395 00396 const_iterator begin() const { return AliasSets.begin(); } 00397 const_iterator end() const { return AliasSets.end(); } 00398 00399 iterator begin() { return AliasSets.begin(); } 00400 iterator end() { return AliasSets.end(); } 00401 00402 void print(raw_ostream &OS) const; 00403 void dump() const; 00404 00405 private: 00406 friend class AliasSet; 00407 void removeAliasSet(AliasSet *AS); 00408 00409 // getEntryFor - Just like operator[] on the map, except that it creates an 00410 // entry for the pointer if it doesn't already exist. 00411 AliasSet::PointerRec &getEntryFor(Value *V) { 00412 AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)]; 00413 if (!Entry) 00414 Entry = new AliasSet::PointerRec(V); 00415 return *Entry; 00416 } 00417 00418 AliasSet &addPointer(Value *P, uint64_t Size, const AAMDNodes &AAInfo, 00419 AliasSet::AccessType E, 00420 bool &NewSet) { 00421 NewSet = false; 00422 AliasSet &AS = getAliasSetForPointer(P, Size, AAInfo, &NewSet); 00423 AS.AccessTy |= E; 00424 return AS; 00425 } 00426 AliasSet *findAliasSetForPointer(const Value *Ptr, uint64_t Size, 00427 const AAMDNodes &AAInfo); 00428 00429 AliasSet *findAliasSetForUnknownInst(Instruction *Inst); 00430 }; 00431 00432 inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) { 00433 AST.print(OS); 00434 return OS; 00435 } 00436 00437 } // End llvm namespace 00438 00439 #endif