LCOV - code coverage report
Current view: top level - include/llvm/IR - Use.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 12 17 70.6 %
Date: 2018-10-20 13:21:21 Functions: 0 5 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/Use.h - Definition of the Use class -----------------*- 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             : ///
      11             : /// This defines the Use class.  The Use class represents the operand of an
      12             : /// instruction or some other User instance which refers to a Value.  The Use
      13             : /// class keeps the "use list" of the referenced value up to date.
      14             : ///
      15             : /// Pointer tagging is used to efficiently find the User corresponding to a Use
      16             : /// without having to store a User pointer in every Use. A User is preceded in
      17             : /// memory by all the Uses corresponding to its operands, and the low bits of
      18             : /// one of the fields (Prev) of the Use class are used to encode offsets to be
      19             : /// able to find that User given a pointer to any Use. For details, see:
      20             : ///
      21             : ///   http://www.llvm.org/docs/ProgrammersManual.html#UserLayout
      22             : ///
      23             : //===----------------------------------------------------------------------===//
      24             : 
      25             : #ifndef LLVM_IR_USE_H
      26             : #define LLVM_IR_USE_H
      27             : 
      28             : #include "llvm-c/Types.h"
      29             : #include "llvm/ADT/PointerIntPair.h"
      30             : #include "llvm/Support/CBindingWrapping.h"
      31             : #include "llvm/Support/Compiler.h"
      32             : 
      33             : namespace llvm {
      34             : 
      35             : template <typename> struct simplify_type;
      36             : class User;
      37             : class Value;
      38             : 
      39             : /// A Use represents the edge between a Value definition and its users.
      40             : ///
      41             : /// This is notionally a two-dimensional linked list. It supports traversing
      42             : /// all of the uses for a particular value definition. It also supports jumping
      43             : /// directly to the used value when we arrive from the User's operands, and
      44             : /// jumping directly to the User when we arrive from the Value's uses.
      45             : ///
      46             : /// The pointer to the used Value is explicit, and the pointer to the User is
      47             : /// implicit. The implicit pointer is found via a waymarking algorithm
      48             : /// described in the programmer's manual:
      49             : ///
      50             : ///   http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
      51             : ///
      52             : /// This is essentially the single most memory intensive object in LLVM because
      53             : /// of the number of uses in the system. At the same time, the constant time
      54             : /// operations it allows are essential to many optimizations having reasonable
      55             : /// time complexity.
      56             : class Use {
      57             : public:
      58             :   Use(const Use &U) = delete;
      59             : 
      60             :   /// Provide a fast substitute to std::swap<Use>
      61             :   /// that also works with less standard-compliant compilers
      62             :   void swap(Use &RHS);
      63             : 
      64             :   /// Pointer traits for the UserRef PointerIntPair. This ensures we always
      65             :   /// use the LSB regardless of pointer alignment on different targets.
      66             :   struct UserRefPointerTraits {
      67             :     static inline void *getAsVoidPointer(User *P) { return P; }
      68             : 
      69             :     static inline User *getFromVoidPointer(void *P) {
      70             :       return (User *)P;
      71             :     }
      72             : 
      73             :     enum { NumLowBitsAvailable = 1 };
      74             :   };
      75             : 
      76             :   // A type for the word following an array of hung-off Uses in memory, which is
      77             :   // a pointer back to their User with the bottom bit set.
      78             :   using UserRef = PointerIntPair<User *, 1, unsigned, UserRefPointerTraits>;
      79             : 
      80             :   /// Pointer traits for the Prev PointerIntPair. This ensures we always use
      81             :   /// the two LSBs regardless of pointer alignment on different targets.
      82             :   struct PrevPointerTraits {
      83             :     static inline void *getAsVoidPointer(Use **P) { return P; }
      84             : 
      85             :     static inline Use **getFromVoidPointer(void *P) {
      86             :       return (Use **)P;
      87             :     }
      88             : 
      89             :     enum { NumLowBitsAvailable = 2 };
      90             :   };
      91             : 
      92             : private:
      93             :   /// Destructor - Only for zap()
      94    53562297 :   ~Use() {
      95    53562297 :     if (Val)
      96             :       removeFromList();
      97             :   }
      98             : 
      99             :   enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag };
     100             : 
     101             :   /// Constructor
     102   116353697 :   Use(PrevPtrTag tag) { Prev.setInt(tag); }
     103             : 
     104             : public:
     105             :   friend class Value;
     106             : 
     107           0 :   operator Value *() const { return Val; }
     108           0 :   Value *get() const { return Val; }
     109             : 
     110             :   /// Returns the User that contains this Use.
     111             :   ///
     112             :   /// For an instruction operand, for example, this will return the
     113             :   /// instruction.
     114             :   User *getUser() const LLVM_READONLY;
     115             : 
     116             :   inline void set(Value *Val);
     117             : 
     118             :   inline Value *operator=(Value *RHS);
     119             :   inline const Use &operator=(const Use &RHS);
     120             : 
     121           0 :   Value *operator->() { return Val; }
     122           0 :   const Value *operator->() const { return Val; }
     123             : 
     124           0 :   Use *getNext() const { return Next; }
     125             : 
     126             :   /// Return the operand # of this use in its User.
     127             :   unsigned getOperandNo() const;
     128             : 
     129             :   /// Initializes the waymarking tags on an array of Uses.
     130             :   ///
     131             :   /// This sets up the array of Uses such that getUser() can find the User from
     132             :   /// any of those Uses.
     133             :   static Use *initTags(Use *Start, Use *Stop);
     134             : 
     135             :   /// Destroys Use operands when the number of operands of
     136             :   /// a User changes.
     137             :   static void zap(Use *Start, const Use *Stop, bool del = false);
     138             : 
     139             : private:
     140             :   const Use *getImpliedUser() const LLVM_READONLY;
     141             : 
     142             :   Value *Val = nullptr;
     143             :   Use *Next;
     144             :   PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev;
     145             : 
     146             :   void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); }
     147             : 
     148             :   void addToList(Use **List) {
     149   185101318 :     Next = *List;
     150   185101318 :     if (Next)
     151   129892530 :       Next->setPrev(&Next);
     152             :     setPrev(List);
     153   185101318 :     *List = this;
     154             :   }
     155             : 
     156             :   void removeFromList() {
     157   122792932 :     Use **StrippedPrev = Prev.getPointer();
     158   122792932 :     *StrippedPrev = Next;
     159   122792932 :     if (Next)
     160             :       Next->setPrev(StrippedPrev);
     161             :   }
     162             : };
     163             : 
     164             : /// Allow clients to treat uses just like values when using
     165             : /// casting operators.
     166             : template <> struct simplify_type<Use> {
     167             :   using SimpleType = Value *;
     168             : 
     169       14169 :   static SimpleType getSimplifiedValue(Use &Val) { return Val.get(); }
     170             : };
     171             : template <> struct simplify_type<const Use> {
     172             :   using SimpleType = /*const*/ Value *;
     173             : 
     174   531149902 :   static SimpleType getSimplifiedValue(const Use &Val) { return Val.get(); }
     175             : };
     176             : 
     177             : // Create wrappers for C Binding types (see CBindingWrapping.h).
     178             : DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Use, LLVMUseRef)
     179             : 
     180             : } // end namespace llvm
     181             : 
     182             : #endif // LLVM_IR_USE_H

Generated by: LCOV version 1.13