LLVM 23.0.0git
LowLevelType.h
Go to the documentation of this file.
1//== llvm/CodeGenTypes/LowLevelType.h -------------------------- -*- 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/// \file
9/// Implement a low-level type suitable for MachineInstr level instruction
10/// selection.
11///
12/// For a type attached to a MachineInstr, we care about total
13/// size, the number of vector lanes (if any)
14/// and the kind of the type (anyscalar, integer, float and etc).
15/// Floating point are filled with APFloat::Semantics to make them
16/// distinguishable.
17///
18/// Earlier other information required for correct selection was expected to be
19/// carried only by the opcode, or non-type flags. For example the distinction
20/// between G_ADD and G_FADD for int/float or fast-math flags.
21///
22/// Now we also able to rely on the kind of the type.
23/// This may be useful to distinguish different types of the same size used at
24/// the same opcode, for example, G_FADD with half vs G_FADD with bfloat16.
25///
26//===----------------------------------------------------------------------===//
27
28#ifndef LLVM_CODEGEN_LOWLEVELTYPE_H
29#define LLVM_CODEGEN_LOWLEVELTYPE_H
30
31#include "llvm/ADT/APFloat.h"
33#include "llvm/ADT/bit.h"
36#include "llvm/Support/Debug.h"
38#include <cassert>
39
40namespace llvm {
41
42class Type;
43class raw_ostream;
44
45class LLT {
46public:
48
60
61 constexpr static Kind toVector(Kind Ty) {
62 if (Ty == Kind::POINTER)
64
65 if (Ty == Kind::INTEGER)
67
68 if (Ty == Kind::FLOAT)
69 return Kind::VECTOR_FLOAT;
70
71 return Kind::VECTOR_ANY;
72 }
73
74 constexpr static Kind toScalar(Kind Ty) {
75 if (Ty == Kind::VECTOR_POINTER)
76 return Kind::POINTER;
77
78 if (Ty == Kind::VECTOR_INTEGER)
79 return Kind::INTEGER;
80
81 if (Ty == Kind::VECTOR_FLOAT)
82 return Kind::FLOAT;
83
84 return Kind::ANY_SCALAR;
85 }
86
87 /// Get a low-level scalar or aggregate "bag of bits".
88 static constexpr LLT scalar(unsigned SizeInBits) {
89 return LLT{Kind::ANY_SCALAR, ElementCount::getFixed(0), SizeInBits};
90 }
91
92 static LLT integer(unsigned SizeInBits) {
93 if (!getUseExtended())
94 return LLT::scalar(SizeInBits);
95
96 return LLT{Kind::INTEGER, ElementCount::getFixed(0), SizeInBits};
97 }
98
107
108 /// Get a low-level token; just a scalar with zero bits (or no size).
109 static constexpr LLT token() {
111 /*SizeInBits=*/0};
112 }
113
114 /// Get a low-level pointer in the given address space.
115 static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits) {
116 assert(SizeInBits > 0 && "invalid pointer size");
117 return LLT{Kind::POINTER, ElementCount::getFixed(0), SizeInBits,
119 }
120
121 /// Get a low-level vector of some number of elements and element width.
122 static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits) {
123 assert(!EC.isScalar() && "invalid number of vector elements");
124 return LLT{Kind::VECTOR_ANY, EC, ScalarSizeInBits};
125 }
126
127 /// Get a low-level vector of some number of elements and element type.
128 static constexpr LLT vector(ElementCount EC, LLT ScalarTy) {
129 assert(!EC.isScalar() && "invalid number of vector elements");
130 assert(!ScalarTy.isVector() && "invalid vector element type");
131
132 Kind Info = toVector(ScalarTy.Info);
133 if (ScalarTy.isPointer())
134 return LLT{Info, EC, ScalarTy.getSizeInBits().getFixedValue(),
135 ScalarTy.getAddressSpace()};
136 if (ScalarTy.isFloat())
137 return LLT{Info, EC, ScalarTy.getSizeInBits().getFixedValue(),
138 ScalarTy.getFpSemantics()};
139
140 return LLT{Info, EC, ScalarTy.getSizeInBits().getFixedValue()};
141 }
142
143 // FIXME: Remove this builder
144 static LLT floatIEEE(unsigned SizeInBits) {
145 if (!getUseExtended())
146 return LLT::scalar(SizeInBits);
147
148 switch (SizeInBits) {
149 default:
150 llvm_unreachable("Wrong SizeInBits for IEEE Floating point!");
151 case 16:
152 return float16();
153 case 32:
154 return float32();
155 case 64:
156 return float64();
157 case 128:
158 return float128();
159 }
160 }
161
162 // Get a bfloat16 value.
163 static constexpr LLT bfloat16() {
165 FpSemantics::S_BFloat};
166 }
167 /// Get a 16-bit IEEE half value.
168 static constexpr LLT float16() {
170 FpSemantics::S_IEEEhalf};
171 }
172 /// Get a 32-bit IEEE float value.
173 static constexpr LLT float32() {
175 FpSemantics::S_IEEEsingle};
176 }
177 /// Get a 64-bit IEEE double value.
178 static constexpr LLT float64() {
180 FpSemantics::S_IEEEdouble};
181 }
182
183 /// Get a 80-bit X86 floating point value.
184 static constexpr LLT x86fp80() {
186 FpSemantics::S_x87DoubleExtended};
187 }
188
189 /// Get a 128-bit IEEE quad value.
190 static constexpr LLT float128() {
191 return LLT{Kind::FLOAT, ElementCount::getFixed(0), 128,
192 FpSemantics::S_IEEEquad};
193 }
194
195 /// Get a 128-bit PowerPC double double value.
196 static constexpr LLT ppcf128() {
197 return LLT{Kind::FLOAT, ElementCount::getFixed(0), 128,
198 FpSemantics::S_PPCDoubleDouble};
199 }
200
201 /// Get a low-level fixed-width vector of some number of elements and element
202 /// width.
203 static constexpr LLT fixed_vector(unsigned NumElements,
204 unsigned ScalarSizeInBits) {
205 return vector(ElementCount::getFixed(NumElements),
206 LLT::scalar(ScalarSizeInBits));
207 }
208
209 /// Get a low-level fixed-width vector of some number of elements and element
210 /// type.
211 static constexpr LLT fixed_vector(unsigned NumElements, LLT ScalarTy) {
212 return vector(ElementCount::getFixed(NumElements), ScalarTy);
213 }
214
215 /// Get a low-level scalable vector of some number of elements and element
216 /// width.
217 static constexpr LLT scalable_vector(unsigned MinNumElements,
218 unsigned ScalarSizeInBits) {
219 return vector(ElementCount::getScalable(MinNumElements),
220 LLT::scalar(ScalarSizeInBits));
221 }
222
223 /// Get a low-level scalable vector of some number of elements and element
224 /// type.
225 static constexpr LLT scalable_vector(unsigned MinNumElements, LLT ScalarTy) {
226 return vector(ElementCount::getScalable(MinNumElements), ScalarTy);
227 }
228
229 static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy) {
230 return EC.isScalar() ? ScalarTy : LLT::vector(EC, ScalarTy);
231 }
232
233 static constexpr LLT scalarOrVector(ElementCount EC, uint64_t ScalarSize) {
234 assert(ScalarSize <= std::numeric_limits<unsigned>::max() &&
235 "Not enough bits in LLT to represent size");
236 return scalarOrVector(EC, LLT::scalar(static_cast<unsigned>(ScalarSize)));
237 }
238
239 explicit constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits)
240 : LLT() {
241 init(Info, EC, SizeInBits);
242 }
243
244 explicit constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits,
245 unsigned AddressSpace)
246 : LLT() {
247 init(Info, EC, SizeInBits, AddressSpace);
248 }
249
250 explicit constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits,
251 FpSemantics Sem)
252 : LLT() {
253 init(Info, EC, SizeInBits, Sem);
254 }
255
256 LLVM_ABI explicit LLT(MVT VT);
257 explicit constexpr LLT() : RawData(0), Info(static_cast<Kind>(0)) {}
258
259 constexpr bool isToken() const {
260 return Info == Kind::ANY_SCALAR && RawData == 0;
261 }
262 constexpr bool isValid() const { return isToken() || RawData != 0; }
263 constexpr bool isAnyScalar() const { return Info == Kind::ANY_SCALAR; }
264 constexpr bool isInteger() const { return Info == Kind::INTEGER; }
265 constexpr bool isFloat() const { return Info == Kind::FLOAT; }
266 constexpr bool isPointer() const { return Info == Kind::POINTER; }
267 constexpr bool isAnyVector() const { return Info == Kind::VECTOR_ANY; }
268 constexpr bool isIntegerVector() const {
269 return Info == Kind::VECTOR_INTEGER;
270 }
271 constexpr bool isFloatVector() const { return Info == Kind::VECTOR_FLOAT; }
272 constexpr bool isPointerVector() const {
273 return Info == Kind::VECTOR_POINTER;
274 }
275 constexpr bool isPointerOrPointerVector() const {
276 return isPointer() || isPointerVector();
277 }
278
279 constexpr bool isScalar() const {
280 return Info == Kind::ANY_SCALAR || Info == Kind::INTEGER ||
281 Info == Kind::FLOAT;
282 }
283 constexpr bool isScalar(unsigned Size) const {
284 return isScalar() && getScalarSizeInBits() == Size;
285 }
286 constexpr bool isVector() const {
287 return Info == Kind::VECTOR_ANY || Info == Kind::VECTOR_INTEGER ||
288 Info == Kind::VECTOR_FLOAT || Info == Kind::VECTOR_POINTER;
289 }
290
291 constexpr bool isInteger(unsigned Size) const {
292 return isInteger() && getScalarSizeInBits() == Size;
293 }
294
295 constexpr bool isFloat(unsigned Size) const {
296 return isFloat() && getScalarSizeInBits() == Size;
297 }
298 constexpr bool isFloat(FpSemantics Sem) const {
299 return isFloat() && getFpSemantics() == Sem;
300 }
301 // FIXME: Remove or rework this predicate
308 constexpr bool isBFloat16() const { return isFloat(FpSemantics::S_BFloat); }
309 constexpr bool isX86FP80() const {
310 return isFloat(FpSemantics::S_x87DoubleExtended);
311 }
312 constexpr bool isPPCF128() const {
313 return isFloat(FpSemantics::S_PPCDoubleDouble);
314 }
315
316 /// Returns the number of elements in a vector LLT. Must only be called on
317 /// vector types.
318 constexpr uint16_t getNumElements() const {
319 if (isScalable())
321 "Possible incorrect use of LLT::getNumElements() for "
322 "scalable vector. Scalable flag may be dropped, use "
323 "LLT::getElementCount() instead");
325 }
326
327 /// Returns true if the LLT is a scalable vector. Must only be called on
328 /// vector types.
329 constexpr bool isScalable() const {
330 assert(isVector() && "Expected a vector type");
331 return getFieldValue(VectorScalableFieldInfo);
332 }
333
334 /// Returns true if the LLT is a fixed vector. Returns false otherwise, even
335 /// if the LLT is not a vector type.
336 constexpr bool isFixedVector() const { return isVector() && !isScalable(); }
337
338 constexpr bool isFixedVector(unsigned NumElements,
339 unsigned ScalarSize) const {
340 return isFixedVector() && getNumElements() == NumElements &&
341 getScalarSizeInBits() == ScalarSize;
342 }
343
344 /// Returns true if the LLT is a scalable vector. Returns false otherwise,
345 /// even if the LLT is not a vector type.
346 constexpr bool isScalableVector() const { return isVector() && isScalable(); }
347
348 constexpr ElementCount getElementCount() const {
349 assert(isVector() && "cannot get number of elements on scalar/aggregate");
350 return ElementCount::get(getFieldValue(VectorElementsFieldInfo),
351 isScalable());
352 }
353
354 /// Returns the total size of the type. Must only be called on sized types.
355 constexpr TypeSize getSizeInBits() const {
356 if (isPointer() || isScalar())
358 auto EC = getElementCount();
359 return TypeSize(getScalarSizeInBits() * EC.getKnownMinValue(),
360 EC.isScalable());
361 }
362
363 /// Returns the total size of the type in bytes, i.e. number of whole bytes
364 /// needed to represent the size in bits. Must only be called on sized types.
365 constexpr TypeSize getSizeInBytes() const {
366 TypeSize BaseSize = getSizeInBits();
367 return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()};
368 }
369
370 LLT getScalarType() const { return isVector() ? getElementType() : *this; }
371
372 constexpr FpSemantics getFpSemantics() const {
373 assert((isFloat() || isFloatVector()) &&
374 "cannot get FP info for non float type");
375 return FpSemantics(getFieldValue(FpSemanticFieldInfo));
376 }
377
378 constexpr Kind getKind() const { return Info; }
379
380 /// Returns a vector with the same number of elements but the new element
381 /// type. Must only be called on vector types.
382 constexpr LLT changeVectorElementType(LLT NewEltTy) const {
383 return LLT::vector(getElementCount(), NewEltTy);
384 }
385
386 /// If this type is a vector, return a vector with the same number of elements
387 /// but the new element type. Otherwise, return the new element type.
388 constexpr LLT changeElementType(LLT NewEltTy) const {
389 return isVector() ? changeVectorElementType(NewEltTy) : NewEltTy;
390 }
391
392 /// If this type is a vector, return a vector with the same number of elements
393 /// but the new element size. Otherwise, return the new element type. Invalid
394 /// for pointer types. For these, use changeElementType.
395 LLT changeElementSize(unsigned NewEltSize) const {
397 "invalid to directly change element size for pointers");
398 if (isVector())
400 getElementType().changeElementSize(NewEltSize));
401
402 if (isInteger())
403 return LLT::integer(NewEltSize);
404
405 if (isFloatIEEE())
406 return LLT::floatIEEE(NewEltSize);
407
408 return LLT::scalar(NewEltSize);
409 }
410
411 /// Return a vector with the same element type and the new element count. Must
412 /// be called on vector types.
414 assert(isVector() &&
415 "cannot change vector element count of non-vector type");
416 return LLT::vector(EC, getElementType());
417 }
418
419 /// Return a vector or scalar with the same element type and the new element
420 /// count.
424
425 LLT changeElementCount(unsigned NumElements) const {
426 return changeElementCount(ElementCount::getFixed(NumElements));
427 }
428
429 /// Return a type that is \p Factor times smaller. Reduces the number of
430 /// elements if this is a vector, or the bitwidth for scalar/pointers. Does
431 /// not attempt to handle cases that aren't evenly divisible.
432 LLT divide(int Factor) const {
433 assert(Factor != 1);
434 assert((!isScalar() || getScalarSizeInBits() != 0) && !isFloat() &&
435 "cannot divide scalar of size zero and floats");
436 if (isVector()) {
437 assert(getElementCount().isKnownMultipleOf(Factor));
438 return scalarOrVector(getElementCount().divideCoefficientBy(Factor),
440 }
441
442 assert(getScalarSizeInBits() % Factor == 0);
443 if (isInteger())
444 return integer(getScalarSizeInBits() / Factor);
445
446 return scalar(getScalarSizeInBits() / Factor);
447 }
448
449 /// Produce a vector type that is \p Factor times bigger, preserving the
450 /// element type. For a scalar or pointer, this will produce a new vector with
451 /// \p Factor elements.
452 LLT multiplyElements(int Factor) const {
453 if (isVector()) {
454 return scalarOrVector(getElementCount().multiplyCoefficientBy(Factor),
456 }
457
458 return fixed_vector(Factor, *this);
459 }
460
461 constexpr bool isByteSized() const {
463 }
464
465 constexpr unsigned getScalarSizeInBits() const {
467 return getFieldValue(PointerSizeFieldInfo);
468 return getFieldValue(ScalarSizeFieldInfo);
469 }
470
471 constexpr unsigned getAddressSpace() const {
473 "cannot get address space of non-pointer type");
474 return getFieldValue(PointerAddressSpaceFieldInfo);
475 }
476
477 /// Returns the vector's element type. Only valid for vector types.
479 assert(isVector() && "cannot get element type of scalar/aggregate");
480 if (isPointerVector())
482
483 if (isFloatVector())
485
486 if (isIntegerVector())
488
489 return scalar(getScalarSizeInBits());
490 }
491
493 if (isPointer() || isPointerVector())
494 return *this;
495
496 if (isVector())
498
499 return integer(getSizeInBits());
500 }
501
502 LLVM_ABI void print(raw_ostream &OS) const;
503
504#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
505 LLVM_DUMP_METHOD void dump() const;
506#endif
507
508 bool operator==(const LLT &RHS) const {
509 if (isAnyScalar() || RHS.isAnyScalar())
510 return isScalar() == RHS.isScalar() &&
511 getScalarSizeInBits() == RHS.getScalarSizeInBits();
512
513 if (isVector() && RHS.isVector())
514 return getElementType() == RHS.getElementType() &&
515 getElementCount() == RHS.getElementCount();
516
517 return Info == RHS.Info && RawData == RHS.RawData;
518 }
519
520 bool operator!=(const LLT &RHS) const { return !(*this == RHS); }
521
522 friend struct DenseMapInfo<LLT>;
524
525private:
526 /// LLT is packed into 64 bits as follows:
527 /// RawData : 60
528 /// Info : 4
529 /// RawData remaining for Kind-specific data, packed in
530 /// bitfields as described below. As there isn't a simple portable way to pack
531 /// bits into bitfields, here the different fields in the packed structure is
532 /// described in static const *Field variables. Each of these variables
533 /// is a 2-element array, with the first element describing the bitfield size
534 /// and the second element describing the bitfield offset.
535 ///
536 /*
537 --- LLT ---
538
539 63 56 47 39 31 23 15 7 0
540 | | | | | | | | |
541 |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|
542 %%%% (1)
543 .... ........ ........ ........ .... (2)
544 **** ******** **** (3)
545 ~~~~ ~~~~~~~~ ~~~~~~~~ ~~~~ (4)
546 #### #### (5)
547 ^^^^ ^^^^^^^^ ^^^^ (6)
548 @ (7)
549
550 (1) Kind: [63:60]
551 (2) ScalarSize: [59:28]
552 (3) PointerSize: [59:44]
553 (4) PointerAddressSpace: [43:20]
554 (5) FpSemantics: [27:20]
555 (6) VectorElements: [19:4]
556 (7) VectorScalable: [0:0]
557
558 */
559
560 /// This is how the LLT are packed per Kind:
561 /// * Invalid:
562 /// Info: [63:60] = 0
563 /// RawData: [59:0] = 0;
564 ///
565 /// * Non-pointer scalar (isPointer == 0 && isVector == 0):
566 /// Info: [63:60];
567 /// SizeOfElement: [59:28];
568 /// FpSemantics: [27:20];
569 ///
570 /// * Pointer (isPointer == 1 && isVector == 0):
571 /// Info: [63:60];
572 /// SizeInBits: [59:44];
573 /// AddressSpace: [43:20];
574 ///
575 /// * Vector-of-non-pointer (isPointer == 0 && isVector == 1):
576 /// Info: [63:60]
577 /// SizeOfElement: [59:28];
578 /// FpSemantics: [27:20];
579 /// VectorElements: [19:4];
580 /// Scalable: [0:0];
581 ///
582 /// * Vector-of-pointer (isPointer == 1 && isVector == 1):
583 /// Info: [63:60];
584 /// SizeInBits: [59:44];
585 /// AddressSpace: [43:20];
586 /// VectorElements: [19:4];
587 /// Scalable: [0:0];
588
589 /// BitFieldInfo: {Size, Offset}
590 typedef int BitFieldInfo[2];
592 static constexpr BitFieldInfo VectorScalableFieldInfo{1, 0};
593 static constexpr BitFieldInfo VectorElementsFieldInfo{16, 4};
594 static constexpr BitFieldInfo FpSemanticFieldInfo{8, 20};
595 static constexpr BitFieldInfo PointerAddressSpaceFieldInfo{24, 20};
596 static constexpr BitFieldInfo ScalarSizeFieldInfo{32, 28};
597 static constexpr BitFieldInfo PointerSizeFieldInfo{16, 44};
598
599 uint64_t RawData : 60;
600 Kind Info : 4;
601
602 static constexpr uint64_t getMask(const BitFieldInfo FieldInfo) {
603 const int FieldSizeInBits = FieldInfo[0];
604 return (((uint64_t)1) << FieldSizeInBits) - 1;
605 }
606 static constexpr uint64_t maskAndShift(uint64_t Val, uint64_t Mask,
607 uint8_t Shift) {
608 assert(Val <= Mask && "Value too large for field");
609 return (Val & Mask) << Shift;
610 }
611 static constexpr uint64_t maskAndShift(uint64_t Val,
612 const BitFieldInfo FieldInfo) {
613 return maskAndShift(Val, getMask(FieldInfo), FieldInfo[1]);
614 }
615
616 constexpr uint64_t getFieldValue(const BitFieldInfo FieldInfo) const {
617 return getMask(FieldInfo) & (RawData >> FieldInfo[1]);
618 }
619
620 // Init for scalar and integer single or vector types
621 constexpr void init(Kind Info, ElementCount EC, uint64_t SizeInBits) {
622 assert(SizeInBits <= std::numeric_limits<unsigned>::max() &&
623 "Not enough bits in LLT to represent size");
624 assert((Info == Kind::ANY_SCALAR || Info == Kind::INTEGER ||
625 Info == Kind::VECTOR_ANY || Info == Kind::VECTOR_INTEGER) &&
626 "Called initializer for wrong LLT Kind");
627 this->Info = Info;
628 RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo);
629
630 if (Info == Kind::VECTOR_ANY || Info == Kind::VECTOR_INTEGER) {
631 RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo) |
632 maskAndShift(EC.getKnownMinValue(), VectorElementsFieldInfo) |
633 maskAndShift(EC.isScalable() ? 1 : 0, VectorScalableFieldInfo);
634 }
635 }
636
637 // Init pointer or pointer vector
638 constexpr void init(Kind Info, ElementCount EC, uint64_t SizeInBits,
639 unsigned AddressSpace) {
640 assert(SizeInBits <= std::numeric_limits<unsigned>::max() &&
641 "Not enough bits in LLT to represent size");
642 assert((Info == Kind::POINTER || Info == Kind::VECTOR_POINTER) &&
643 "Called initializer for wrong LLT Kind");
644 this->Info = Info;
645 RawData = maskAndShift(SizeInBits, PointerSizeFieldInfo) |
646 maskAndShift(AddressSpace, PointerAddressSpaceFieldInfo);
647
648 if (Info == Kind::VECTOR_POINTER) {
649 RawData |= maskAndShift(EC.getKnownMinValue(), VectorElementsFieldInfo) |
650 maskAndShift(EC.isScalable() ? 1 : 0, VectorScalableFieldInfo);
651 }
652 }
653
654 constexpr void init(Kind Info, ElementCount EC, uint64_t SizeInBits,
655 FpSemantics Sem) {
656 assert(SizeInBits <= std::numeric_limits<unsigned>::max() &&
657 "Not enough bits in LLT to represent size");
658 assert((Info == Kind::FLOAT || Info == Kind::VECTOR_FLOAT) &&
659 "Called initializer for wrong LLT Kind");
660 this->Info = Info;
661 RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo) |
662 maskAndShift((uint64_t)Sem, FpSemanticFieldInfo);
663
664 if (Info == Kind::VECTOR_FLOAT) {
665 RawData |= maskAndShift(EC.getKnownMinValue(), VectorElementsFieldInfo) |
666 maskAndShift(EC.isScalable() ? 1 : 0, VectorScalableFieldInfo);
667 }
668 }
669
670public:
671 constexpr uint64_t getUniqueRAWLLTData() const {
672 return ((uint64_t)RawData) | ((uint64_t)Info) << 60;
673 }
674
675 static bool getUseExtended() { return ExtendedLLT; }
676 static void setUseExtended(bool Enable) { ExtendedLLT = Enable; }
677
678private:
679 static bool ExtendedLLT;
680};
681
682inline raw_ostream &operator<<(raw_ostream &OS, const LLT &Ty) {
683 Ty.print(OS);
684 return OS;
685}
686
687template <> struct DenseMapInfo<LLT> {
688 static inline LLT getEmptyKey() {
689 LLT Invalid;
691 return Invalid;
692 }
693 static inline LLT getTombstoneKey() {
694 LLT Invalid;
696 return Invalid;
697 }
698 static inline unsigned getHashValue(const LLT &Ty) {
699 uint64_t Val = Ty.getUniqueRAWLLTData();
701 }
702 static bool isEqual(const LLT &LHS, const LLT &RHS) { return LHS == RHS; }
703};
704
705} // namespace llvm
706
707#endif // LLVM_CODEGEN_LOWLEVELTYPE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:661
This file defines DenseMapInfo traits for DenseMap.
static std::pair< Value *, APInt > getMask(Value *WideMask, unsigned Factor, ElementCount LeafValueEC)
Value * RHS
Value * LHS
This file implements the C++20 <bit> header.
static LLVM_ABI const llvm::fltSemantics & EnumToSemantics(Semantics S)
Definition APFloat.cpp:98
static LLVM_ABI unsigned getSizeInBits(const fltSemantics &Sem)
Returns the size of the floating point number (in bits) in the given semantics.
Definition APFloat.cpp:278
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition TypeSize.h:312
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:309
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition TypeSize.h:315
static constexpr LLT float64()
Get a 64-bit IEEE double value.
constexpr bool isFloatVector() const
LLT changeElementCount(ElementCount EC) const
Return a vector or scalar with the same element type and the new element count.
static constexpr Kind toVector(Kind Ty)
constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits, FpSemantics Sem)
LLVM_ABI void print(raw_ostream &OS) const
static constexpr LLT x86fp80()
Get a 80-bit X86 floating point value.
constexpr bool isBFloat16() const
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
constexpr bool isFixedVector(unsigned NumElements, unsigned ScalarSize) const
static constexpr LLT scalarOrVector(ElementCount EC, uint64_t ScalarSize)
bool operator==(const LLT &RHS) const
constexpr unsigned getScalarSizeInBits() const
static bool getUseExtended()
constexpr bool isScalar() const
constexpr bool isAnyVector() const
static constexpr LLT scalable_vector(unsigned MinNumElements, unsigned ScalarSizeInBits)
Get a low-level scalable vector of some number of elements and element width.
constexpr Kind getKind() const
LLT multiplyElements(int Factor) const
Produce a vector type that is Factor times bigger, preserving the element type.
APFloat::Semantics FpSemantics
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
LLT getScalarType() const
constexpr bool isPointerVector() const
constexpr bool isInteger() const
static void setUseExtended(bool Enable)
constexpr bool isIntegerVector() const
constexpr FpSemantics getFpSemantics() const
bool operator!=(const LLT &RHS) const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isValid() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isFloat() const
friend class GISelInstProfileBuilder
constexpr bool isToken() const
constexpr bool isX86FP80() const
static constexpr LLT float128()
Get a 128-bit IEEE quad value.
constexpr bool isVector() const
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr bool isScalable() const
Returns true if the LLT is a scalable vector.
constexpr uint64_t getUniqueRAWLLTData() const
constexpr bool isByteSized() const
LLT changeToInteger() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr bool isFloat(FpSemantics Sem) const
constexpr bool isPointer() const
constexpr LLT()
constexpr bool isAnyScalar() const
static constexpr LLT vector(ElementCount EC, LLT ScalarTy)
Get a low-level vector of some number of elements and element type.
constexpr bool isInteger(unsigned Size) const
static constexpr LLT ppcf128()
Get a 128-bit PowerPC double double value.
constexpr ElementCount getElementCount() const
static constexpr LLT fixed_vector(unsigned NumElements, LLT ScalarTy)
Get a low-level fixed-width vector of some number of elements and element type.
LLT divide(int Factor) const
Return a type that is Factor times smaller.
static constexpr Kind toScalar(Kind Ty)
static constexpr LLT float16()
Get a 16-bit IEEE half value.
constexpr unsigned getAddressSpace() const
constexpr bool isFloat(unsigned Size) const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isPointerOrPointerVector() const
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static constexpr LLT token()
Get a low-level token; just a scalar with zero bits (or no size).
constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits, unsigned AddressSpace)
static LLT integer(unsigned SizeInBits)
constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits)
LLVM_DUMP_METHOD void dump() const
constexpr bool isFloatIEEE() const
static constexpr LLT bfloat16()
LLT changeElementCount(unsigned NumElements) const
constexpr LLT changeVectorElementType(LLT NewEltTy) const
Returns a vector with the same number of elements but the new element type.
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
static constexpr LLT scalable_vector(unsigned MinNumElements, LLT ScalarTy)
Get a low-level scalable vector of some number of elements and element type.
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
constexpr bool isScalar(unsigned Size) const
LLT changeVectorElementCount(ElementCount EC) const
Return a vector with the same element type and the new element count.
static constexpr LLT float32()
Get a 32-bit IEEE float value.
constexpr bool isPPCF128() const
static LLT floatIEEE(unsigned SizeInBits)
static LLT floatingPoint(const FpSemantics &Sem)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
Machine Value Type.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
Definition TypeSize.h:180
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
Definition Error.cpp:173
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
constexpr int bit_width_constexpr(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
Definition bit.h:335
@ Enable
Enable colors.
Definition WithColor.h:47
static bool isEqual(const LLT &LHS, const LLT &RHS)
static unsigned getHashValue(const LLT &Ty)
An information struct used to provide DenseMap with the various necessary components for a given valu...