Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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