LCOV - code coverage report
Current view: top level - include/llvm/ADT - PointerIntPair.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 39 100.0 %
Date: 2017-09-14 15:23:50 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- 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 the PointerIntPair class.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_ADT_POINTERINTPAIR_H
      15             : #define LLVM_ADT_POINTERINTPAIR_H
      16             : 
      17             : #include "llvm/Support/Compiler.h"
      18             : #include "llvm/Support/PointerLikeTypeTraits.h"
      19             : #include <cassert>
      20             : #include <limits>
      21             : 
      22             : namespace llvm {
      23             : 
      24             : template <typename T> struct DenseMapInfo;
      25             : 
      26             : template <typename PointerT, unsigned IntBits, typename PtrTraits>
      27             : struct PointerIntPairInfo;
      28             : 
      29             : /// PointerIntPair - This class implements a pair of a pointer and small
      30             : /// integer.  It is designed to represent this in the space required by one
      31             : /// pointer by bitmangling the integer into the low part of the pointer.  This
      32             : /// can only be done for small integers: typically up to 3 bits, but it depends
      33             : /// on the number of bits available according to PointerLikeTypeTraits for the
      34             : /// type.
      35             : ///
      36             : /// Note that PointerIntPair always puts the IntVal part in the highest bits
      37             : /// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
      38             : /// the bool into bit #2, not bit #0, which allows the low two bits to be used
      39             : /// for something else.  For example, this allows:
      40             : ///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
      41             : /// ... and the two bools will land in different bits.
      42             : ///
      43             : template <typename PointerTy, unsigned IntBits, typename IntType = unsigned,
      44             :           typename PtrTraits = PointerLikeTypeTraits<PointerTy>,
      45             :           typename Info = PointerIntPairInfo<PointerTy, IntBits, PtrTraits>>
      46             : class PointerIntPair {
      47             :   intptr_t Value;
      48             : 
      49             : public:
      50  2682664043 :   PointerIntPair() : Value(0) {}
      51   805113459 :   PointerIntPair(PointerTy PtrVal, IntType IntVal) {
      52  1028751418 :     setPointerAndInt(PtrVal, IntVal);
      53             :   }
      54   500328398 :   explicit PointerIntPair(PointerTy PtrVal) { initWithPointer(PtrVal); }
      55             : 
      56 10004810916 :   PointerTy getPointer() const { return Info::getPointer(Value); }
      57             : 
      58             :   IntType getInt() const {
      59  9289909403 :     return (IntType)Info::getInt(Value);
      60             :   }
      61             : 
      62             :   void setPointer(PointerTy PtrVal) {
      63   277490970 :     Value = Info::updatePointer(Value, PtrVal);
      64             :   }
      65             : 
      66             :   void setInt(IntType IntVal) {
      67   514848336 :     Value = Info::updateInt(Value, static_cast<intptr_t>(IntVal));
      68             :   }
      69             : 
      70             :   void initWithPointer(PointerTy PtrVal) {
      71   338041847 :     Value = Info::updatePointer(0, PtrVal);
      72             :   }
      73             : 
      74             :   void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
      75  2772774183 :     Value = Info::updateInt(Info::updatePointer(0, PtrVal),
      76             :                             static_cast<intptr_t>(IntVal));
      77             :   }
      78             : 
      79             :   PointerTy const *getAddrOfPointer() const {
      80             :     return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
      81             :   }
      82             : 
      83             :   PointerTy *getAddrOfPointer() {
      84             :     assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
      85             :            "Can only return the address if IntBits is cleared and "
      86             :            "PtrTraits doesn't change the pointer");
      87     6981166 :     return reinterpret_cast<PointerTy *>(&Value);
      88             :   }
      89             : 
      90   616008710 :   void *getOpaqueValue() const { return reinterpret_cast<void *>(Value); }
      91             :   void setFromOpaqueValue(void *Val) {
      92  1182853768 :     Value = reinterpret_cast<intptr_t>(Val);
      93             :   }
      94             : 
      95             :   static PointerIntPair getFromOpaqueValue(void *V) {
      96   752066657 :     PointerIntPair P;
      97   752066657 :     P.setFromOpaqueValue(V);
      98             :     return P;
      99             :   }
     100             : 
     101             :   // Allow PointerIntPairs to be created from const void * if and only if the
     102             :   // pointer type could be created from a const void *.
     103             :   static PointerIntPair getFromOpaqueValue(const void *V) {
     104        1606 :     (void)PtrTraits::getFromVoidPointer(V);
     105        1606 :     return getFromOpaqueValue(const_cast<void *>(V));
     106             :   }
     107             : 
     108             :   bool operator==(const PointerIntPair &RHS) const {
     109    84018188 :     return Value == RHS.Value;
     110             :   }
     111             :   bool operator!=(const PointerIntPair &RHS) const {
     112   109072925 :     return Value != RHS.Value;
     113             :   }
     114       62524 :   bool operator<(const PointerIntPair &RHS) const { return Value < RHS.Value; }
     115             :   bool operator>(const PointerIntPair &RHS) const { return Value > RHS.Value; }
     116             :   bool operator<=(const PointerIntPair &RHS) const {
     117             :     return Value <= RHS.Value;
     118             :   }
     119             :   bool operator>=(const PointerIntPair &RHS) const {
     120             :     return Value >= RHS.Value;
     121             :   }
     122             : };
     123             : 
     124             : template <typename PointerT, unsigned IntBits, typename PtrTraits>
     125             : struct PointerIntPairInfo {
     126             :   static_assert(PtrTraits::NumLowBitsAvailable <
     127             :                     std::numeric_limits<uintptr_t>::digits,
     128             :                 "cannot use a pointer type that has all bits free");
     129             :   static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
     130             :                 "PointerIntPair with integer size too large for pointer");
     131             :   enum : uintptr_t {
     132             :     /// PointerBitMask - The bits that come from the pointer.
     133             :     PointerBitMask =
     134             :         ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1),
     135             : 
     136             :     /// IntShift - The number of low bits that we reserve for other uses, and
     137             :     /// keep zero.
     138             :     IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits,
     139             : 
     140             :     /// IntMask - This is the unshifted mask for valid bits of the int type.
     141             :     IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1),
     142             : 
     143             :     // ShiftedIntMask - This is the bits for the integer shifted in place.
     144             :     ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
     145             :   };
     146             : 
     147             :   static PointerT getPointer(intptr_t Value) {
     148  5002977881 :     return PtrTraits::getFromVoidPointer(
     149  9527874758 :         reinterpret_cast<void *>(Value & PointerBitMask));
     150             :   }
     151             : 
     152             :   static intptr_t getInt(intptr_t Value) {
     153  4506314438 :     return (Value >> IntShift) & IntMask;
     154             :   }
     155             : 
     156             :   static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr) {
     157  1401045393 :     intptr_t PtrWord =
     158  1401045392 :         reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
     159             :     assert((PtrWord & ~PointerBitMask) == 0 &&
     160             :            "Pointer is not sufficiently aligned");
     161             :     // Preserve all low bits, just update the pointer.
     162   694788367 :     return PtrWord | (OrigValue & ~PointerBitMask);
     163             :   }
     164             : 
     165             :   static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) {
     166  1181682229 :     intptr_t IntWord = static_cast<intptr_t>(Int);
     167             :     assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
     168             : 
     169             :     // Preserve all bits other than the ones we are updating.
     170   811291812 :     return (OrigValue & ~ShiftedIntMask) | IntWord << IntShift;
     171             :   }
     172             : };
     173             : 
     174             : template <typename T> struct isPodLike;
     175             : template <typename PointerTy, unsigned IntBits, typename IntType>
     176             : struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType>> {
     177             :   static const bool value = true;
     178             : };
     179             : 
     180             : // Provide specialization of DenseMapInfo for PointerIntPair.
     181             : template <typename PointerTy, unsigned IntBits, typename IntType>
     182             : struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>> {
     183             :   typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
     184             :   static Ty getEmptyKey() {
     185      865060 :     uintptr_t Val = static_cast<uintptr_t>(-1);
     186      865060 :     Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
     187     1730120 :     return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
     188             :   }
     189             :   static Ty getTombstoneKey() {
     190      671296 :     uintptr_t Val = static_cast<uintptr_t>(-2);
     191      671296 :     Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
     192     1342592 :     return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
     193             :   }
     194             :   static unsigned getHashValue(Ty V) {
     195      578024 :     uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
     196      578024 :     return unsigned(IV) ^ unsigned(IV >> 9);
     197             :   }
     198     2747438 :   static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
     199             : };
     200             : 
     201             : // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
     202             : template <typename PointerTy, unsigned IntBits, typename IntType,
     203             :           typename PtrTraits>
     204             : struct PointerLikeTypeTraits<
     205             :     PointerIntPair<PointerTy, IntBits, IntType, PtrTraits>> {
     206             :   static inline void *
     207             :   getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
     208      708111 :     return P.getOpaqueValue();
     209             :   }
     210             :   static inline PointerIntPair<PointerTy, IntBits, IntType>
     211             :   getFromVoidPointer(void *P) {
     212     1596065 :     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
     213             :   }
     214             :   static inline PointerIntPair<PointerTy, IntBits, IntType>
     215             :   getFromVoidPointer(const void *P) {
     216             :     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
     217             :   }
     218             :   enum { NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits };
     219             : };
     220             : 
     221             : } // end namespace llvm
     222             : #endif

Generated by: LCOV version 1.13