AliasSetTracker.h 15 KB

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