@@ -42,31 +42,37 @@ class LLT {
42
42
// / Get a low-level scalar or aggregate "bag of bits".
43
43
static LLT scalar (unsigned SizeInBits) {
44
44
assert (SizeInBits > 0 && " invalid scalar size" );
45
- return LLT{/* isPointer=*/ false , /* isVector=*/ false , /* NumElements=*/ 0 ,
46
- SizeInBits, /* AddressSpace=*/ 0 };
45
+ return LLT{/* isPointer=*/ false , /* isVector=*/ false ,
46
+ ElementCount::getFixed (0 ), SizeInBits,
47
+ /* AddressSpace=*/ 0 };
47
48
}
48
49
49
50
// / Get a low-level pointer in the given address space.
50
51
static LLT pointer (unsigned AddressSpace, unsigned SizeInBits) {
51
52
assert (SizeInBits > 0 && " invalid pointer size" );
52
- return LLT{/* isPointer=*/ true , /* isVector=*/ false , /* NumElements= */ 0 ,
53
- SizeInBits, AddressSpace};
53
+ return LLT{/* isPointer=*/ true , /* isVector=*/ false ,
54
+ ElementCount::getFixed ( 0 ), SizeInBits, AddressSpace};
54
55
}
55
56
56
57
// / Get a low-level vector of some number of elements and element width.
57
58
// / \p NumElements must be at least 2.
58
- static LLT vector (uint16_t NumElements, unsigned ScalarSizeInBits) {
59
- assert (NumElements > 1 && " invalid number of vector elements" );
59
+ static LLT vector (uint16_t NumElements, unsigned ScalarSizeInBits,
60
+ bool Scalable = false ) {
61
+ assert (((!Scalable && NumElements > 1 ) || NumElements > 0 ) &&
62
+ " invalid number of vector elements" );
60
63
assert (ScalarSizeInBits > 0 && " invalid vector element size" );
61
- return LLT{/* isPointer=*/ false , /* isVector=*/ true , NumElements,
62
- ScalarSizeInBits, /* AddressSpace=*/ 0 };
64
+ return LLT{/* isPointer=*/ false , /* isVector=*/ true ,
65
+ ElementCount::get (NumElements, Scalable), ScalarSizeInBits,
66
+ /* AddressSpace=*/ 0 };
63
67
}
64
68
65
69
// / Get a low-level vector of some number of elements and element type.
66
- static LLT vector (uint16_t NumElements, LLT ScalarTy) {
67
- assert (NumElements > 1 && " invalid number of vector elements" );
70
+ static LLT vector (uint16_t NumElements, LLT ScalarTy, bool Scalable = false ) {
71
+ assert (((!Scalable && NumElements > 1 ) || NumElements > 0 ) &&
72
+ " invalid number of vector elements" );
68
73
assert (!ScalarTy.isVector () && " invalid vector element type" );
69
- return LLT{ScalarTy.isPointer (), /* isVector=*/ true , NumElements,
74
+ return LLT{ScalarTy.isPointer (), /* isVector=*/ true ,
75
+ ElementCount::get (NumElements, Scalable),
70
76
ScalarTy.getSizeInBits (),
71
77
ScalarTy.isPointer () ? ScalarTy.getAddressSpace () : 0 };
72
78
}
@@ -79,9 +85,9 @@ class LLT {
79
85
return scalarOrVector (NumElements, LLT::scalar (ScalarSize));
80
86
}
81
87
82
- explicit LLT (bool isPointer, bool isVector, uint16_t NumElements ,
88
+ explicit LLT (bool isPointer, bool isVector, ElementCount EC ,
83
89
unsigned SizeInBits, unsigned AddressSpace) {
84
- init (isPointer, isVector, NumElements , SizeInBits, AddressSpace);
90
+ init (isPointer, isVector, EC , SizeInBits, AddressSpace);
85
91
}
86
92
explicit LLT () : IsPointer(false ), IsVector(false ), RawData(0 ) {}
87
93
@@ -98,18 +104,37 @@ class LLT {
98
104
// / Returns the number of elements in a vector LLT. Must only be called on
99
105
// / vector types.
100
106
uint16_t getNumElements () const {
107
+ if (isScalable ())
108
+ llvm::reportInvalidSizeRequest (
109
+ " Possible incorrect use of LLT::getNumElements() for "
110
+ " scalable vector. Scalable flag may be dropped, use "
111
+ " LLT::getElementCount() instead" );
112
+ return getElementCount ().getKnownMinValue ();
113
+ }
114
+
115
+ // / Returns true if the LLT is a scalable vector. Must only be called on
116
+ // / vector types.
117
+ bool isScalable () const {
118
+ assert (isVector () && " Expected a vector type" );
119
+ return IsPointer ? getFieldValue (PointerVectorScalableFieldInfo)
120
+ : getFieldValue (VectorScalableFieldInfo);
121
+ }
122
+
123
+ ElementCount getElementCount () const {
101
124
assert (IsVector && " cannot get number of elements on scalar/aggregate" );
102
- if (! IsPointer)
103
- return getFieldValue (VectorElementsFieldInfo);
104
- else
105
- return getFieldValue (PointerVectorElementsFieldInfo );
125
+ return ElementCount::get ( IsPointer
126
+ ? getFieldValue (PointerVectorElementsFieldInfo)
127
+ : getFieldValue (VectorElementsFieldInfo),
128
+ isScalable () );
106
129
}
107
130
108
131
// / Returns the total size of the type. Must only be called on sized types.
109
132
unsigned getSizeInBits () const {
110
133
if (isPointer () || isScalar ())
111
134
return getScalarSizeInBits ();
112
- return getScalarSizeInBits () * getNumElements ();
135
+ // FIXME: This should return a TypeSize in order to work for scalable
136
+ // vectors.
137
+ return getScalarSizeInBits () * getElementCount ().getKnownMinValue ();
113
138
}
114
139
115
140
// / Returns the total size of the type in bytes, i.e. number of whole bytes
@@ -125,7 +150,9 @@ class LLT {
125
150
// / If this type is a vector, return a vector with the same number of elements
126
151
// / but the new element type. Otherwise, return the new element type.
127
152
LLT changeElementType (LLT NewEltTy) const {
128
- return isVector () ? LLT::vector (getNumElements (), NewEltTy) : NewEltTy;
153
+ return isVector () ? LLT::vector (getElementCount ().getKnownMinValue (),
154
+ NewEltTy, isScalable ())
155
+ : NewEltTy;
129
156
}
130
157
131
158
// / If this type is a vector, return a vector with the same number of elements
@@ -134,13 +161,16 @@ class LLT {
134
161
LLT changeElementSize (unsigned NewEltSize) const {
135
162
assert (!getScalarType ().isPointer () &&
136
163
" invalid to directly change element size for pointers" );
137
- return isVector () ? LLT::vector (getNumElements (), NewEltSize)
164
+ return isVector () ? LLT::vector (getElementCount ().getKnownMinValue (),
165
+ NewEltSize, isScalable ())
138
166
: LLT::scalar (NewEltSize);
139
167
}
140
168
141
169
// / Return a vector or scalar with the same element type and the new number of
142
170
// / elements.
143
171
LLT changeNumElements (unsigned NewNumElts) const {
172
+ assert ((!isVector () || !isScalable ()) &&
173
+ " Cannot use changeNumElements on a scalable vector" );
144
174
return LLT::scalarOrVector (NewNumElts, getScalarType ());
145
175
}
146
176
@@ -237,22 +267,37 @@ class LLT {
237
267
static const constexpr BitFieldInfo PointerSizeFieldInfo{16 , 0 };
238
268
static const constexpr BitFieldInfo PointerAddressSpaceFieldInfo{
239
269
24 , PointerSizeFieldInfo[0 ] + PointerSizeFieldInfo[1 ]};
270
+ static_assert ((PointerAddressSpaceFieldInfo[0 ] +
271
+ PointerAddressSpaceFieldInfo[1 ]) <= 62 ,
272
+ " Insufficient bits to encode all data" );
240
273
// / * Vector-of-non-pointer (isPointer == 0 && isVector == 1):
241
274
// / NumElements: 16;
242
275
// / SizeOfElement: 32;
276
+ // / Scalable: 1;
243
277
static const constexpr BitFieldInfo VectorElementsFieldInfo{16 , 0 };
244
278
static const constexpr BitFieldInfo VectorSizeFieldInfo{
245
279
32 , VectorElementsFieldInfo[0 ] + VectorElementsFieldInfo[1 ]};
280
+ static const constexpr BitFieldInfo VectorScalableFieldInfo{
281
+ 1 , VectorSizeFieldInfo[0 ] + VectorSizeFieldInfo[1 ]};
282
+ static_assert ((VectorSizeFieldInfo[0 ] + VectorSizeFieldInfo[1 ]) <= 62 ,
283
+ " Insufficient bits to encode all data" );
246
284
// / * Vector-of-pointer (isPointer == 1 && isVector == 1):
247
285
// / NumElements: 16;
248
286
// / SizeOfElement: 16;
249
287
// / AddressSpace: 24;
288
+ // / Scalable: 1;
250
289
static const constexpr BitFieldInfo PointerVectorElementsFieldInfo{16 , 0 };
251
290
static const constexpr BitFieldInfo PointerVectorSizeFieldInfo{
252
291
16 ,
253
292
PointerVectorElementsFieldInfo[1 ] + PointerVectorElementsFieldInfo[0 ]};
254
293
static const constexpr BitFieldInfo PointerVectorAddressSpaceFieldInfo{
255
294
24 , PointerVectorSizeFieldInfo[1 ] + PointerVectorSizeFieldInfo[0 ]};
295
+ static const constexpr BitFieldInfo PointerVectorScalableFieldInfo{
296
+ 1 , PointerVectorAddressSpaceFieldInfo[0 ] +
297
+ PointerVectorAddressSpaceFieldInfo[1 ]};
298
+ static_assert ((PointerVectorAddressSpaceFieldInfo[0 ] +
299
+ PointerVectorAddressSpaceFieldInfo[1 ]) <= 62 ,
300
+ " Insufficient bits to encode all data" );
256
301
257
302
uint64_t IsPointer : 1 ;
258
303
uint64_t IsVector : 1 ;
@@ -273,8 +318,8 @@ class LLT {
273
318
return getMask (FieldInfo) & (RawData >> FieldInfo[1 ]);
274
319
}
275
320
276
- void init (bool IsPointer, bool IsVector, uint16_t NumElements ,
277
- unsigned SizeInBits, unsigned AddressSpace) {
321
+ void init (bool IsPointer, bool IsVector, ElementCount EC, unsigned SizeInBits ,
322
+ unsigned AddressSpace) {
278
323
this ->IsPointer = IsPointer;
279
324
this ->IsVector = IsVector;
280
325
if (!IsVector) {
@@ -284,15 +329,20 @@ class LLT {
284
329
RawData = maskAndShift (SizeInBits, PointerSizeFieldInfo) |
285
330
maskAndShift (AddressSpace, PointerAddressSpaceFieldInfo);
286
331
} else {
287
- assert (NumElements > 1 && " invalid number of vector elements" );
332
+ assert (EC. isVector () && " invalid number of vector elements" );
288
333
if (!IsPointer)
289
- RawData = maskAndShift (NumElements, VectorElementsFieldInfo) |
290
- maskAndShift (SizeInBits, VectorSizeFieldInfo);
334
+ RawData =
335
+ maskAndShift (EC.getKnownMinValue (), VectorElementsFieldInfo) |
336
+ maskAndShift (SizeInBits, VectorSizeFieldInfo) |
337
+ maskAndShift (EC.isScalable () ? 1 : 0 , VectorScalableFieldInfo);
291
338
else
292
339
RawData =
293
- maskAndShift (NumElements, PointerVectorElementsFieldInfo) |
340
+ maskAndShift (EC.getKnownMinValue (),
341
+ PointerVectorElementsFieldInfo) |
294
342
maskAndShift (SizeInBits, PointerVectorSizeFieldInfo) |
295
- maskAndShift (AddressSpace, PointerVectorAddressSpaceFieldInfo);
343
+ maskAndShift (AddressSpace, PointerVectorAddressSpaceFieldInfo) |
344
+ maskAndShift (EC.isScalable () ? 1 : 0 ,
345
+ PointerVectorScalableFieldInfo);
296
346
}
297
347
}
298
348
0 commit comments