llvm.org GIT mirror llvm / e30173a
Replace the PointerLikeTypeTraits::getNumLowBitsAvailable function with a new NumLowBitsAvailable enum, which makes the value available as an integer constant expression. Add PointerLikeTypeTraits specializations for Instruction* and Use** since they are only guaranteed 4-byte aligned. Enhance PointerIntPair to know about (and enforce) the alignment specified by PointerLikeTypeTraits. This should allow things like PointerIntPair<PointerIntPair<void*, 1,bool>, 1, bool> because the inner one knows that 2 low bits are free. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67979 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
4 changed file(s) with 65 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
1414 #define LLVM_ADT_POINTERINTPAIR_H
1515
1616 #include "llvm/Support/DataTypes.h"
17 #include "llvm/Support/PointerLikeTypeTraits.h"
1718 #include
1819
1920 namespace llvm {
2021
2122 template
2223 struct DenseMapInfo;
23 template
24 class PointerLikeTypeTraits;
2524
2625 /// PointerIntPair - This class implements a pair of a pointer and small
2726 /// integer. It is designed to represent this in the space required by one
2827 /// pointer by bitmangling the integer into the low part of the pointer. This
2928 /// can only be done for small integers: typically up to 3 bits, but it depends
30 /// on the alignment returned by the allocator in use.
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 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, 1, bool>
37 /// ... and the two bools will land in different bits.
3138 ///
3239 template
3340 class PointerIntPair {
3441 intptr_t Value;
42 typedef PointerLikeTypeTraits PtrTraits;
43 enum {
44 /// PointerBitMask - The bits that come from the pointer.
45 PointerBitMask = ~(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
46 /// IntShift - The number of low bits that we reserve for other uses, and
47 /// keep zero.
48 IntShift = PtrTraits::NumLowBitsAvailable-IntBits,
49
50 /// IntMask - This is the unshifted mask for valid bits of the int type.
51 IntMask = ((intptr_t)1 << IntBits)-1,
52
53 // ShiftedIntMask - This is the bits for the integer shifted in place.
54 ShiftedIntMask = IntMask << IntShift
55 };
3556 public:
3657 PointerIntPair() : Value(0) {}
3758 PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
59 assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
60 "PointerIntPair formed with integer size too large for pointer");
3861 setPointer(Ptr);
3962 setInt(Int);
4063 }
4164
4265 PointerTy getPointer() const {
43 return reinterpret_cast(Value & ~((1 << IntBits)-1));
66 return reinterpret_cast(Value & PointerBitMask);
4467 }
4568
4669 IntType getInt() const {
47 return (IntType)(Value & ((1 << IntBits)-1));
70 return (IntType)((Value >> IntShift) & IntMask);
4871 }
4972
5073 void setPointer(PointerTy Ptr) {
5174 intptr_t PtrVal = reinterpret_cast(Ptr);
52 assert((PtrVal & ((1 << IntBits)-1)) == 0 &&
75 assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
5376 "Pointer is not sufficiently aligned");
54 Value = PtrVal | (intptr_t)getInt();
77 // Preserve all low bits, just update the pointer.
78 Value = PtrVal | (Value & ~PointerBitMask);
5579 }
5680
5781 void setInt(IntType Int) {
5882 intptr_t IntVal = Int;
5983 assert(IntVal < (1 << IntBits) && "Integer too large for field");
60 Value = reinterpret_cast(getPointer()) | IntVal;
84
85 // Preserve all bits other than the ones we are updating.
86 Value &= ~ShiftedIntMask; // Remove integer field.
87 Value |= IntVal << IntShift; // Set new integer.
6188 }
6289
6390 void *getOpaqueValue() const { return reinterpret_cast(Value); }
106133 getFromVoidPointer(void *P) {
107134 return PointerIntPair::getFromOpaqueValue(P);
108135 }
109 static inline unsigned getNumLowBitsAvailable() { return 0; }
136 enum {
137 NumLowBitsAvailable =
138 PointerLikeTypeTraits::NumLowBitsAvailable - IntBits
139 };
110140 };
111141
112142 } // end namespace llvm
226226 };
227227 };
228228
229 // Instruction* is only 4-byte aligned.
230 template<>
231 class PointerLikeTypeTraits {
232 typedef Instruction* PT;
233 public:
234 static inline void *getAsVoidPointer(PT P) { return P; }
235 static inline PT getFromVoidPointer(void *P) {
236 return static_cast(P);
237 }
238 enum { NumLowBitsAvailable = 2 };
239 };
240
229241 } // End llvm namespace
230242
231243 #endif
4141 ///
4242 /// All clients should use assertions to do a run-time check to ensure that
4343 /// this is actually true.
44 static inline unsigned getNumLowBitsAvailable() { return 3; }
44 enum { NumLowBitsAvailable = 3 };
4545 };
4646
4747 // Provide PointerLikeTypeTraits for const pointers.
5252 static inline const T *getFromVoidPointer(const void *P) {
5353 return static_cast(P);
5454 }
55 static inline unsigned getNumLowBitsAvailable() { return 3; }
55 enum { NumLowBitsAvailable = 3 };
5656 };
5757
5858 } // end namespace llvm
2323
2424 class Value;
2525 class User;
26
26 class Use;
2727
2828 /// Tag - generic tag type for (at least 32 bit) pointers
2929 enum Tag { noTag, tagOne, tagTwo, tagThree };
3030
31 // Use** is only 4-byte aligned.
32 template<>
33 class PointerLikeTypeTraits {
34 public:
35 static inline void *getAsVoidPointer(Use** P) { return P; }
36 static inline Use **getFromVoidPointer(void *P) {
37 return static_cast(P);
38 }
39 enum { NumLowBitsAvailable = 2 };
40 };
3141
3242 //===----------------------------------------------------------------------===//
3343 // Use Class
211221
212222 template<> struct simplify_type >
213223 : public simplify_type > {};
214
224
215225 } // End llvm namespace
216226
217227 #endif