Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

437 lines
15 KiB

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