AliasSetTracker.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file defines two classes: AliasSetTracker and AliasSet. These interfaces
  15. // are used to classify a collection of pointer references into a maximal number
  16. // of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
  17. // object refers to memory disjoint from the other sets.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
  21. #define LLVM_ANALYSIS_ALIASSETTRACKER_H
  22. #include "llvm/ADT/DenseMap.h"
  23. #include "llvm/ADT/DenseMapInfo.h"
  24. #include "llvm/ADT/ilist.h"
  25. #include "llvm/ADT/ilist_node.h"
  26. #include "llvm/Analysis/MemoryLocation.h"
  27. #include "llvm/IR/Instruction.h"
  28. #include "llvm/IR/Metadata.h"
  29. #include "llvm/IR/PassManager.h"
  30. #include "llvm/IR/ValueHandle.h"
  31. #include "llvm/Support/Casting.h"
  32. #include <cassert>
  33. #include <cstddef>
  34. #include <cstdint>
  35. #include <iterator>
  36. #include <vector>
  37. namespace llvm {
  38. class AAResults;
  39. class AliasSetTracker;
  40. class BasicBlock;
  41. class LoadInst;
  42. class Loop;
  43. class MemorySSA;
  44. class AnyMemSetInst;
  45. class AnyMemTransferInst;
  46. class raw_ostream;
  47. class StoreInst;
  48. class VAArgInst;
  49. class Value;
  50. enum AliasResult : uint8_t;
  51. class AliasSet : public ilist_node<AliasSet> {
  52. friend class AliasSetTracker;
  53. class PointerRec {
  54. Value *Val; // The pointer this record corresponds to.
  55. PointerRec **PrevInList = nullptr;
  56. PointerRec *NextInList = nullptr;
  57. AliasSet *AS = nullptr;
  58. LocationSize Size = LocationSize::mapEmpty();
  59. AAMDNodes AAInfo;
  60. // Whether the size for this record has been set at all. This makes no
  61. // guarantees about the size being known.
  62. bool isSizeSet() const { return Size != LocationSize::mapEmpty(); }
  63. public:
  64. PointerRec(Value *V)
  65. : Val(V), AAInfo(DenseMapInfo<AAMDNodes>::getEmptyKey()) {}
  66. Value *getValue() const { return Val; }
  67. PointerRec *getNext() const { return NextInList; }
  68. bool hasAliasSet() const { return AS != nullptr; }
  69. PointerRec** setPrevInList(PointerRec **PIL) {
  70. PrevInList = PIL;
  71. return &NextInList;
  72. }
  73. bool updateSizeAndAAInfo(LocationSize NewSize, const AAMDNodes &NewAAInfo) {
  74. bool SizeChanged = false;
  75. if (NewSize != Size) {
  76. LocationSize OldSize = Size;
  77. Size = isSizeSet() ? Size.unionWith(NewSize) : NewSize;
  78. SizeChanged = OldSize != Size;
  79. }
  80. if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey())
  81. // We don't have a AAInfo yet. Set it to NewAAInfo.
  82. AAInfo = NewAAInfo;
  83. else {
  84. AAMDNodes Intersection(AAInfo.intersect(NewAAInfo));
  85. SizeChanged |= Intersection != AAInfo;
  86. AAInfo = Intersection;
  87. }
  88. return SizeChanged;
  89. }
  90. LocationSize getSize() const {
  91. assert(isSizeSet() && "Getting an unset size!");
  92. return Size;
  93. }
  94. /// Return the AAInfo, or null if there is no information or conflicting
  95. /// information.
  96. AAMDNodes getAAInfo() const {
  97. // If we have missing or conflicting AAInfo, return null.
  98. if (AAInfo == DenseMapInfo<AAMDNodes>::getEmptyKey() ||
  99. AAInfo == DenseMapInfo<AAMDNodes>::getTombstoneKey())
  100. return AAMDNodes();
  101. return AAInfo;
  102. }
  103. AliasSet *getAliasSet(AliasSetTracker &AST) {
  104. assert(AS && "No AliasSet yet!");
  105. if (AS->Forward) {
  106. AliasSet *OldAS = AS;
  107. AS = OldAS->getForwardedTarget(AST);
  108. AS->addRef();
  109. OldAS->dropRef(AST);
  110. }
  111. return AS;
  112. }
  113. void setAliasSet(AliasSet *as) {
  114. assert(!AS && "Already have an alias set!");
  115. AS = as;
  116. }
  117. void eraseFromList() {
  118. if (NextInList) NextInList->PrevInList = PrevInList;
  119. *PrevInList = NextInList;
  120. if (AS->PtrListEnd == &NextInList) {
  121. AS->PtrListEnd = PrevInList;
  122. assert(*AS->PtrListEnd == nullptr && "List not terminated right!");
  123. }
  124. delete this;
  125. }
  126. };
  127. // Doubly linked list of nodes.
  128. PointerRec *PtrList = nullptr;
  129. PointerRec **PtrListEnd;
  130. // Forwarding pointer.
  131. AliasSet *Forward = nullptr;
  132. /// All instructions without a specific address in this alias set.
  133. /// In rare cases this vector can have a null'ed out WeakVH
  134. /// instances (can happen if some other loop pass deletes an
  135. /// instruction in this list).
  136. std::vector<WeakVH> UnknownInsts;
  137. /// Number of nodes pointing to this AliasSet plus the number of AliasSets
  138. /// forwarding to it.
  139. unsigned RefCount : 27;
  140. // Signifies that this set should be considered to alias any pointer.
  141. // Use when the tracker holding this set is saturated.
  142. unsigned AliasAny : 1;
  143. /// The kinds of access this alias set models.
  144. ///
  145. /// We keep track of whether this alias set merely refers to the locations of
  146. /// memory (and not any particular access), whether it modifies or references
  147. /// the memory, or whether it does both. The lattice goes from "NoAccess" to
  148. /// either RefAccess or ModAccess, then to ModRefAccess as necessary.
  149. enum AccessLattice {
  150. NoAccess = 0,
  151. RefAccess = 1,
  152. ModAccess = 2,
  153. ModRefAccess = RefAccess | ModAccess
  154. };
  155. unsigned Access : 2;
  156. /// The kind of alias relationship between pointers of the set.
  157. ///
  158. /// These represent conservatively correct alias results between any members
  159. /// of the set. We represent these independently of the values of alias
  160. /// results in order to pack it into a single bit. Lattice goes from
  161. /// MustAlias to MayAlias.
  162. enum AliasLattice {
  163. SetMustAlias = 0, SetMayAlias = 1
  164. };
  165. unsigned Alias : 1;
  166. unsigned SetSize = 0;
  167. void addRef() { ++RefCount; }
  168. void dropRef(AliasSetTracker &AST) {
  169. assert(RefCount >= 1 && "Invalid reference count detected!");
  170. if (--RefCount == 0)
  171. removeFromTracker(AST);
  172. }
  173. Instruction *getUnknownInst(unsigned i) const {
  174. assert(i < UnknownInsts.size());
  175. return cast_or_null<Instruction>(UnknownInsts[i]);
  176. }
  177. public:
  178. AliasSet(const AliasSet &) = delete;
  179. AliasSet &operator=(const AliasSet &) = delete;
  180. /// Accessors...
  181. bool isRef() const { return Access & RefAccess; }
  182. bool isMod() const { return Access & ModAccess; }
  183. bool isMustAlias() const { return Alias == SetMustAlias; }
  184. bool isMayAlias() const { return Alias == SetMayAlias; }
  185. /// Return true if this alias set should be ignored as part of the
  186. /// AliasSetTracker object.
  187. bool isForwardingAliasSet() const { return Forward; }
  188. /// Merge the specified alias set into this alias set.
  189. void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);
  190. // Alias Set iteration - Allow access to all of the pointers which are part of
  191. // this alias set.
  192. class iterator;
  193. iterator begin() const { return iterator(PtrList); }
  194. iterator end() const { return iterator(); }
  195. bool empty() const { return PtrList == nullptr; }
  196. // Unfortunately, ilist::size() is linear, so we have to add code to keep
  197. // track of the list's exact size.
  198. unsigned size() { return SetSize; }
  199. /// If this alias set is known to contain a single instruction and *only* a
  200. /// single unique instruction, return it. Otherwise, return nullptr.
  201. Instruction* getUniqueInstruction();
  202. void print(raw_ostream &OS) const;
  203. void dump() const;
  204. /// Define an iterator for alias sets... this is just a forward iterator.
  205. class iterator : public std::iterator<std::forward_iterator_tag,
  206. PointerRec, ptrdiff_t> {
  207. PointerRec *CurNode;
  208. public:
  209. explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {}
  210. bool operator==(const iterator& x) const {
  211. return CurNode == x.CurNode;
  212. }
  213. bool operator!=(const iterator& x) const { return !operator==(x); }
  214. value_type &operator*() const {
  215. assert(CurNode && "Dereferencing AliasSet.end()!");
  216. return *CurNode;
  217. }
  218. value_type *operator->() const { return &operator*(); }
  219. Value *getPointer() const { return CurNode->getValue(); }
  220. LocationSize getSize() const { return CurNode->getSize(); }
  221. AAMDNodes getAAInfo() const { return CurNode->getAAInfo(); }
  222. iterator& operator++() { // Preincrement
  223. assert(CurNode && "Advancing past AliasSet.end()!");
  224. CurNode = CurNode->getNext();
  225. return *this;
  226. }
  227. iterator operator++(int) { // Postincrement
  228. iterator tmp = *this; ++*this; return tmp;
  229. }
  230. };
  231. private:
  232. // Can only be created by AliasSetTracker.
  233. AliasSet()
  234. : PtrListEnd(&PtrList), RefCount(0), AliasAny(false), Access(NoAccess),
  235. Alias(SetMustAlias) {}
  236. PointerRec *getSomePointer() const {
  237. return PtrList;
  238. }
  239. /// Return the real alias set this represents. If this has been merged with
  240. /// another set and is forwarding, return the ultimate destination set. This
  241. /// also implements the union-find collapsing as well.
  242. AliasSet *getForwardedTarget(AliasSetTracker &AST) {
  243. if (!Forward) return this;
  244. AliasSet *Dest = Forward->getForwardedTarget(AST);
  245. if (Dest != Forward) {
  246. Dest->addRef();
  247. Forward->dropRef(AST);
  248. Forward = Dest;
  249. }
  250. return Dest;
  251. }
  252. void removeFromTracker(AliasSetTracker &AST);
  253. void addPointer(AliasSetTracker &AST, PointerRec &Entry, LocationSize Size,
  254. const AAMDNodes &AAInfo, bool KnownMustAlias = false,
  255. bool SkipSizeUpdate = false);
  256. void addUnknownInst(Instruction *I, AAResults &AA);
  257. void removeUnknownInst(AliasSetTracker &AST, Instruction *I) {
  258. bool WasEmpty = UnknownInsts.empty();
  259. for (size_t i = 0, e = UnknownInsts.size(); i != e; ++i)
  260. if (UnknownInsts[i] == I) {
  261. UnknownInsts[i] = UnknownInsts.back();
  262. UnknownInsts.pop_back();
  263. --i; --e; // Revisit the moved entry.
  264. }
  265. if (!WasEmpty && UnknownInsts.empty())
  266. dropRef(AST);
  267. }
  268. public:
  269. /// If the specified pointer "may" (or must) alias one of the members in the
  270. /// set return the appropriate AliasResult. Otherwise return NoAlias.
  271. AliasResult aliasesPointer(const Value *Ptr, LocationSize Size,
  272. const AAMDNodes &AAInfo, AAResults &AA) const;
  273. bool aliasesUnknownInst(const Instruction *Inst, AAResults &AA) const;
  274. };
  275. inline raw_ostream& operator<<(raw_ostream &OS, const AliasSet &AS) {
  276. AS.print(OS);
  277. return OS;
  278. }
  279. class AliasSetTracker {
  280. /// A CallbackVH to arrange for AliasSetTracker to be notified whenever a
  281. /// Value is deleted.
  282. class ASTCallbackVH final : public CallbackVH {
  283. AliasSetTracker *AST;
  284. void deleted() override;
  285. void allUsesReplacedWith(Value *) override;
  286. public:
  287. ASTCallbackVH(Value *V, AliasSetTracker *AST = nullptr);
  288. ASTCallbackVH &operator=(Value *V);
  289. };
  290. /// Traits to tell DenseMap that tell us how to compare and hash the value
  291. /// handle.
  292. struct ASTCallbackVHDenseMapInfo : public DenseMapInfo<Value *> {};
  293. AAResults &AA;
  294. MemorySSA *MSSA = nullptr;
  295. Loop *L = nullptr;
  296. ilist<AliasSet> AliasSets;
  297. using PointerMapType = DenseMap<ASTCallbackVH, AliasSet::PointerRec *,
  298. ASTCallbackVHDenseMapInfo>;
  299. // Map from pointers to their node
  300. PointerMapType PointerMap;
  301. public:
  302. /// Create an empty collection of AliasSets, and use the specified alias
  303. /// analysis object to disambiguate load and store addresses.
  304. explicit AliasSetTracker(AAResults &AA) : AA(AA) {}
  305. explicit AliasSetTracker(AAResults &AA, MemorySSA *MSSA, Loop *L)
  306. : AA(AA), MSSA(MSSA), L(L) {}
  307. ~AliasSetTracker() { clear(); }
  308. /// These methods are used to add different types of instructions to the alias
  309. /// sets. Adding a new instruction can result in one of three actions
  310. /// happening:
  311. ///
  312. /// 1. If the instruction doesn't alias any other sets, create a new set.
  313. /// 2. If the instruction aliases exactly one set, add it to the set
  314. /// 3. If the instruction aliases multiple sets, merge the sets, and add
  315. /// the instruction to the result.
  316. ///
  317. /// These methods return true if inserting the instruction resulted in the
  318. /// addition of a new alias set (i.e., the pointer did not alias anything).
  319. ///
  320. void add(Value *Ptr, LocationSize Size, const AAMDNodes &AAInfo); // Add a loc
  321. void add(LoadInst *LI);
  322. void add(StoreInst *SI);
  323. void add(VAArgInst *VAAI);
  324. void add(AnyMemSetInst *MSI);
  325. void add(AnyMemTransferInst *MTI);
  326. void add(Instruction *I); // Dispatch to one of the other add methods...
  327. void add(BasicBlock &BB); // Add all instructions in basic block
  328. void add(const AliasSetTracker &AST); // Add alias relations from another AST
  329. void addUnknown(Instruction *I);
  330. void addAllInstructionsInLoopUsingMSSA();
  331. void clear();
  332. /// Return the alias sets that are active.
  333. const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
  334. /// Return the alias set which contains the specified memory location. If
  335. /// the memory location aliases two or more existing alias sets, will have
  336. /// the effect of merging those alias sets before the single resulting alias
  337. /// set is returned.
  338. AliasSet &getAliasSetFor(const MemoryLocation &MemLoc);
  339. /// Return the underlying alias analysis object used by this tracker.
  340. AAResults &getAliasAnalysis() const { return AA; }
  341. /// This method is used to remove a pointer value from the AliasSetTracker
  342. /// entirely. It should be used when an instruction is deleted from the
  343. /// program to update the AST. If you don't use this, you would have dangling
  344. /// pointers to deleted instructions.
  345. void deleteValue(Value *PtrVal);
  346. /// This method should be used whenever a preexisting value in the program is
  347. /// copied or cloned, introducing a new value. Note that it is ok for clients
  348. /// that use this method to introduce the same value multiple times: if the
  349. /// tracker already knows about a value, it will ignore the request.
  350. void copyValue(Value *From, Value *To);
  351. using iterator = ilist<AliasSet>::iterator;
  352. using const_iterator = ilist<AliasSet>::const_iterator;
  353. const_iterator begin() const { return AliasSets.begin(); }
  354. const_iterator end() const { return AliasSets.end(); }
  355. iterator begin() { return AliasSets.begin(); }
  356. iterator end() { return AliasSets.end(); }
  357. void print(raw_ostream &OS) const;
  358. void dump() const;
  359. private:
  360. friend class AliasSet;
  361. // The total number of pointers contained in all "may" alias sets.
  362. unsigned TotalMayAliasSetSize = 0;
  363. // A non-null value signifies this AST is saturated. A saturated AST lumps
  364. // all pointers into a single "May" set.
  365. AliasSet *AliasAnyAS = nullptr;
  366. void removeAliasSet(AliasSet *AS);
  367. /// Just like operator[] on the map, except that it creates an entry for the
  368. /// pointer if it doesn't already exist.
  369. AliasSet::PointerRec &getEntryFor(Value *V) {
  370. AliasSet::PointerRec *&Entry = PointerMap[ASTCallbackVH(V, this)];
  371. if (!Entry)
  372. Entry = new AliasSet::PointerRec(V);
  373. return *Entry;
  374. }
  375. AliasSet &addPointer(MemoryLocation Loc, AliasSet::AccessLattice E);
  376. AliasSet *mergeAliasSetsForPointer(const Value *Ptr, LocationSize Size,
  377. const AAMDNodes &AAInfo,
  378. bool &MustAliasAll);
  379. /// Merge all alias sets into a single set that is considered to alias any
  380. /// pointer.
  381. AliasSet &mergeAllAliasSets();
  382. AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
  383. };
  384. inline raw_ostream& operator<<(raw_ostream &OS, const AliasSetTracker &AST) {
  385. AST.print(OS);
  386. return OS;
  387. }
  388. class AliasSetsPrinterPass : public PassInfoMixin<AliasSetsPrinterPass> {
  389. raw_ostream &OS;
  390. public:
  391. explicit AliasSetsPrinterPass(raw_ostream &OS);
  392. PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
  393. };
  394. } // end namespace llvm
  395. #endif // LLVM_ANALYSIS_ALIASSETTRACKER_H
  396. #ifdef __GNUC__
  397. #pragma GCC diagnostic pop
  398. #endif