@@ -25,80 +25,20 @@ namespace CodeGen {
25
25
// Indicates whether a pointer is known not to be null.
26
26
enum KnownNonNull_t { NotKnownNonNull, KnownNonNull };
27
27
28
- // We try to save some space by using 6 bits over two PointerIntPairs to store
29
- // the alignment. However, some arches don't support 3 bits in a PointerIntPair
30
- // so we fallback to storing the alignment separately.
31
- template <typename T, bool = alignof (llvm::Value *) >= 8 > class AddressImpl {};
32
-
33
- template <typename T> class AddressImpl <T, false > {
28
+ // / An aligned address.
29
+ class Address {
34
30
llvm::PointerIntPair<llvm::Value *, 1 , bool > PointerAndKnownNonNull;
35
31
llvm::Type *ElementType;
36
32
CharUnits Alignment;
37
33
38
- public:
39
- AddressImpl (llvm::Value *Pointer, llvm::Type *ElementType,
40
- CharUnits Alignment, KnownNonNull_t IsKnownNonNull)
41
- : PointerAndKnownNonNull(Pointer, IsKnownNonNull),
42
- ElementType (ElementType), Alignment(Alignment) {}
43
- llvm::Value *getPointer () const {
44
- return PointerAndKnownNonNull.getPointer ();
45
- }
46
- llvm::Type *getElementType () const { return ElementType; }
47
- CharUnits getAlignment () const { return Alignment; }
48
- KnownNonNull_t isKnownNonNull () const {
49
- return (KnownNonNull_t)PointerAndKnownNonNull.getInt ();
50
- }
51
- void setKnownNonNull () { PointerAndKnownNonNull.setInt (true ); }
52
- };
53
-
54
- template <typename T> class AddressImpl <T, true > {
55
- // Int portion stores the non-null bit and the upper 2 bits of the log of the
56
- // alignment.
57
- llvm::PointerIntPair<llvm::Value *, 3 , unsigned > Pointer;
58
- // Int portion stores lower 3 bits of the log of the alignment.
59
- llvm::PointerIntPair<llvm::Type *, 3 , unsigned > ElementType;
60
-
61
- public:
62
- AddressImpl (llvm::Value *Pointer, llvm::Type *ElementType,
63
- CharUnits Alignment, KnownNonNull_t IsKnownNonNull)
64
- : Pointer(Pointer), ElementType(ElementType) {
65
- if (Alignment.isZero ()) {
66
- this ->Pointer .setInt (IsKnownNonNull << 2 );
67
- return ;
68
- }
69
- // Currently the max supported alignment is exactly 1 << 32 and is
70
- // guaranteed to be a power of 2, so we can store the log of the alignment
71
- // into 5 bits.
72
- assert (Alignment.isPowerOfTwo () && " Alignment cannot be zero" );
73
- auto AlignLog = llvm::Log2_64 (Alignment.getQuantity ());
74
- assert (AlignLog < (1 << 5 ) && " cannot fit alignment into 5 bits" );
75
- this ->Pointer .setInt (IsKnownNonNull << 2 | AlignLog >> 3 );
76
- this ->ElementType .setInt (AlignLog & 7 );
77
- }
78
- llvm::Value *getPointer () const { return Pointer.getPointer (); }
79
- llvm::Type *getElementType () const { return ElementType.getPointer (); }
80
- CharUnits getAlignment () const {
81
- unsigned AlignLog = ((Pointer.getInt () & 0x3 ) << 3 ) | ElementType.getInt ();
82
- return CharUnits::fromQuantity (CharUnits::QuantityType (1 ) << AlignLog);
83
- }
84
- KnownNonNull_t isKnownNonNull () const {
85
- return (KnownNonNull_t)(!!(Pointer.getInt () & 0x4 ));
86
- }
87
- void setKnownNonNull () { Pointer.setInt (Pointer.getInt () | 0x4 ); }
88
- };
89
-
90
- // / An aligned address.
91
- class Address {
92
- AddressImpl<void > A;
93
-
94
34
protected:
95
- Address (std::nullptr_t )
96
- : A(nullptr , nullptr , CharUnits::Zero(), NotKnownNonNull) {}
35
+ Address (std::nullptr_t ) : ElementType(nullptr ) {}
97
36
98
37
public:
99
38
Address (llvm::Value *Pointer, llvm::Type *ElementType, CharUnits Alignment,
100
39
KnownNonNull_t IsKnownNonNull = NotKnownNonNull)
101
- : A(Pointer, ElementType, Alignment, IsKnownNonNull) {
40
+ : PointerAndKnownNonNull(Pointer, IsKnownNonNull),
41
+ ElementType (ElementType), Alignment(Alignment) {
102
42
assert (Pointer != nullptr && " Pointer cannot be null" );
103
43
assert (ElementType != nullptr && " Element type cannot be null" );
104
44
assert (llvm::cast<llvm::PointerType>(Pointer->getType ())
@@ -107,11 +47,13 @@ class Address {
107
47
}
108
48
109
49
static Address invalid () { return Address (nullptr ); }
110
- bool isValid () const { return A.getPointer () != nullptr ; }
50
+ bool isValid () const {
51
+ return PointerAndKnownNonNull.getPointer () != nullptr ;
52
+ }
111
53
112
54
llvm::Value *getPointer () const {
113
55
assert (isValid ());
114
- return A .getPointer ();
56
+ return PointerAndKnownNonNull .getPointer ();
115
57
}
116
58
117
59
// / Return the type of the pointer value.
@@ -122,7 +64,7 @@ class Address {
122
64
// / Return the type of the values stored in this address.
123
65
llvm::Type *getElementType () const {
124
66
assert (isValid ());
125
- return A. getElementType () ;
67
+ return ElementType ;
126
68
}
127
69
128
70
// / Return the address space that this address resides in.
@@ -138,7 +80,7 @@ class Address {
138
80
// / Return the alignment of this pointer.
139
81
CharUnits getAlignment () const {
140
82
assert (isValid ());
141
- return A. getAlignment () ;
83
+ return Alignment ;
142
84
}
143
85
144
86
// / Return address with different pointer, but same element type and
@@ -159,13 +101,13 @@ class Address {
159
101
// / Whether the pointer is known not to be null.
160
102
KnownNonNull_t isKnownNonNull () const {
161
103
assert (isValid ());
162
- return A. isKnownNonNull ();
104
+ return (KnownNonNull_t)PointerAndKnownNonNull. getInt ();
163
105
}
164
106
165
107
// / Set the non-null bit.
166
108
Address setKnownNonNull () {
167
109
assert (isValid ());
168
- A. setKnownNonNull ( );
110
+ PointerAndKnownNonNull. setInt ( true );
169
111
return *this ;
170
112
}
171
113
};
0 commit comments