ccdcd1a8d1b949c5f1698d4a74b0288f28420e84
[oota-llvm.git] / include / llvm / ADT / PointerIntPair.h
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/PointerLikeTypeTraits.h"
18 #include <cassert>
19
20 namespace llvm {
21
22 template<typename T>
23 struct DenseMapInfo;
24
25 /// PointerIntPair - This class implements a pair of a pointer and small
26 /// integer.  It is designed to represent this in the space required by one
27 /// pointer by bitmangling the integer into the low part of the pointer.  This
28 /// can only be done for small integers: typically up to 3 bits, but it depends
29 /// on the number of bits available according to PointerLikeTypeTraits for the
30 /// type.
31 ///
32 /// Note that PointerIntPair always puts the Int part in the highest bits
33 /// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
34 /// the bool into bit #2, not bit #0, which allows the low two bits to be used
35 /// for something else.  For example, this allows:
36 ///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
37 /// ... and the two bools will land in different bits.
38 ///
39 template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
40           typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
41 class PointerIntPair {
42   intptr_t Value;
43   enum {
44     /// PointerBitMask - The bits that come from the pointer.
45     PointerBitMask =
46       ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
47
48     /// IntShift - The number of low bits that we reserve for other uses, and
49     /// keep zero.
50     IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
51     
52     /// IntMask - This is the unshifted mask for valid bits of the int type.
53     IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
54     
55     // ShiftedIntMask - This is the bits for the integer shifted in place.
56     ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
57   };
58 public:
59   PointerIntPair() : Value(0) {}
60   PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
61     assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
62            "PointerIntPair formed with integer size too large for pointer");
63     setPointer(Ptr);
64     setInt(Int);
65   }
66
67   PointerTy getPointer() const {
68     return PtrTraits::getFromVoidPointer(
69                          reinterpret_cast<void*>(Value & PointerBitMask));
70   }
71
72   IntType getInt() const {
73     return (IntType)((Value >> IntShift) & IntMask);
74   }
75
76   void setPointer(PointerTy Ptr) {
77     intptr_t PtrVal
78       = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
79     assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
80            "Pointer is not sufficiently aligned");
81     // Preserve all low bits, just update the pointer.
82     Value = PtrVal | (Value & ~PointerBitMask);
83   }
84
85   void setInt(IntType Int) {
86     intptr_t IntVal = Int;
87     assert(IntVal < (1 << IntBits) && "Integer too large for field");
88     
89     // Preserve all bits other than the ones we are updating.
90     Value &= ~ShiftedIntMask;     // Remove integer field.
91     Value |= IntVal << IntShift;  // Set new integer.
92   }
93
94   PointerTy const *getAddrOfPointer() const {
95     return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
96   }
97
98   PointerTy *getAddrOfPointer() {
99     assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
100            "Can only return the address if IntBits is cleared and "
101            "PtrTraits doesn't change the pointer");
102     return reinterpret_cast<PointerTy *>(&Value);
103   }
104
105   void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
106   void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
107
108   static PointerIntPair getFromOpaqueValue(void *V) {
109     PointerIntPair P; P.setFromOpaqueValue(V); return P; 
110   }
111   
112   bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
113   bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
114   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 {return Value <= RHS.Value;}
117   bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
118 };
119
120 template <typename T> struct isPodLike;
121 template<typename PointerTy, unsigned IntBits, typename IntType>
122 struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
123    static const bool value = true;
124 };
125   
126 // Provide specialization of DenseMapInfo for PointerIntPair.
127 template<typename PointerTy, unsigned IntBits, typename IntType>
128 struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
129   typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
130   static Ty getEmptyKey() {
131     intptr_t Val = -1;
132     Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
133     return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
134   }
135   static Ty getTombstoneKey() {
136     intptr_t Val = -2;
137     Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
138     return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
139   }
140   static unsigned getHashValue(Ty V) {
141     uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
142     return unsigned(IV) ^ unsigned(IV >> 9);
143   }
144   static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
145 };
146
147 // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
148 template<typename PointerTy, unsigned IntBits, typename IntType,
149          typename PtrTraits>
150 class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
151                                            PtrTraits> > {
152 public:
153   static inline void *
154   getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
155     return P.getOpaqueValue();
156   }
157   static inline PointerIntPair<PointerTy, IntBits, IntType>
158   getFromVoidPointer(void *P) {
159     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
160   }
161   enum {
162     NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits
163   };
164 };
165
166 } // end namespace llvm
167 #endif