1193323Sed//===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file defines the PointerIntPair class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#ifndef LLVM_ADT_POINTERINTPAIR_H
15193323Sed#define LLVM_ADT_POINTERINTPAIR_H
16193323Sed
17193323Sed#include "llvm/Support/PointerLikeTypeTraits.h"
18193323Sed#include <cassert>
19193323Sed
20193323Sednamespace llvm {
21193323Sed
22193323Sedtemplate<typename T>
23193323Sedstruct DenseMapInfo;
24193323Sed
25193323Sed/// PointerIntPair - This class implements a pair of a pointer and small
26193323Sed/// integer.  It is designed to represent this in the space required by one
27193323Sed/// pointer by bitmangling the integer into the low part of the pointer.  This
28193323Sed/// can only be done for small integers: typically up to 3 bits, but it depends
29193323Sed/// on the number of bits available according to PointerLikeTypeTraits for the
30193323Sed/// type.
31193323Sed///
32251662Sdim/// Note that PointerIntPair always puts the IntVal part in the highest bits
33193323Sed/// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
34193323Sed/// the bool into bit #2, not bit #0, which allows the low two bits to be used
35193323Sed/// for something else.  For example, this allows:
36193323Sed///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
37193323Sed/// ... and the two bools will land in different bits.
38193323Sed///
39193323Sedtemplate <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
40193323Sed          typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
41193323Sedclass PointerIntPair {
42193323Sed  intptr_t Value;
43193323Sed  enum {
44193323Sed    /// PointerBitMask - The bits that come from the pointer.
45193323Sed    PointerBitMask =
46193323Sed      ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
47193323Sed
48193323Sed    /// IntShift - The number of low bits that we reserve for other uses, and
49193323Sed    /// keep zero.
50193323Sed    IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
51193323Sed
52193323Sed    /// IntMask - This is the unshifted mask for valid bits of the int type.
53193323Sed    IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
54193323Sed
55193323Sed    // ShiftedIntMask - This is the bits for the integer shifted in place.
56193323Sed    ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
57193323Sed  };
58193323Sedpublic:
59193323Sed  PointerIntPair() : Value(0) {}
60251662Sdim  PointerIntPair(PointerTy PtrVal, IntType IntVal) {
61193323Sed    assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
62193323Sed           "PointerIntPair formed with integer size too large for pointer");
63251662Sdim    setPointerAndInt(PtrVal, IntVal);
64193323Sed  }
65251662Sdim  explicit PointerIntPair(PointerTy PtrVal) {
66251662Sdim    initWithPointer(PtrVal);
67249423Sdim  }
68193323Sed
69193323Sed  PointerTy getPointer() const {
70198090Srdivacky    return PtrTraits::getFromVoidPointer(
71198090Srdivacky                         reinterpret_cast<void*>(Value & PointerBitMask));
72193323Sed  }
73193323Sed
74193323Sed  IntType getInt() const {
75193323Sed    return (IntType)((Value >> IntShift) & IntMask);
76193323Sed  }
77193323Sed
78251662Sdim  void setPointer(PointerTy PtrVal) {
79251662Sdim    intptr_t PtrWord
80251662Sdim      = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
81251662Sdim    assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
82193323Sed           "Pointer is not sufficiently aligned");
83193323Sed    // Preserve all low bits, just update the pointer.
84251662Sdim    Value = PtrWord | (Value & ~PointerBitMask);
85193323Sed  }
86193323Sed
87251662Sdim  void setInt(IntType IntVal) {
88251662Sdim    intptr_t IntWord = static_cast<intptr_t>(IntVal);
89251662Sdim    assert(IntWord < (1 << IntBits) && "Integer too large for field");
90193323Sed
91193323Sed    // Preserve all bits other than the ones we are updating.
92193323Sed    Value &= ~ShiftedIntMask;     // Remove integer field.
93251662Sdim    Value |= IntWord << IntShift;  // Set new integer.
94193323Sed  }
95193323Sed
96251662Sdim  void initWithPointer(PointerTy PtrVal) {
97251662Sdim    intptr_t PtrWord
98251662Sdim      = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
99251662Sdim    assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
100249423Sdim           "Pointer is not sufficiently aligned");
101251662Sdim    Value = PtrWord;
102249423Sdim  }
103249423Sdim
104251662Sdim  void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
105251662Sdim    intptr_t PtrWord
106251662Sdim      = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
107251662Sdim    assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
108249423Sdim           "Pointer is not sufficiently aligned");
109251662Sdim    intptr_t IntWord = static_cast<intptr_t>(IntVal);
110251662Sdim    assert(IntWord < (1 << IntBits) && "Integer too large for field");
111249423Sdim
112251662Sdim    Value = PtrWord | (IntWord << IntShift);
113249423Sdim  }
114249423Sdim
115218893Sdim  PointerTy const *getAddrOfPointer() const {
116234353Sdim    return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
117234353Sdim  }
118234353Sdim
119234353Sdim  PointerTy *getAddrOfPointer() {
120218893Sdim    assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
121218893Sdim           "Can only return the address if IntBits is cleared and "
122218893Sdim           "PtrTraits doesn't change the pointer");
123234353Sdim    return reinterpret_cast<PointerTy *>(&Value);
124218893Sdim  }
125218893Sdim
126193323Sed  void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
127193323Sed  void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
128193323Sed
129193323Sed  static PointerIntPair getFromOpaqueValue(void *V) {
130193323Sed    PointerIntPair P; P.setFromOpaqueValue(V); return P;
131193323Sed  }
132239462Sdim
133239462Sdim  // Allow PointerIntPairs to be created from const void * if and only if the
134239462Sdim  // pointer type could be created from a const void *.
135239462Sdim  static PointerIntPair getFromOpaqueValue(const void *V) {
136239462Sdim    (void)PtrTraits::getFromVoidPointer(V);
137239462Sdim    return getFromOpaqueValue(const_cast<void *>(V));
138239462Sdim  }
139239462Sdim
140193323Sed  bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
141193323Sed  bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
142193323Sed  bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
143193323Sed  bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
144193323Sed  bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
145193323Sed  bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
146193323Sed};
147193323Sed
148200581Srdivackytemplate <typename T> struct isPodLike;
149200581Srdivackytemplate<typename PointerTy, unsigned IntBits, typename IntType>
150200581Srdivackystruct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
151200581Srdivacky   static const bool value = true;
152200581Srdivacky};
153200581Srdivacky
154193323Sed// Provide specialization of DenseMapInfo for PointerIntPair.
155193323Sedtemplate<typename PointerTy, unsigned IntBits, typename IntType>
156193323Sedstruct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
157193323Sed  typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
158193323Sed  static Ty getEmptyKey() {
159243830Sdim    uintptr_t Val = static_cast<uintptr_t>(-1);
160193323Sed    Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
161193323Sed    return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
162193323Sed  }
163193323Sed  static Ty getTombstoneKey() {
164243830Sdim    uintptr_t Val = static_cast<uintptr_t>(-2);
165193323Sed    Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
166193323Sed    return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
167193323Sed  }
168193323Sed  static unsigned getHashValue(Ty V) {
169193323Sed    uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
170193323Sed    return unsigned(IV) ^ unsigned(IV >> 9);
171193323Sed  }
172193323Sed  static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
173193323Sed};
174193323Sed
175193323Sed// Teach SmallPtrSet that PointerIntPair is "basically a pointer".
176193323Sedtemplate<typename PointerTy, unsigned IntBits, typename IntType,
177193323Sed         typename PtrTraits>
178193323Sedclass PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
179193323Sed                                           PtrTraits> > {
180193323Sedpublic:
181193323Sed  static inline void *
182193323Sed  getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
183193323Sed    return P.getOpaqueValue();
184193323Sed  }
185193323Sed  static inline PointerIntPair<PointerTy, IntBits, IntType>
186193323Sed  getFromVoidPointer(void *P) {
187193323Sed    return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
188193323Sed  }
189239462Sdim  static inline PointerIntPair<PointerTy, IntBits, IntType>
190239462Sdim  getFromVoidPointer(const void *P) {
191239462Sdim    return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
192239462Sdim  }
193193323Sed  enum {
194198090Srdivacky    NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits
195193323Sed  };
196193323Sed};
197193323Sed
198193323Sed} // end namespace llvm
199193323Sed#endif
200