teach SmallPtrSet that PointerIntPair is "basically a pointer".
[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/DataTypes.h"
18 #include <cassert>
19
20 namespace llvm {
21
22 template<typename T>
23 struct DenseMapInfo;
24 template<typename>
25 class PointerLikeTypeInfo;
26
27 /// PointerIntPair - This class implements a pair of a pointer and small
28 /// integer.  It is designed to represent this in the space required by one
29 /// pointer by bitmangling the integer into the low part of the pointer.  This
30 /// can only be done for small integers: typically up to 3 bits, but it depends
31 /// on the alignment returned by the allocator in use.
32 ///
33 template <typename PointerTy, unsigned IntBits, typename IntType=unsigned>
34 class PointerIntPair {
35   intptr_t Value;
36 public:
37   PointerIntPair() : Value(0) {}
38   PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
39     setPointer(Ptr);
40     setInt(Int);
41   }
42
43   PointerTy getPointer() const {
44     return reinterpret_cast<PointerTy>(Value & ~((1 << IntBits)-1));
45   }
46
47   IntType getInt() const {
48     return (IntType)(Value & ((1 << IntBits)-1));
49   }
50
51   void setPointer(PointerTy Ptr) {
52     intptr_t PtrVal = reinterpret_cast<intptr_t>(Ptr);
53     assert((PtrVal & ((1 << IntBits)-1)) == 0 &&
54            "Pointer is not sufficiently aligned");
55     Value = PtrVal | (intptr_t)getInt();
56   }
57
58   void setInt(IntType Int) {
59     intptr_t IntVal = Int;
60     assert(IntVal < (1 << IntBits) && "Integer too large for field");
61     Value = reinterpret_cast<intptr_t>(getPointer()) | IntVal;
62   }
63
64   void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
65   void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
66
67   static PointerIntPair getFromOpaqueValue(void *V) {
68     PointerIntPair P; P.setFromOpaqueValue(V); return P; 
69   }
70   
71   bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
72   bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
73   bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
74   bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
75   bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
76   bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
77 };
78
79 // Provide specialization of DenseMapInfo for PointerIntPair.
80 template<typename PointerTy, unsigned IntBits, typename IntType>
81 struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
82   typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
83   static Ty getEmptyKey() {
84     return Ty(reinterpret_cast<PointerTy>(-1 << IntBits),
85               IntType((1 << IntBits)-1));
86   }
87   static Ty getTombstoneKey() {
88     return Ty(reinterpret_cast<PointerTy>(-2 << IntBits), IntType(0));
89   }
90   static unsigned getHashValue(Ty V) {
91     uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
92     return unsigned(IV) ^ unsigned(IV >> 9);
93   }
94   static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
95   static bool isPod() { return true; }
96 };
97
98 // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
99 template<typename PointerTy, unsigned IntBits, typename IntType>
100 class PointerLikeTypeInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
101 public:
102   static inline void *
103   getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
104     return P.getOpaqueValue();
105   }
106   static inline PointerIntPair<PointerTy, IntBits, IntType>
107   getFromVoidPointer(void *P) {
108     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
109   }
110 };
111
112 } // end namespace llvm
113 #endif