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
309 bool isFloat16() const {
310 if (!getUseExtended())
311 return isAnyScalar() && getSizeInBits() == 16;
313 }
314 bool isFloat32() const {
315 if (!getUseExtended())
316 return isAnyScalar() && getSizeInBits() == 32;
318 }
319 bool isFloat64() const {
320 if (!getUseExtended())
321 return isAnyScalar() && getSizeInBits() == 64;
323 }
324 bool isFloat128() const {
325 if (!getUseExtended())
326 return isAnyScalar() && getSizeInBits() == 128;
328 }
329 bool isBFloat16() const {
330 if (!getUseExtended())
331 return false;
332 return isFloat(FpSemantics::S_BFloat);
333 }
334 bool isX86FP80() const {
335 if (!getUseExtended())
336 return false;
337 return isFloat(FpSemantics::S_x87DoubleExtended);
338 }
339 bool isPPCF128() const {
340 if (!getUseExtended())
341 return false;
342 return isFloat(FpSemantics::S_PPCDoubleDouble);
343 }
344
345 /// Returns the number of elements in a vector LLT. Must only be called on
346 /// vector types.
347 constexpr uint16_t getNumElements() const {
348 if (isScalable())
350 "Possible incorrect use of LLT::getNumElements() for "
351 "scalable vector. Scalable flag may be dropped, use "
352 "LLT::getElementCount() instead");
354 }
355
356 /// Returns true if the LLT is a scalable vector. Must only be called on
357 /// vector types.
358 constexpr bool isScalable() const {
359 assert(isVector() && "Expected a vector type");
360 return getFieldValue(VectorScalableFieldInfo);
361 }
362
363 /// Returns true if the LLT is a fixed vector. Returns false otherwise, even
364 /// if the LLT is not a vector type.
365 constexpr bool isFixedVector() const { return isVector() && !isScalable(); }
366
367 constexpr bool isFixedVector(unsigned NumElements,
368 unsigned ScalarSize) const {
369 return isFixedVector() && getNumElements() == NumElements &&
370 getScalarSizeInBits() == ScalarSize;
371 }
372
373 /// Returns true if the LLT is a scalable vector. Returns false otherwise,
374 /// even if the LLT is not a vector type.
375 constexpr bool isScalableVector() const { return isVector() && isScalable(); }
376
377 constexpr ElementCount getElementCount() const {
378 assert(isVector() && "cannot get number of elements on scalar/aggregate");
379 return ElementCount::get(getFieldValue(VectorElementsFieldInfo),
380 isScalable());
381 }
382
383 /// Returns the total size of the type. Must only be called on sized types.
384 constexpr TypeSize getSizeInBits() const {
385 if (isPointer() || isScalar())
387 auto EC = getElementCount();
388 return TypeSize(getScalarSizeInBits() * EC.getKnownMinValue(),
389 EC.isScalable());
390 }
391
392 /// Returns the total size of the type in bytes, i.e. number of whole bytes
393 /// needed to represent the size in bits. Must only be called on sized types.
394 constexpr TypeSize getSizeInBytes() const {
395 TypeSize BaseSize = getSizeInBits();
396 return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()};
397 }
398
399 LLT getScalarType() const { return isVector() ? getElementType() : *this; }
400
401 constexpr FpSemantics getFpSemantics() const {
402 assert((isFloat() || isFloatVector()) &&
403 "cannot get FP info for non float type");
404 return FpSemantics(getFieldValue(FpSemanticFieldInfo));
405 }
406
407 constexpr Kind getKind() const { return Info; }
408
409 /// Returns a vector with the same number of elements but the new element
410 /// type. Must only be called on vector types.
411 constexpr LLT changeVectorElementType(LLT NewEltTy) const {
412 return LLT::vector(getElementCount(), NewEltTy);
413 }
414
415 /// If this type is a vector, return a vector with the same number of elements
416 /// but the new element type. Otherwise, return the new element type.
417 constexpr LLT changeElementType(LLT NewEltTy) const {
418 return isVector() ? changeVectorElementType(NewEltTy) : NewEltTy;
419 }
420
421 /// If this type is a vector, return a vector with the same number of elements
422 /// but the new element size. Otherwise, return the new element type. Invalid
423 /// for pointer types. For these, use changeElementType.
424 LLT changeElementSize(unsigned NewEltSize) const {
426 "invalid to directly change element size for pointers");
427 if (isVector())
429 getElementType().changeElementSize(NewEltSize));
430
431 if (isInteger())
432 return LLT::integer(NewEltSize);
433
434 if (isFloatIEEE())
435 return LLT::floatIEEE(NewEltSize);
436
437 return LLT::scalar(NewEltSize);
438 }
439
440 /// Return a vector with the same element type and the new element count. Must
441 /// be called on vector types.
443 assert(isVector() &&
444 "cannot change vector element count of non-vector type");
445 return LLT::vector(EC, getElementType());
446 }
447
448 /// Return a vector or scalar with the same element type and the new element
449 /// count.
453
454 LLT changeElementCount(unsigned NumElements) const {
455 return changeElementCount(ElementCount::getFixed(NumElements));
456 }
457
458 /// Return a type that is \p Factor times smaller. Reduces the number of
459 /// elements if this is a vector, or the bitwidth for scalar/pointers. Does
460 /// not attempt to handle cases that aren't evenly divisible.
461 LLT divide(int Factor) const {
462 assert(Factor != 1);
463 assert((!isScalar() || getScalarSizeInBits() != 0) && !isFloat() &&
464 "cannot divide scalar of size zero and floats");
465 if (isVector()) {
466 assert(getElementCount().isKnownMultipleOf(Factor));
467 return scalarOrVector(getElementCount().divideCoefficientBy(Factor),
469 }
470
471 assert(getScalarSizeInBits() % Factor == 0);
472 if (isInteger())
473 return integer(getScalarSizeInBits() / Factor);
474
475 return scalar(getScalarSizeInBits() / Factor);
476 }
477
478 /// Produce a vector type that is \p Factor times bigger, preserving the
479 /// element type. For a scalar or pointer, this will produce a new vector with
480 /// \p Factor elements.
481 LLT multiplyElements(int Factor) const {
482 if (isVector()) {
483 return scalarOrVector(getElementCount().multiplyCoefficientBy(Factor),
485 }
486
487 return fixed_vector(Factor, *this);
488 }
489
490 constexpr bool isByteSized() const {
492 }
493
494 constexpr unsigned getScalarSizeInBits() const {
496 return getFieldValue(PointerSizeFieldInfo);
497 return getFieldValue(ScalarSizeFieldInfo);
498 }
499
500 constexpr unsigned getAddressSpace() const {
502 "cannot get address space of non-pointer type");
503 return getFieldValue(PointerAddressSpaceFieldInfo);
504 }
505
506 /// Returns the vector's element type. Only valid for vector types.
508 assert(isVector() && "cannot get element type of scalar/aggregate");
509 if (isPointerVector())
511
512 if (isFloatVector())
514
515 if (isIntegerVector())
517
518 return scalar(getScalarSizeInBits());
519 }
520
522 if (isPointer() || isPointerVector())
523 return *this;
524
525 if (isVector())
527
528 return integer(getSizeInBits());
529 }
530
531 LLVM_ABI void print(raw_ostream &OS) const;
532
533#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
534 LLVM_DUMP_METHOD void dump() const;
535#endif
536
537 bool operator==(const LLT &RHS) const {
538 if (isAnyScalar() || RHS.isAnyScalar())
539 return isScalar() == RHS.isScalar() &&
540 getScalarSizeInBits() == RHS.getScalarSizeInBits();
541
542 if (isVector() && RHS.isVector())
543 return getElementType() == RHS.getElementType() &&
544 getElementCount() == RHS.getElementCount();
545
546 return Info == RHS.Info && RawData == RHS.RawData;
547 }
548
549 bool operator!=(const LLT &RHS) const { return !(*this == RHS); }
550
551 friend struct DenseMapInfo<LLT>;
553
554private:
555 /// LLT is packed into 64 bits as follows:
556 /// RawData : 60
557 /// Info : 4
558 /// RawData remaining for Kind-specific data, packed in
559 /// bitfields as described below. As there isn't a simple portable way to pack
560 /// bits into bitfields, here the different fields in the packed structure is
561 /// described in static const *Field variables. Each of these variables
562 /// is a 2-element array, with the first element describing the bitfield size
563 /// and the second element describing the bitfield offset.
564 ///
565 /*
566 --- LLT ---
567
568 63 56 47 39 31 23 15 7 0
569 | | | | | | | | |
570 |xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|xxxxxxxx|
571 %%%% (1)
572 .... ........ ........ ........ .... (2)
573 **** ******** **** (3)
574 ~~~~ ~~~~~~~~ ~~~~~~~~ ~~~~ (4)
575 #### #### (5)
576 ^^^^ ^^^^^^^^ ^^^^ (6)
577 @ (7)
578
579 (1) Kind: [63:60]
580 (2) ScalarSize: [59:28]
581 (3) PointerSize: [59:44]
582 (4) PointerAddressSpace: [43:20]
583 (5) FpSemantics: [27:20]
584 (6) VectorElements: [19:4]
585 (7) VectorScalable: [0:0]
586
587 */
588
589 /// This is how the LLT are packed per Kind:
590 /// * Invalid:
591 /// Info: [63:60] = 0
592 /// RawData: [59:0] = 0;
593 ///
594 /// * Non-pointer scalar (isPointer == 0 && isVector == 0):
595 /// Info: [63:60];
596 /// SizeOfElement: [59:28];
597 /// FpSemantics: [27:20];
598 ///
599 /// * Pointer (isPointer == 1 && isVector == 0):
600 /// Info: [63:60];
601 /// SizeInBits: [59:44];
602 /// AddressSpace: [43:20];
603 ///
604 /// * Vector-of-non-pointer (isPointer == 0 && isVector == 1):
605 /// Info: [63:60]
606 /// SizeOfElement: [59:28];
607 /// FpSemantics: [27:20];
608 /// VectorElements: [19:4];
609 /// Scalable: [0:0];
610 ///
611 /// * Vector-of-pointer (isPointer == 1 && isVector == 1):
612 /// Info: [63:60];
613 /// SizeInBits: [59:44];
614 /// AddressSpace: [43:20];
615 /// VectorElements: [19:4];
616 /// Scalable: [0:0];
617
618 /// BitFieldInfo: {Size, Offset}
619 typedef int BitFieldInfo[2];
621 static constexpr BitFieldInfo VectorScalableFieldInfo{1, 0};
622 static constexpr BitFieldInfo VectorElementsFieldInfo{16, 4};
623 static constexpr BitFieldInfo FpSemanticFieldInfo{8, 20};
624 static constexpr BitFieldInfo PointerAddressSpaceFieldInfo{24, 20};
625 static constexpr BitFieldInfo ScalarSizeFieldInfo{32, 28};
626 static constexpr BitFieldInfo PointerSizeFieldInfo{16, 44};
627
628 uint64_t RawData : 60;
629 Kind Info : 4;
630
631 static constexpr uint64_t getMask(const BitFieldInfo FieldInfo) {
632 const int FieldSizeInBits = FieldInfo[0];
633 return (((uint64_t)1) << FieldSizeInBits) - 1;
634 }
635 static constexpr uint64_t maskAndShift(uint64_t Val, uint64_t Mask,
636 uint8_t Shift) {
637 assert(Val <= Mask && "Value too large for field");
638 return (Val & Mask) << Shift;
639 }
640 static constexpr uint64_t maskAndShift(uint64_t Val,
641 const BitFieldInfo FieldInfo) {
642 return maskAndShift(Val, getMask(FieldInfo), FieldInfo[1]);
643 }
644
645 constexpr uint64_t getFieldValue(const BitFieldInfo FieldInfo) const {
646 return getMask(FieldInfo) & (RawData >> FieldInfo[1]);
647 }
648
649 // Init for scalar and integer single or vector types
650 constexpr void init(Kind Info, ElementCount EC, uint64_t SizeInBits) {
651 assert(SizeInBits <= std::numeric_limits<unsigned>::max() &&
652 "Not enough bits in LLT to represent size");
653 assert((Info == Kind::ANY_SCALAR || Info == Kind::INTEGER ||
654 Info == Kind::VECTOR_ANY || Info == Kind::VECTOR_INTEGER) &&
655 "Called initializer for wrong LLT Kind");
656 this->Info = Info;
657 RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo);
658
659 if (Info == Kind::VECTOR_ANY || Info == Kind::VECTOR_INTEGER) {
660 RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo) |
661 maskAndShift(EC.getKnownMinValue(), VectorElementsFieldInfo) |
662 maskAndShift(EC.isScalable() ? 1 : 0, VectorScalableFieldInfo);
663 }
664 }
665
666 // Init pointer or pointer vector
667 constexpr void init(Kind Info, ElementCount EC, uint64_t SizeInBits,
668 unsigned AddressSpace) {
669 assert(SizeInBits <= std::numeric_limits<unsigned>::max() &&
670 "Not enough bits in LLT to represent size");
671 assert((Info == Kind::POINTER || Info == Kind::VECTOR_POINTER) &&
672 "Called initializer for wrong LLT Kind");
673 this->Info = Info;
674 RawData = maskAndShift(SizeInBits, PointerSizeFieldInfo) |
675 maskAndShift(AddressSpace, PointerAddressSpaceFieldInfo);
676
677 if (Info == Kind::VECTOR_POINTER) {
678 RawData |= maskAndShift(EC.getKnownMinValue(), VectorElementsFieldInfo) |
679 maskAndShift(EC.isScalable() ? 1 : 0, VectorScalableFieldInfo);
680 }
681 }
682
683 constexpr void init(Kind Info, ElementCount EC, uint64_t SizeInBits,
684 FpSemantics Sem) {
685 assert(SizeInBits <= std::numeric_limits<unsigned>::max() &&
686 "Not enough bits in LLT to represent size");
687 assert((Info == Kind::FLOAT || Info == Kind::VECTOR_FLOAT) &&
688 "Called initializer for wrong LLT Kind");
689 this->Info = Info;
690 RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo) |
691 maskAndShift((uint64_t)Sem, FpSemanticFieldInfo);
692
693 if (Info == Kind::VECTOR_FLOAT) {
694 RawData |= maskAndShift(EC.getKnownMinValue(), VectorElementsFieldInfo) |
695 maskAndShift(EC.isScalable() ? 1 : 0, VectorScalableFieldInfo);
696 }
697 }
698
699public:
700 constexpr uint64_t getUniqueRAWLLTData() const {
701 return ((uint64_t)RawData) | ((uint64_t)Info) << 60;
702 }
703
704 static bool getUseExtended() { return ExtendedLLT; }
705 static void setUseExtended(bool Enable) { ExtendedLLT = Enable; }
706
707private:
708 static bool ExtendedLLT;
709};
710
711inline raw_ostream &operator<<(raw_ostream &OS, const LLT &Ty) {
712 Ty.print(OS);
713 return OS;
714}
715
716template <> struct DenseMapInfo<LLT> {
717 static inline LLT getEmptyKey() {
718 LLT Invalid;
720 return Invalid;
721 }
722 static inline LLT getTombstoneKey() {
723 LLT Invalid;
725 return Invalid;
726 }
727 static inline unsigned getHashValue(const LLT &Ty) {
728 uint64_t Val = Ty.getUniqueRAWLLTData();
730 }
731 static bool isEqual(const LLT &LHS, const LLT &RHS) { return LHS == RHS; }
732};
733
734} // namespace llvm
735
736#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 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()
bool isX86FP80() const
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
bool isBFloat16() 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
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)
bool isPPCF128() const
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()
bool isFloat16() const
bool isFloat32() const
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.
bool isFloat128() const
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.
bool isFloat64() 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:337
@ 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...