1//===- CodeGenTypes/MachineValueType.h - Machine-Level 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 machine-level target independent types which
10// legal values in the code generator use.
11//
12// Constants and properties are defined in ValueTypes.td.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_CODEGEN_MACHINEVALUETYPE_H
17#define LLVM_CODEGEN_MACHINEVALUETYPE_H
18
19#include "llvm/ADT/Sequence.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/MathExtras.h"
22#include "llvm/Support/TypeSize.h"
23#include <cassert>
24#include <cstdint>
25
26namespace llvm {
27
28 class Type;
29 class raw_ostream;
30
31 /// Machine Value Type. Every type that is supported natively by some
32 /// processor targeted by LLVM occurs here. This means that any legal value
33 /// type can be represented by an MVT.
34 class MVT {
35 public:
36 enum SimpleValueType : uint8_t {
37 // Simple value types that aren't explicitly part of this enumeration
38 // are considered extended value types.
39 INVALID_SIMPLE_VALUE_TYPE = 0,
40
41#define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc) Ty = n,
42#define GET_VT_RANGES
43#include "llvm/CodeGen/GenVT.inc"
44#undef GET_VT_ATTR
45#undef GET_VT_RANGES
46
47 VALUETYPE_SIZE = LAST_VALUETYPE + 1,
48
49 // This is the current maximum for LAST_VALUETYPE.
50 // MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
51 // This value must be a multiple of 32.
52 MAX_ALLOWED_VALUETYPE = 224,
53 };
54
55 static_assert(FIRST_VALUETYPE > 0);
56 static_assert(LAST_VALUETYPE < MAX_ALLOWED_VALUETYPE);
57
58 SimpleValueType SimpleTy = INVALID_SIMPLE_VALUE_TYPE;
59
60 constexpr MVT() = default;
61 constexpr MVT(SimpleValueType SVT) : SimpleTy(SVT) {}
62
63 bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; }
64 bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; }
65 bool operator==(const MVT& S) const { return SimpleTy == S.SimpleTy; }
66 bool operator!=(const MVT& S) const { return SimpleTy != S.SimpleTy; }
67 bool operator>=(const MVT& S) const { return SimpleTy >= S.SimpleTy; }
68 bool operator<=(const MVT& S) const { return SimpleTy <= S.SimpleTy; }
69
70 /// Support for debugging, callable in GDB: VT.dump()
71 void dump() const;
72
73 /// Implement operator<<.
74 void print(raw_ostream &OS) const;
75
76 /// Return true if this is a valid simple valuetype.
77 bool isValid() const {
78 return (SimpleTy >= MVT::FIRST_VALUETYPE &&
79 SimpleTy <= MVT::LAST_VALUETYPE);
80 }
81
82 /// Return true if this is a FP or a vector FP type.
83 bool isFloatingPoint() const {
84 return ((SimpleTy >= MVT::FIRST_FP_VALUETYPE &&
85 SimpleTy <= MVT::LAST_FP_VALUETYPE) ||
86 (SimpleTy >= MVT::FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE &&
87 SimpleTy <= MVT::LAST_FP_FIXEDLEN_VECTOR_VALUETYPE) ||
88 (SimpleTy >= MVT::FIRST_FP_SCALABLE_VECTOR_VALUETYPE &&
89 SimpleTy <= MVT::LAST_FP_SCALABLE_VECTOR_VALUETYPE));
90 }
91
92 /// Return true if this is an integer or a vector integer type.
93 bool isInteger() const {
94 return ((SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
95 SimpleTy <= MVT::LAST_INTEGER_VALUETYPE) ||
96 (SimpleTy >= MVT::FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE &&
97 SimpleTy <= MVT::LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE) ||
98 (SimpleTy >= MVT::FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE &&
99 SimpleTy <= MVT::LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE));
100 }
101
102 /// Return true if this is an integer, not including vectors.
103 bool isScalarInteger() const {
104 return (SimpleTy >= MVT::FIRST_INTEGER_VALUETYPE &&
105 SimpleTy <= MVT::LAST_INTEGER_VALUETYPE);
106 }
107
108 /// Return true if this is a vector value type.
109 bool isVector() const {
110 return (SimpleTy >= MVT::FIRST_VECTOR_VALUETYPE &&
111 SimpleTy <= MVT::LAST_VECTOR_VALUETYPE);
112 }
113
114 /// Return true if this is a vector value type where the
115 /// runtime length is machine dependent
116 bool isScalableVector() const {
117 return (SimpleTy >= MVT::FIRST_SCALABLE_VECTOR_VALUETYPE &&
118 SimpleTy <= MVT::LAST_SCALABLE_VECTOR_VALUETYPE);
119 }
120
121 /// Return true if this is a custom target type that has a scalable size.
122 bool isScalableTargetExtVT() const {
123 return SimpleTy == MVT::aarch64svcount;
124 }
125
126 /// Return true if the type is a scalable type.
127 bool isScalableVT() const {
128 return isScalableVector() || isScalableTargetExtVT();
129 }
130
131 bool isFixedLengthVector() const {
132 return (SimpleTy >= MVT::FIRST_FIXEDLEN_VECTOR_VALUETYPE &&
133 SimpleTy <= MVT::LAST_FIXEDLEN_VECTOR_VALUETYPE);
134 }
135
136 /// Return true if this is a 16-bit vector type.
137 bool is16BitVector() const {
138 return (isFixedLengthVector() && getFixedSizeInBits() == 16);
139 }
140
141 /// Return true if this is a 32-bit vector type.
142 bool is32BitVector() const {
143 return (isFixedLengthVector() && getFixedSizeInBits() == 32);
144 }
145
146 /// Return true if this is a 64-bit vector type.
147 bool is64BitVector() const {
148 return (isFixedLengthVector() && getFixedSizeInBits() == 64);
149 }
150
151 /// Return true if this is a 128-bit vector type.
152 bool is128BitVector() const {
153 return (isFixedLengthVector() && getFixedSizeInBits() == 128);
154 }
155
156 /// Return true if this is a 256-bit vector type.
157 bool is256BitVector() const {
158 return (isFixedLengthVector() && getFixedSizeInBits() == 256);
159 }
160
161 /// Return true if this is a 512-bit vector type.
162 bool is512BitVector() const {
163 return (isFixedLengthVector() && getFixedSizeInBits() == 512);
164 }
165
166 /// Return true if this is a 1024-bit vector type.
167 bool is1024BitVector() const {
168 return (isFixedLengthVector() && getFixedSizeInBits() == 1024);
169 }
170
171 /// Return true if this is a 2048-bit vector type.
172 bool is2048BitVector() const {
173 return (isFixedLengthVector() && getFixedSizeInBits() == 2048);
174 }
175
176 /// Return true if this is an overloaded type for TableGen.
177 bool isOverloaded() const {
178 switch (SimpleTy) {
179#define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc) \
180 case Ty: \
181 return Any;
182#include "llvm/CodeGen/GenVT.inc"
183#undef GET_VT_ATTR
184 default:
185 return false;
186 }
187 }
188
189 /// Return a vector with the same number of elements as this vector, but
190 /// with the element type converted to an integer type with the same
191 /// bitwidth.
192 MVT changeVectorElementTypeToInteger() const {
193 MVT EltTy = getVectorElementType();
194 MVT IntTy = MVT::getIntegerVT(BitWidth: EltTy.getSizeInBits());
195 MVT VecTy = MVT::getVectorVT(VT: IntTy, EC: getVectorElementCount());
196 assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
197 "Simple vector VT not representable by simple integer vector VT!");
198 return VecTy;
199 }
200
201 /// Return a VT for a vector type whose attributes match ourselves
202 /// with the exception of the element type that is chosen by the caller.
203 MVT changeVectorElementType(MVT EltVT) const {
204 MVT VecTy = MVT::getVectorVT(VT: EltVT, EC: getVectorElementCount());
205 assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
206 "Simple vector VT not representable by simple integer vector VT!");
207 return VecTy;
208 }
209
210 /// Return the type converted to an equivalently sized integer or vector
211 /// with integer element type. Similar to changeVectorElementTypeToInteger,
212 /// but also handles scalars.
213 MVT changeTypeToInteger() {
214 if (isVector())
215 return changeVectorElementTypeToInteger();
216 return MVT::getIntegerVT(BitWidth: getSizeInBits());
217 }
218
219 /// Return a VT for a vector type with the same element type but
220 /// half the number of elements.
221 MVT getHalfNumVectorElementsVT() const {
222 MVT EltVT = getVectorElementType();
223 auto EltCnt = getVectorElementCount();
224 assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!");
225 return getVectorVT(VT: EltVT, EC: EltCnt.divideCoefficientBy(RHS: 2));
226 }
227
228 // Return a VT for a vector type with the same element type but
229 // double the number of elements.
230 MVT getDoubleNumVectorElementsVT() const {
231 MVT EltVT = getVectorElementType();
232 auto EltCnt = getVectorElementCount();
233 return MVT::getVectorVT(VT: EltVT, EC: EltCnt * 2);
234 }
235
236 /// Returns true if the given vector is a power of 2.
237 bool isPow2VectorType() const {
238 unsigned NElts = getVectorMinNumElements();
239 return !(NElts & (NElts - 1));
240 }
241
242 /// Widens the length of the given vector MVT up to the nearest power of 2
243 /// and returns that type.
244 MVT getPow2VectorType() const {
245 if (isPow2VectorType())
246 return *this;
247
248 ElementCount NElts = getVectorElementCount();
249 unsigned NewMinCount = 1 << Log2_32_Ceil(Value: NElts.getKnownMinValue());
250 NElts = ElementCount::get(MinVal: NewMinCount, Scalable: NElts.isScalable());
251 return MVT::getVectorVT(VT: getVectorElementType(), EC: NElts);
252 }
253
254 /// If this is a vector, return the element type, otherwise return this.
255 MVT getScalarType() const {
256 return isVector() ? getVectorElementType() : *this;
257 }
258
259 MVT getVectorElementType() const {
260 switch (SimpleTy) {
261 default:
262 llvm_unreachable("Not a vector MVT!");
263
264#define GET_VT_VECATTR(Ty, Sc, nElem, ElTy, ElSz) \
265 case Ty: \
266 return ElTy;
267#include "llvm/CodeGen/GenVT.inc"
268#undef GET_VT_VECATTR
269 }
270 }
271
272 /// Given a vector type, return the minimum number of elements it contains.
273 unsigned getVectorMinNumElements() const {
274 switch (SimpleTy) {
275 default:
276 llvm_unreachable("Not a vector MVT!");
277
278#define GET_VT_VECATTR(Ty, Sc, nElem, ElTy, ElSz) \
279 case Ty: \
280 return nElem;
281#include "llvm/CodeGen/GenVT.inc"
282#undef GET_VT_VECATTR
283 }
284 }
285
286 ElementCount getVectorElementCount() const {
287 return ElementCount::get(MinVal: getVectorMinNumElements(), Scalable: isScalableVector());
288 }
289
290 unsigned getVectorNumElements() const {
291 if (isScalableVector())
292 llvm::reportInvalidSizeRequest(
293 Msg: "Possible incorrect use of MVT::getVectorNumElements() for "
294 "scalable vector. Scalable flag may be dropped, use "
295 "MVT::getVectorElementCount() instead");
296 return getVectorMinNumElements();
297 }
298
299 /// Returns the size of the specified MVT in bits.
300 ///
301 /// If the value type is a scalable vector type, the scalable property will
302 /// be set and the runtime size will be a positive integer multiple of the
303 /// base size.
304 TypeSize getSizeInBits() const {
305 static constexpr TypeSize SizeTable[] = {
306#define GET_VT_ATTR(Ty, N, Sz, Any, Int, FP, Vec, Sc) \
307 TypeSize(Sz, Sc || Ty == aarch64svcount /* FIXME: Not in the td. */),
308#include "llvm/CodeGen/GenVT.inc"
309#undef GET_VT_ATTR
310 };
311
312 switch (SimpleTy) {
313 case INVALID_SIMPLE_VALUE_TYPE:
314 llvm_unreachable("getSizeInBits called on extended MVT.");
315 case Other:
316 llvm_unreachable("Value type is non-standard value, Other.");
317 case iPTR:
318 llvm_unreachable("Value type size is target-dependent. Ask TLI.");
319 case iPTRAny:
320 case iAny:
321 case fAny:
322 case vAny:
323 case Any:
324 llvm_unreachable("Value type is overloaded.");
325 case token:
326 llvm_unreachable("Token type is a sentinel that cannot be used "
327 "in codegen and has no size");
328 case Metadata:
329 llvm_unreachable("Value type is metadata.");
330 default:
331 assert(SimpleTy < VALUETYPE_SIZE && "Unexpected value type!");
332 return SizeTable[SimpleTy - FIRST_VALUETYPE];
333 }
334 }
335
336 /// Return the size of the specified fixed width value type in bits. The
337 /// function will assert if the type is scalable.
338 uint64_t getFixedSizeInBits() const {
339 return getSizeInBits().getFixedValue();
340 }
341
342 uint64_t getScalarSizeInBits() const {
343 return getScalarType().getSizeInBits().getFixedValue();
344 }
345
346 /// Return the number of bytes overwritten by a store of the specified value
347 /// type.
348 ///
349 /// If the value type is a scalable vector type, the scalable property will
350 /// be set and the runtime size will be a positive integer multiple of the
351 /// base size.
352 TypeSize getStoreSize() const {
353 TypeSize BaseSize = getSizeInBits();
354 return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()};
355 }
356
357 // Return the number of bytes overwritten by a store of this value type or
358 // this value type's element type in the case of a vector.
359 uint64_t getScalarStoreSize() const {
360 return getScalarType().getStoreSize().getFixedValue();
361 }
362
363 /// Return the number of bits overwritten by a store of the specified value
364 /// type.
365 ///
366 /// If the value type is a scalable vector type, the scalable property will
367 /// be set and the runtime size will be a positive integer multiple of the
368 /// base size.
369 TypeSize getStoreSizeInBits() const {
370 return getStoreSize() * 8;
371 }
372
373 /// Returns true if the number of bits for the type is a multiple of an
374 /// 8-bit byte.
375 bool isByteSized() const { return getSizeInBits().isKnownMultipleOf(RHS: 8); }
376
377 /// Return true if we know at compile time this has more bits than VT.
378 bool knownBitsGT(MVT VT) const {
379 return TypeSize::isKnownGT(LHS: getSizeInBits(), RHS: VT.getSizeInBits());
380 }
381
382 /// Return true if we know at compile time this has more than or the same
383 /// bits as VT.
384 bool knownBitsGE(MVT VT) const {
385 return TypeSize::isKnownGE(LHS: getSizeInBits(), RHS: VT.getSizeInBits());
386 }
387
388 /// Return true if we know at compile time this has fewer bits than VT.
389 bool knownBitsLT(MVT VT) const {
390 return TypeSize::isKnownLT(LHS: getSizeInBits(), RHS: VT.getSizeInBits());
391 }
392
393 /// Return true if we know at compile time this has fewer than or the same
394 /// bits as VT.
395 bool knownBitsLE(MVT VT) const {
396 return TypeSize::isKnownLE(LHS: getSizeInBits(), RHS: VT.getSizeInBits());
397 }
398
399 /// Return true if this has more bits than VT.
400 bool bitsGT(MVT VT) const {
401 assert(isScalableVector() == VT.isScalableVector() &&
402 "Comparison between scalable and fixed types");
403 return knownBitsGT(VT);
404 }
405
406 /// Return true if this has no less bits than VT.
407 bool bitsGE(MVT VT) const {
408 assert(isScalableVector() == VT.isScalableVector() &&
409 "Comparison between scalable and fixed types");
410 return knownBitsGE(VT);
411 }
412
413 /// Return true if this has less bits than VT.
414 bool bitsLT(MVT VT) const {
415 assert(isScalableVector() == VT.isScalableVector() &&
416 "Comparison between scalable and fixed types");
417 return knownBitsLT(VT);
418 }
419
420 /// Return true if this has no more bits than VT.
421 bool bitsLE(MVT VT) const {
422 assert(isScalableVector() == VT.isScalableVector() &&
423 "Comparison between scalable and fixed types");
424 return knownBitsLE(VT);
425 }
426
427 static MVT getFloatingPointVT(unsigned BitWidth) {
428#define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc) \
429 if (FP == 3 && sz == BitWidth) \
430 return Ty;
431#include "llvm/CodeGen/GenVT.inc"
432#undef GET_VT_ATTR
433
434 llvm_unreachable("Bad bit width!");
435 }
436
437 static MVT getIntegerVT(unsigned BitWidth) {
438#define GET_VT_ATTR(Ty, n, sz, Any, Int, FP, Vec, Sc) \
439 if (Int == 3 && sz == BitWidth) \
440 return Ty;
441#include "llvm/CodeGen/GenVT.inc"
442#undef GET_VT_ATTR
443
444 return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
445 }
446
447 static MVT getVectorVT(MVT VT, unsigned NumElements) {
448#define GET_VT_VECATTR(Ty, Sc, nElem, ElTy, ElSz) \
449 if (!Sc && VT.SimpleTy == ElTy && NumElements == nElem) \
450 return Ty;
451#include "llvm/CodeGen/GenVT.inc"
452#undef GET_VT_VECATTR
453
454 return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
455 }
456
457 static MVT getScalableVectorVT(MVT VT, unsigned NumElements) {
458#define GET_VT_VECATTR(Ty, Sc, nElem, ElTy, ElSz) \
459 if (Sc && VT.SimpleTy == ElTy && NumElements == nElem) \
460 return Ty;
461#include "llvm/CodeGen/GenVT.inc"
462#undef GET_VT_VECATTR
463
464 return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
465 }
466
467 static MVT getVectorVT(MVT VT, unsigned NumElements, bool IsScalable) {
468 if (IsScalable)
469 return getScalableVectorVT(VT, NumElements);
470 return getVectorVT(VT, NumElements);
471 }
472
473 static MVT getVectorVT(MVT VT, ElementCount EC) {
474 if (EC.isScalable())
475 return getScalableVectorVT(VT, NumElements: EC.getKnownMinValue());
476 return getVectorVT(VT, NumElements: EC.getKnownMinValue());
477 }
478
479 /// Return the value type corresponding to the specified type. This returns
480 /// all pointers as iPTR. If HandleUnknown is true, unknown types are
481 /// returned as Other, otherwise they are invalid.
482 static MVT getVT(Type *Ty, bool HandleUnknown = false);
483
484 public:
485 /// SimpleValueType Iteration
486 /// @{
487 static auto all_valuetypes() {
488 return enum_seq_inclusive(MVT::FIRST_VALUETYPE, MVT::LAST_VALUETYPE,
489 force_iteration_on_noniterable_enum);
490 }
491
492 static auto integer_valuetypes() {
493 return enum_seq_inclusive(MVT::FIRST_INTEGER_VALUETYPE,
494 MVT::LAST_INTEGER_VALUETYPE,
495 force_iteration_on_noniterable_enum);
496 }
497
498 static auto fp_valuetypes() {
499 return enum_seq_inclusive(MVT::FIRST_FP_VALUETYPE, MVT::LAST_FP_VALUETYPE,
500 force_iteration_on_noniterable_enum);
501 }
502
503 static auto vector_valuetypes() {
504 return enum_seq_inclusive(MVT::FIRST_VECTOR_VALUETYPE,
505 MVT::LAST_VECTOR_VALUETYPE,
506 force_iteration_on_noniterable_enum);
507 }
508
509 static auto fixedlen_vector_valuetypes() {
510 return enum_seq_inclusive(MVT::FIRST_FIXEDLEN_VECTOR_VALUETYPE,
511 MVT::LAST_FIXEDLEN_VECTOR_VALUETYPE,
512 force_iteration_on_noniterable_enum);
513 }
514
515 static auto scalable_vector_valuetypes() {
516 return enum_seq_inclusive(MVT::FIRST_SCALABLE_VECTOR_VALUETYPE,
517 MVT::LAST_SCALABLE_VECTOR_VALUETYPE,
518 force_iteration_on_noniterable_enum);
519 }
520
521 static auto integer_fixedlen_vector_valuetypes() {
522 return enum_seq_inclusive(MVT::FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE,
523 MVT::LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE,
524 force_iteration_on_noniterable_enum);
525 }
526
527 static auto fp_fixedlen_vector_valuetypes() {
528 return enum_seq_inclusive(MVT::FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE,
529 MVT::LAST_FP_FIXEDLEN_VECTOR_VALUETYPE,
530 force_iteration_on_noniterable_enum);
531 }
532
533 static auto integer_scalable_vector_valuetypes() {
534 return enum_seq_inclusive(MVT::FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE,
535 MVT::LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE,
536 force_iteration_on_noniterable_enum);
537 }
538
539 static auto fp_scalable_vector_valuetypes() {
540 return enum_seq_inclusive(MVT::FIRST_FP_SCALABLE_VECTOR_VALUETYPE,
541 MVT::LAST_FP_SCALABLE_VECTOR_VALUETYPE,
542 force_iteration_on_noniterable_enum);
543 }
544 /// @}
545 };
546
547 inline raw_ostream &operator<<(raw_ostream &OS, const MVT &VT) {
548 VT.print(OS);
549 return OS;
550 }
551
552} // end namespace llvm
553
554#endif // LLVM_CODEGEN_MACHINEVALUETYPE_H
555

source code of llvm/include/llvm/CodeGenTypes/MachineValueType.h