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.

285 lines
9.5 KiB

  1. //===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- 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. /// \file
  10. /// This file provides a collection of visitors which walk the (instruction)
  11. /// uses of a pointer. These visitors all provide the same essential behavior
  12. /// as an InstVisitor with similar template-based flexibility and
  13. /// implementation strategies.
  14. ///
  15. /// These can be used, for example, to quickly analyze the uses of an alloca,
  16. /// global variable, or function argument.
  17. ///
  18. /// FIXME: Provide a variant which doesn't track offsets and is cheaper.
  19. ///
  20. //===----------------------------------------------------------------------===//
  21. #ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H
  22. #define LLVM_ANALYSIS_PTRUSEVISITOR_H
  23. #include "llvm/ADT/APInt.h"
  24. #include "llvm/ADT/SmallPtrSet.h"
  25. #include "llvm/ADT/SmallVector.h"
  26. #include "llvm/IR/DataLayout.h"
  27. #include "llvm/IR/IntrinsicInst.h"
  28. #include "llvm/InstVisitor.h"
  29. #include "llvm/Support/Compiler.h"
  30. namespace llvm {
  31. namespace detail {
  32. /// \brief Implementation of non-dependent functionality for \c PtrUseVisitor.
  33. ///
  34. /// See \c PtrUseVisitor for the public interface and detailed comments about
  35. /// usage. This class is just a helper base class which is not templated and
  36. /// contains all common code to be shared between different instantiations of
  37. /// PtrUseVisitor.
  38. class PtrUseVisitorBase {
  39. public:
  40. /// \brief This class provides information about the result of a visit.
  41. ///
  42. /// After walking all the users (recursively) of a pointer, the basic
  43. /// infrastructure records some commonly useful information such as escape
  44. /// analysis and whether the visit completed or aborted early.
  45. class PtrInfo {
  46. public:
  47. PtrInfo() : AbortedInfo(0, false), EscapedInfo(0, false) {}
  48. /// \brief Reset the pointer info, clearing all state.
  49. void reset() {
  50. AbortedInfo.setPointer(0);
  51. AbortedInfo.setInt(false);
  52. EscapedInfo.setPointer(0);
  53. EscapedInfo.setInt(false);
  54. }
  55. /// \brief Did we abort the visit early?
  56. bool isAborted() const { return AbortedInfo.getInt(); }
  57. /// \brief Is the pointer escaped at some point?
  58. bool isEscaped() const { return EscapedInfo.getInt(); }
  59. /// \brief Get the instruction causing the visit to abort.
  60. /// \returns a pointer to the instruction causing the abort if one is
  61. /// available; otherwise returns null.
  62. Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); }
  63. /// \brief Get the instruction causing the pointer to escape.
  64. /// \returns a pointer to the instruction which escapes the pointer if one
  65. /// is available; otherwise returns null.
  66. Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); }
  67. /// \brief Mark the visit as aborted. Intended for use in a void return.
  68. /// \param I The instruction which caused the visit to abort, if available.
  69. void setAborted(Instruction *I = 0) {
  70. AbortedInfo.setInt(true);
  71. AbortedInfo.setPointer(I);
  72. }
  73. /// \brief Mark the pointer as escaped. Intended for use in a void return.
  74. /// \param I The instruction which escapes the pointer, if available.
  75. void setEscaped(Instruction *I = 0) {
  76. EscapedInfo.setInt(true);
  77. EscapedInfo.setPointer(I);
  78. }
  79. /// \brief Mark the pointer as escaped, and the visit as aborted. Intended
  80. /// for use in a void return.
  81. /// \param I The instruction which both escapes the pointer and aborts the
  82. /// visit, if available.
  83. void setEscapedAndAborted(Instruction *I = 0) {
  84. setEscaped(I);
  85. setAborted(I);
  86. }
  87. private:
  88. PointerIntPair<Instruction *, 1, bool> AbortedInfo, EscapedInfo;
  89. };
  90. protected:
  91. const DataLayout &DL;
  92. /// \name Visitation infrastructure
  93. /// @{
  94. /// \brief The info collected about the pointer being visited thus far.
  95. PtrInfo PI;
  96. /// \brief A struct of the data needed to visit a particular use.
  97. ///
  98. /// This is used to maintain a worklist fo to-visit uses. This is used to
  99. /// make the visit be iterative rather than recursive.
  100. struct UseToVisit {
  101. typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair;
  102. UseAndIsOffsetKnownPair UseAndIsOffsetKnown;
  103. APInt Offset;
  104. };
  105. /// \brief The worklist of to-visit uses.
  106. SmallVector<UseToVisit, 8> Worklist;
  107. /// \brief A set of visited uses to break cycles in unreachable code.
  108. SmallPtrSet<Use *, 8> VisitedUses;
  109. /// @}
  110. /// \name Per-visit state
  111. /// This state is reset for each instruction visited.
  112. /// @{
  113. /// \brief The use currently being visited.
  114. Use *U;
  115. /// \brief True if we have a known constant offset for the use currently
  116. /// being visited.
  117. bool IsOffsetKnown;
  118. /// \brief The constant offset of the use if that is known.
  119. APInt Offset;
  120. /// @}
  121. /// Note that the constructor is protected because this class must be a base
  122. /// class, we can't create instances directly of this class.
  123. PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {}
  124. /// \brief Enqueue the users of this instruction in the visit worklist.
  125. ///
  126. /// This will visit the users with the same offset of the current visit
  127. /// (including an unknown offset if that is the current state).
  128. void enqueueUsers(Instruction &I);
  129. /// \brief Walk the operands of a GEP and adjust the offset as appropriate.
  130. ///
  131. /// This routine does the heavy lifting of the pointer walk by computing
  132. /// offsets and looking through GEPs.
  133. bool adjustOffsetForGEP(GetElementPtrInst &GEPI);
  134. };
  135. } // end namespace detail
  136. /// \brief A base class for visitors over the uses of a pointer value.
  137. ///
  138. /// Once constructed, a user can call \c visit on a pointer value, and this
  139. /// will walk its uses and visit each instruction using an InstVisitor. It also
  140. /// provides visit methods which will recurse through any pointer-to-pointer
  141. /// transformations such as GEPs and bitcasts.
  142. ///
  143. /// During the visit, the current Use* being visited is available to the
  144. /// subclass, as well as the current offset from the original base pointer if
  145. /// known.
  146. ///
  147. /// The recursive visit of uses is accomplished with a worklist, so the only
  148. /// ordering guarantee is that an instruction is visited before any uses of it
  149. /// are visited. Note that this does *not* mean before any of its users are
  150. /// visited! This is because users can be visited multiple times due to
  151. /// multiple, different uses of pointers derived from the same base.
  152. ///
  153. /// A particular Use will only be visited once, but a User may be visited
  154. /// multiple times, once per Use. This visits may notably have different
  155. /// offsets.
  156. ///
  157. /// All visit methods on the underlying InstVisitor return a boolean. This
  158. /// return short-circuits the visit, stopping it immediately.
  159. ///
  160. /// FIXME: Generalize this for all values rather than just instructions.
  161. template <typename DerivedT>
  162. class PtrUseVisitor : protected InstVisitor<DerivedT>,
  163. public detail::PtrUseVisitorBase {
  164. friend class InstVisitor<DerivedT>;
  165. typedef InstVisitor<DerivedT> Base;
  166. public:
  167. PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {}
  168. /// \brief Recursively visit the uses of the given pointer.
  169. /// \returns An info struct about the pointer. See \c PtrInfo for details.
  170. PtrInfo visitPtr(Instruction &I) {
  171. // This must be a pointer type. Get an integer type suitable to hold
  172. // offsets on this pointer.
  173. // FIXME: Support a vector of pointers.
  174. assert(I.getType()->isPointerTy());
  175. IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(I.getType()));
  176. IsOffsetKnown = true;
  177. Offset = APInt(IntPtrTy->getBitWidth(), 0);
  178. PI.reset();
  179. // Enqueue the uses of this pointer.
  180. enqueueUsers(I);
  181. // Visit all the uses off the worklist until it is empty.
  182. while (!Worklist.empty()) {
  183. UseToVisit ToVisit = Worklist.pop_back_val();
  184. U = ToVisit.UseAndIsOffsetKnown.getPointer();
  185. IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt();
  186. if (IsOffsetKnown)
  187. Offset = llvm_move(ToVisit.Offset);
  188. Instruction *I = cast<Instruction>(U->getUser());
  189. static_cast<DerivedT*>(this)->visit(I);
  190. if (PI.isAborted())
  191. break;
  192. }
  193. return PI;
  194. }
  195. protected:
  196. void visitStoreInst(StoreInst &SI) {
  197. if (SI.getValueOperand() == U->get())
  198. PI.setEscaped(&SI);
  199. }
  200. void visitBitCastInst(BitCastInst &BC) {
  201. enqueueUsers(BC);
  202. }
  203. void visitPtrToIntInst(PtrToIntInst &I) {
  204. PI.setEscaped(&I);
  205. }
  206. void visitGetElementPtrInst(GetElementPtrInst &GEPI) {
  207. if (GEPI.use_empty())
  208. return;
  209. // If we can't walk the GEP, clear the offset.
  210. if (!adjustOffsetForGEP(GEPI)) {
  211. IsOffsetKnown = false;
  212. Offset = APInt();
  213. }
  214. // Enqueue the users now that the offset has been adjusted.
  215. enqueueUsers(GEPI);
  216. }
  217. // No-op intrinsics which we know don't escape the pointer to to logic in
  218. // some other function.
  219. void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {}
  220. void visitMemIntrinsic(MemIntrinsic &I) {}
  221. void visitIntrinsicInst(IntrinsicInst &II) {
  222. switch (II.getIntrinsicID()) {
  223. default:
  224. return Base::visitIntrinsicInst(II);
  225. case Intrinsic::lifetime_start:
  226. case Intrinsic::lifetime_end:
  227. return; // No-op intrinsics.
  228. }
  229. }
  230. // Generically, arguments to calls and invokes escape the pointer to some
  231. // other function. Mark that.
  232. void visitCallSite(CallSite CS) {
  233. PI.setEscaped(CS.getInstruction());
  234. Base::visitCallSite(CS);
  235. }
  236. };
  237. }
  238. #endif