1 | //===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines the set of low-level target independent types which various |
10 | // values in the code generator are. This allows the target specific behavior |
11 | // of instructions to be described to target independent passes. |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_CODEGEN_VALUETYPES_H |
16 | #define LLVM_CODEGEN_VALUETYPES_H |
17 | |
18 | #include "llvm/CodeGenTypes/MachineValueType.h" |
19 | #include "llvm/Support/Compiler.h" |
20 | #include "llvm/Support/MathExtras.h" |
21 | #include "llvm/Support/TypeSize.h" |
22 | #include <cassert> |
23 | #include <cstdint> |
24 | #include <string> |
25 | |
26 | namespace llvm { |
27 | |
28 | class LLVMContext; |
29 | class Type; |
30 | |
31 | /// Extended Value Type. Capable of holding value types which are not native |
32 | /// for any processor (such as the i12345 type), as well as the types an MVT |
33 | /// can represent. |
34 | struct EVT { |
35 | private: |
36 | MVT V = MVT::INVALID_SIMPLE_VALUE_TYPE; |
37 | Type *LLVMTy = nullptr; |
38 | |
39 | public: |
40 | constexpr EVT() = default; |
41 | constexpr EVT(MVT::SimpleValueType SVT) : V(SVT) {} |
42 | constexpr EVT(MVT S) : V(S) {} |
43 | |
44 | bool operator==(EVT VT) const { |
45 | return !(*this != VT); |
46 | } |
47 | bool operator!=(EVT VT) const { |
48 | if (V.SimpleTy != VT.V.SimpleTy) |
49 | return true; |
50 | if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) |
51 | return LLVMTy != VT.LLVMTy; |
52 | return false; |
53 | } |
54 | |
55 | /// Returns the EVT that represents a floating-point type with the given |
56 | /// number of bits. There are two floating-point types with 128 bits - this |
57 | /// returns f128 rather than ppcf128. |
58 | static EVT getFloatingPointVT(unsigned BitWidth) { |
59 | return MVT::getFloatingPointVT(BitWidth); |
60 | } |
61 | |
62 | /// Returns the EVT that represents an integer with the given number of |
63 | /// bits. |
64 | static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) { |
65 | MVT M = MVT::getIntegerVT(BitWidth); |
66 | if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) |
67 | return M; |
68 | return getExtendedIntegerVT(C&: Context, BitWidth); |
69 | } |
70 | |
71 | /// Returns the EVT that represents a vector NumElements in length, where |
72 | /// each element is of type VT. |
73 | static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, |
74 | bool IsScalable = false) { |
75 | MVT M = MVT::getVectorVT(VT: VT.V, NumElements, IsScalable); |
76 | if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) |
77 | return M; |
78 | return getExtendedVectorVT(C&: Context, VT, NumElements, IsScalable); |
79 | } |
80 | |
81 | /// Returns the EVT that represents a vector EC.Min elements in length, |
82 | /// where each element is of type VT. |
83 | static EVT getVectorVT(LLVMContext &Context, EVT VT, ElementCount EC) { |
84 | MVT M = MVT::getVectorVT(VT: VT.V, EC); |
85 | if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) |
86 | return M; |
87 | return getExtendedVectorVT(Context, VT, EC); |
88 | } |
89 | |
90 | /// Return a vector with the same number of elements as this vector, but |
91 | /// with the element type converted to an integer type with the same |
92 | /// bitwidth. |
93 | EVT changeVectorElementTypeToInteger() const { |
94 | if (isSimple()) |
95 | return getSimpleVT().changeVectorElementTypeToInteger(); |
96 | return changeExtendedVectorElementTypeToInteger(); |
97 | } |
98 | |
99 | /// Return a VT for a vector type whose attributes match ourselves |
100 | /// with the exception of the element type that is chosen by the caller. |
101 | EVT changeVectorElementType(EVT EltVT) const { |
102 | if (isSimple()) { |
103 | assert(EltVT.isSimple() && |
104 | "Can't change simple vector VT to have extended element VT" ); |
105 | return getSimpleVT().changeVectorElementType(EltVT: EltVT.getSimpleVT()); |
106 | } |
107 | return changeExtendedVectorElementType(EltVT); |
108 | } |
109 | |
110 | /// Return the type converted to an equivalently sized integer or vector |
111 | /// with integer element type. Similar to changeVectorElementTypeToInteger, |
112 | /// but also handles scalars. |
113 | EVT changeTypeToInteger() const { |
114 | if (isVector()) |
115 | return changeVectorElementTypeToInteger(); |
116 | |
117 | if (isSimple()) |
118 | return getSimpleVT().changeTypeToInteger(); |
119 | return changeExtendedTypeToInteger(); |
120 | } |
121 | |
122 | /// Test if the given EVT has zero size, this will fail if called on a |
123 | /// scalable type |
124 | bool isZeroSized() const { |
125 | return getSizeInBits().isZero(); |
126 | } |
127 | |
128 | /// Test if the given EVT is simple (as opposed to being extended). |
129 | bool isSimple() const { |
130 | return V.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE; |
131 | } |
132 | |
133 | /// Test if the given EVT is extended (as opposed to being simple). |
134 | bool isExtended() const { |
135 | return !isSimple(); |
136 | } |
137 | |
138 | /// Return true if this is a FP or a vector FP type. |
139 | bool isFloatingPoint() const { |
140 | return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint(); |
141 | } |
142 | |
143 | /// Return true if this is an integer or a vector integer type. |
144 | bool isInteger() const { |
145 | return isSimple() ? V.isInteger() : isExtendedInteger(); |
146 | } |
147 | |
148 | /// Return true if this is an integer, but not a vector. |
149 | bool isScalarInteger() const { |
150 | return isSimple() ? V.isScalarInteger() : isExtendedScalarInteger(); |
151 | } |
152 | |
153 | /// Return true if this is a vector type where the runtime |
154 | /// length is machine dependent |
155 | bool isScalableTargetExtVT() const { |
156 | return isSimple() && V.isScalableTargetExtVT(); |
157 | } |
158 | |
159 | /// Return true if this is a vector value type. |
160 | bool isVector() const { |
161 | return isSimple() ? V.isVector() : isExtendedVector(); |
162 | } |
163 | |
164 | /// Return true if this is a vector type where the runtime |
165 | /// length is machine dependent |
166 | bool isScalableVector() const { |
167 | return isSimple() ? V.isScalableVector() : isExtendedScalableVector(); |
168 | } |
169 | |
170 | bool isFixedLengthVector() const { |
171 | return isSimple() ? V.isFixedLengthVector() |
172 | : isExtendedFixedLengthVector(); |
173 | } |
174 | |
175 | /// Return true if the type is a scalable type. |
176 | bool isScalableVT() const { |
177 | return isScalableVector() || isScalableTargetExtVT(); |
178 | } |
179 | |
180 | /// Return true if this is a 16-bit vector type. |
181 | bool is16BitVector() const { |
182 | return isSimple() ? V.is16BitVector() : isExtended16BitVector(); |
183 | } |
184 | |
185 | /// Return true if this is a 32-bit vector type. |
186 | bool is32BitVector() const { |
187 | return isSimple() ? V.is32BitVector() : isExtended32BitVector(); |
188 | } |
189 | |
190 | /// Return true if this is a 64-bit vector type. |
191 | bool is64BitVector() const { |
192 | return isSimple() ? V.is64BitVector() : isExtended64BitVector(); |
193 | } |
194 | |
195 | /// Return true if this is a 128-bit vector type. |
196 | bool is128BitVector() const { |
197 | return isSimple() ? V.is128BitVector() : isExtended128BitVector(); |
198 | } |
199 | |
200 | /// Return true if this is a 256-bit vector type. |
201 | bool is256BitVector() const { |
202 | return isSimple() ? V.is256BitVector() : isExtended256BitVector(); |
203 | } |
204 | |
205 | /// Return true if this is a 512-bit vector type. |
206 | bool is512BitVector() const { |
207 | return isSimple() ? V.is512BitVector() : isExtended512BitVector(); |
208 | } |
209 | |
210 | /// Return true if this is a 1024-bit vector type. |
211 | bool is1024BitVector() const { |
212 | return isSimple() ? V.is1024BitVector() : isExtended1024BitVector(); |
213 | } |
214 | |
215 | /// Return true if this is a 2048-bit vector type. |
216 | bool is2048BitVector() const { |
217 | return isSimple() ? V.is2048BitVector() : isExtended2048BitVector(); |
218 | } |
219 | |
220 | /// Return true if this is an overloaded type for TableGen. |
221 | bool isOverloaded() const { |
222 | return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny); |
223 | } |
224 | |
225 | /// Return true if the bit size is a multiple of 8. |
226 | bool isByteSized() const { |
227 | return !isZeroSized() && getSizeInBits().isKnownMultipleOf(RHS: 8); |
228 | } |
229 | |
230 | /// Return true if the size is a power-of-two number of bytes. |
231 | bool isRound() const { |
232 | if (isScalableVector()) |
233 | return false; |
234 | unsigned BitSize = getSizeInBits(); |
235 | return BitSize >= 8 && !(BitSize & (BitSize - 1)); |
236 | } |
237 | |
238 | /// Return true if this has the same number of bits as VT. |
239 | bool bitsEq(EVT VT) const { |
240 | if (EVT::operator==(VT)) return true; |
241 | return getSizeInBits() == VT.getSizeInBits(); |
242 | } |
243 | |
244 | /// Return true if we know at compile time this has more bits than VT. |
245 | bool knownBitsGT(EVT VT) const { |
246 | return TypeSize::isKnownGT(LHS: getSizeInBits(), RHS: VT.getSizeInBits()); |
247 | } |
248 | |
249 | /// Return true if we know at compile time this has more than or the same |
250 | /// bits as VT. |
251 | bool knownBitsGE(EVT VT) const { |
252 | return TypeSize::isKnownGE(LHS: getSizeInBits(), RHS: VT.getSizeInBits()); |
253 | } |
254 | |
255 | /// Return true if we know at compile time this has fewer bits than VT. |
256 | bool knownBitsLT(EVT VT) const { |
257 | return TypeSize::isKnownLT(LHS: getSizeInBits(), RHS: VT.getSizeInBits()); |
258 | } |
259 | |
260 | /// Return true if we know at compile time this has fewer than or the same |
261 | /// bits as VT. |
262 | bool knownBitsLE(EVT VT) const { |
263 | return TypeSize::isKnownLE(LHS: getSizeInBits(), RHS: VT.getSizeInBits()); |
264 | } |
265 | |
266 | /// Return true if this has more bits than VT. |
267 | bool bitsGT(EVT VT) const { |
268 | if (EVT::operator==(VT)) return false; |
269 | assert(isScalableVector() == VT.isScalableVector() && |
270 | "Comparison between scalable and fixed types" ); |
271 | return knownBitsGT(VT); |
272 | } |
273 | |
274 | /// Return true if this has no less bits than VT. |
275 | bool bitsGE(EVT VT) const { |
276 | if (EVT::operator==(VT)) return true; |
277 | assert(isScalableVector() == VT.isScalableVector() && |
278 | "Comparison between scalable and fixed types" ); |
279 | return knownBitsGE(VT); |
280 | } |
281 | |
282 | /// Return true if this has less bits than VT. |
283 | bool bitsLT(EVT VT) const { |
284 | if (EVT::operator==(VT)) return false; |
285 | assert(isScalableVector() == VT.isScalableVector() && |
286 | "Comparison between scalable and fixed types" ); |
287 | return knownBitsLT(VT); |
288 | } |
289 | |
290 | /// Return true if this has no more bits than VT. |
291 | bool bitsLE(EVT VT) const { |
292 | if (EVT::operator==(VT)) return true; |
293 | assert(isScalableVector() == VT.isScalableVector() && |
294 | "Comparison between scalable and fixed types" ); |
295 | return knownBitsLE(VT); |
296 | } |
297 | |
298 | /// Return the SimpleValueType held in the specified simple EVT. |
299 | MVT getSimpleVT() const { |
300 | assert(isSimple() && "Expected a SimpleValueType!" ); |
301 | return V; |
302 | } |
303 | |
304 | /// If this is a vector type, return the element type, otherwise return |
305 | /// this. |
306 | EVT getScalarType() const { |
307 | return isVector() ? getVectorElementType() : *this; |
308 | } |
309 | |
310 | /// Given a vector type, return the type of each element. |
311 | EVT getVectorElementType() const { |
312 | assert(isVector() && "Invalid vector type!" ); |
313 | if (isSimple()) |
314 | return V.getVectorElementType(); |
315 | return getExtendedVectorElementType(); |
316 | } |
317 | |
318 | /// Given a vector type, return the number of elements it contains. |
319 | unsigned getVectorNumElements() const { |
320 | assert(isVector() && "Invalid vector type!" ); |
321 | |
322 | if (isScalableVector()) |
323 | llvm::reportInvalidSizeRequest( |
324 | Msg: "Possible incorrect use of EVT::getVectorNumElements() for " |
325 | "scalable vector. Scalable flag may be dropped, use " |
326 | "EVT::getVectorElementCount() instead" ); |
327 | |
328 | return isSimple() ? V.getVectorNumElements() |
329 | : getExtendedVectorNumElements(); |
330 | } |
331 | |
332 | // Given a (possibly scalable) vector type, return the ElementCount |
333 | ElementCount getVectorElementCount() const { |
334 | assert((isVector()) && "Invalid vector type!" ); |
335 | if (isSimple()) |
336 | return V.getVectorElementCount(); |
337 | |
338 | return getExtendedVectorElementCount(); |
339 | } |
340 | |
341 | /// Given a vector type, return the minimum number of elements it contains. |
342 | unsigned getVectorMinNumElements() const { |
343 | return getVectorElementCount().getKnownMinValue(); |
344 | } |
345 | |
346 | /// Return the size of the specified value type in bits. |
347 | /// |
348 | /// If the value type is a scalable vector type, the scalable property will |
349 | /// be set and the runtime size will be a positive integer multiple of the |
350 | /// base size. |
351 | TypeSize getSizeInBits() const { |
352 | if (isSimple()) |
353 | return V.getSizeInBits(); |
354 | return getExtendedSizeInBits(); |
355 | } |
356 | |
357 | /// Return the size of the specified fixed width value type in bits. The |
358 | /// function will assert if the type is scalable. |
359 | uint64_t getFixedSizeInBits() const { |
360 | return getSizeInBits().getFixedValue(); |
361 | } |
362 | |
363 | uint64_t getScalarSizeInBits() const { |
364 | return getScalarType().getSizeInBits().getFixedValue(); |
365 | } |
366 | |
367 | /// Return the number of bytes overwritten by a store of the specified value |
368 | /// type. |
369 | /// |
370 | /// If the value type is a scalable vector type, the scalable property will |
371 | /// be set and the runtime size will be a positive integer multiple of the |
372 | /// base size. |
373 | TypeSize getStoreSize() const { |
374 | TypeSize BaseSize = getSizeInBits(); |
375 | return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()}; |
376 | } |
377 | |
378 | // Return the number of bytes overwritten by a store of this value type or |
379 | // this value type's element type in the case of a vector. |
380 | uint64_t getScalarStoreSize() const { |
381 | return getScalarType().getStoreSize().getFixedValue(); |
382 | } |
383 | |
384 | /// Return the number of bits overwritten by a store of the specified value |
385 | /// type. |
386 | /// |
387 | /// If the value type is a scalable vector type, the scalable property will |
388 | /// be set and the runtime size will be a positive integer multiple of the |
389 | /// base size. |
390 | TypeSize getStoreSizeInBits() const { |
391 | return getStoreSize() * 8; |
392 | } |
393 | |
394 | /// Rounds the bit-width of the given integer EVT up to the nearest power of |
395 | /// two (and at least to eight), and returns the integer EVT with that |
396 | /// number of bits. |
397 | EVT getRoundIntegerType(LLVMContext &Context) const { |
398 | assert(isInteger() && !isVector() && "Invalid integer type!" ); |
399 | unsigned BitWidth = getSizeInBits(); |
400 | if (BitWidth <= 8) |
401 | return EVT(MVT::i8); |
402 | return getIntegerVT(Context, BitWidth: llvm::bit_ceil(Value: BitWidth)); |
403 | } |
404 | |
405 | /// Finds the smallest simple value type that is greater than or equal to |
406 | /// half the width of this EVT. If no simple value type can be found, an |
407 | /// extended integer value type of half the size (rounded up) is returned. |
408 | EVT getHalfSizedIntegerVT(LLVMContext &Context) const { |
409 | assert(isInteger() && !isVector() && "Invalid integer type!" ); |
410 | unsigned EVTSize = getSizeInBits(); |
411 | for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE; |
412 | IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) { |
413 | EVT HalfVT = EVT((MVT::SimpleValueType)IntVT); |
414 | if (HalfVT.getSizeInBits() * 2 >= EVTSize) |
415 | return HalfVT; |
416 | } |
417 | return getIntegerVT(Context, BitWidth: (EVTSize + 1) / 2); |
418 | } |
419 | |
420 | /// Return a VT for an integer vector type with the size of the |
421 | /// elements doubled. The typed returned may be an extended type. |
422 | EVT widenIntegerVectorElementType(LLVMContext &Context) const { |
423 | EVT EltVT = getVectorElementType(); |
424 | EltVT = EVT::getIntegerVT(Context, BitWidth: 2 * EltVT.getSizeInBits()); |
425 | return EVT::getVectorVT(Context, VT: EltVT, EC: getVectorElementCount()); |
426 | } |
427 | |
428 | // Return a VT for a vector type with the same element type but |
429 | // half the number of elements. The type returned may be an |
430 | // extended type. |
431 | EVT getHalfNumVectorElementsVT(LLVMContext &Context) const { |
432 | EVT EltVT = getVectorElementType(); |
433 | auto EltCnt = getVectorElementCount(); |
434 | assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!" ); |
435 | return EVT::getVectorVT(Context, VT: EltVT, EC: EltCnt.divideCoefficientBy(RHS: 2)); |
436 | } |
437 | |
438 | // Return a VT for a vector type with the same element type but |
439 | // double the number of elements. The type returned may be an |
440 | // extended type. |
441 | EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const { |
442 | EVT EltVT = getVectorElementType(); |
443 | auto EltCnt = getVectorElementCount(); |
444 | return EVT::getVectorVT(Context, VT: EltVT, EC: EltCnt * 2); |
445 | } |
446 | |
447 | /// Returns true if the given vector is a power of 2. |
448 | bool isPow2VectorType() const { |
449 | unsigned NElts = getVectorMinNumElements(); |
450 | return !(NElts & (NElts - 1)); |
451 | } |
452 | |
453 | /// Widens the length of the given vector EVT up to the nearest power of 2 |
454 | /// and returns that type. |
455 | EVT getPow2VectorType(LLVMContext &Context) const { |
456 | if (!isPow2VectorType()) { |
457 | ElementCount NElts = getVectorElementCount(); |
458 | unsigned NewMinCount = 1 << Log2_32_Ceil(Value: NElts.getKnownMinValue()); |
459 | NElts = ElementCount::get(MinVal: NewMinCount, Scalable: NElts.isScalable()); |
460 | return EVT::getVectorVT(Context, VT: getVectorElementType(), EC: NElts); |
461 | } |
462 | else { |
463 | return *this; |
464 | } |
465 | } |
466 | |
467 | /// This function returns value type as a string, e.g. "i32". |
468 | std::string getEVTString() const; |
469 | |
470 | /// Support for debugging, callable in GDB: VT.dump() |
471 | void dump() const; |
472 | |
473 | /// Implement operator<<. |
474 | void print(raw_ostream &OS) const { |
475 | OS << getEVTString(); |
476 | } |
477 | |
478 | /// This method returns an LLVM type corresponding to the specified EVT. |
479 | /// For integer types, this returns an unsigned type. Note that this will |
480 | /// abort for types that cannot be represented. |
481 | Type *getTypeForEVT(LLVMContext &Context) const; |
482 | |
483 | /// Return the value type corresponding to the specified type. |
484 | /// This returns all pointers as iPTR. If HandleUnknown is true, unknown |
485 | /// types are returned as Other, otherwise they are invalid. |
486 | static EVT getEVT(Type *Ty, bool HandleUnknown = false); |
487 | |
488 | intptr_t getRawBits() const { |
489 | if (isSimple()) |
490 | return V.SimpleTy; |
491 | else |
492 | return (intptr_t)(LLVMTy); |
493 | } |
494 | |
495 | /// A meaningless but well-behaved order, useful for constructing |
496 | /// containers. |
497 | struct compareRawBits { |
498 | bool operator()(EVT L, EVT R) const { |
499 | if (L.V.SimpleTy == R.V.SimpleTy) |
500 | return L.LLVMTy < R.LLVMTy; |
501 | else |
502 | return L.V.SimpleTy < R.V.SimpleTy; |
503 | } |
504 | }; |
505 | |
506 | private: |
507 | // Methods for handling the Extended-type case in functions above. |
508 | // These are all out-of-line to prevent users of this header file |
509 | // from having a dependency on Type.h. |
510 | EVT changeExtendedTypeToInteger() const; |
511 | EVT changeExtendedVectorElementType(EVT EltVT) const; |
512 | EVT changeExtendedVectorElementTypeToInteger() const; |
513 | static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth); |
514 | static EVT getExtendedVectorVT(LLVMContext &C, EVT VT, unsigned NumElements, |
515 | bool IsScalable); |
516 | static EVT getExtendedVectorVT(LLVMContext &Context, EVT VT, |
517 | ElementCount EC); |
518 | bool isExtendedFloatingPoint() const LLVM_READONLY; |
519 | bool isExtendedInteger() const LLVM_READONLY; |
520 | bool isExtendedScalarInteger() const LLVM_READONLY; |
521 | bool isExtendedVector() const LLVM_READONLY; |
522 | bool isExtended16BitVector() const LLVM_READONLY; |
523 | bool isExtended32BitVector() const LLVM_READONLY; |
524 | bool isExtended64BitVector() const LLVM_READONLY; |
525 | bool isExtended128BitVector() const LLVM_READONLY; |
526 | bool isExtended256BitVector() const LLVM_READONLY; |
527 | bool isExtended512BitVector() const LLVM_READONLY; |
528 | bool isExtended1024BitVector() const LLVM_READONLY; |
529 | bool isExtended2048BitVector() const LLVM_READONLY; |
530 | bool isExtendedFixedLengthVector() const LLVM_READONLY; |
531 | bool isExtendedScalableVector() const LLVM_READONLY; |
532 | EVT getExtendedVectorElementType() const; |
533 | unsigned getExtendedVectorNumElements() const LLVM_READONLY; |
534 | ElementCount getExtendedVectorElementCount() const LLVM_READONLY; |
535 | TypeSize getExtendedSizeInBits() const LLVM_READONLY; |
536 | }; |
537 | |
538 | inline raw_ostream &operator<<(raw_ostream &OS, const EVT &V) { |
539 | V.print(OS); |
540 | return OS; |
541 | } |
542 | } // end namespace llvm |
543 | |
544 | #endif // LLVM_CODEGEN_VALUETYPES_H |
545 | |