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
26namespace 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

source code of llvm/include/llvm/CodeGen/ValueTypes.h