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