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