LLVM 24.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 <atomic>
39#include <cassert>
40
41namespace llvm {
42
43class Type;
44class raw_ostream;
45
46class LLT {
47public:
49
61
62 constexpr static Kind toVector(Kind Ty) {
63 if (Ty == Kind::POINTER)
65
66 if (Ty == Kind::INTEGER)
68
69 if (Ty == Kind::FLOAT)
70 return Kind::VECTOR_FLOAT;
71
72 return Kind::VECTOR_ANY;
73 }
74
75 constexpr static Kind toScalar(Kind Ty) {
76 if (Ty == Kind::VECTOR_POINTER)
77 return Kind::POINTER;
78
79 if (Ty == Kind::VECTOR_INTEGER)
80 return Kind::INTEGER;
81
82 if (Ty == Kind::VECTOR_FLOAT)
83 return Kind::FLOAT;
84
85 return Kind::ANY_SCALAR;
86 }
87
88 /// Get a low-level scalar or aggregate "bag of bits".
89 static constexpr LLT scalar(unsigned SizeInBits) {
90 return LLT{Kind::ANY_SCALAR, ElementCount::getFixed(0), SizeInBits};
91 }
92
93 static LLT integer(unsigned SizeInBits) {
94 if (!getUseExtended())
95 return LLT::scalar(SizeInBits);
96
97 return LLT{Kind::INTEGER, ElementCount::getFixed(0), SizeInBits};
98 }
99
108
109 /// Get a low-level token; just a scalar with zero bits (or no size).
110 static constexpr LLT token() {
112 /*SizeInBits=*/0};
113 }
114
115 /// Get a low-level pointer in the given address space.
116 static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits) {
117 assert(SizeInBits > 0 && "invalid pointer size");
118 return LLT{Kind::POINTER, ElementCount::getFixed(0), SizeInBits,
120 }
121
122 /// Get a low-level vector of some number of elements and element width.
123 static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits) {
124 assert(!EC.isScalar() && "invalid number of vector elements");
125 return LLT{Kind::VECTOR_ANY, EC, ScalarSizeInBits};
126 }
127
128 /// Get a low-level vector of some number of elements and element type.
129 static constexpr LLT vector(ElementCount EC, LLT ScalarTy) {
130 assert(!EC.isScalar() && "invalid number of vector elements");
131 assert(!ScalarTy.isVector() && "invalid vector element type");
132
133 Kind Info = toVector(ScalarTy.Info);
134 if (ScalarTy.isPointer())
135 return LLT{Info, EC, ScalarTy.getSizeInBits().getFixedValue(),
136 ScalarTy.getAddressSpace()};
137 if (ScalarTy.isFloat())
138 return LLT{Info, EC, ScalarTy.getSizeInBits().getFixedValue(),
139 ScalarTy.getFpSemantics()};
140
141 return LLT{Info, EC, ScalarTy.getSizeInBits().getFixedValue()};
142 }
143
144 // FIXME: Remove this builder
145 static LLT floatIEEE(unsigned SizeInBits) {
146 if (!getUseExtended())
147 return LLT::scalar(SizeInBits);
148
149 switch (SizeInBits) {
150 default:
151 llvm_unreachable("Wrong SizeInBits for IEEE Floating point!");
152 case 16:
153 return float16();
154 case 32:
155 return float32();
156 case 64:
157 return float64();
158 case 128:
159 return float128();
160 }
161 }
162
163 // Get a bfloat16 value.
164 static constexpr LLT bfloat16() {
166 FpSemantics::S_BFloat};
167 }
168 /// Get a 16-bit IEEE half value.
169 static constexpr LLT float16() {
171 FpSemantics::S_IEEEhalf};
172 }
173 /// Get a 32-bit IEEE float value.
174 static constexpr LLT float32() {
176 FpSemantics::S_IEEEsingle};
177 }
178 /// Get a 64-bit IEEE double value.
179 static constexpr LLT float64() {
181 FpSemantics::S_IEEEdouble};
182 }
183
184 /// Get a 80-bit X86 floating point value.
185 static constexpr LLT x86fp80() {
187 FpSemantics::S_x87DoubleExtended};
188 }
189
190 /// Get a 128-bit IEEE quad value.
191 static constexpr LLT float128() {
192 return LLT{Kind::FLOAT, ElementCount::getFixed(0), 128,
193 FpSemantics::S_IEEEquad};
194 }
195
196 /// Get a 128-bit PowerPC double double value.
197 static constexpr LLT ppcf128() {
198 return LLT{Kind::FLOAT, ElementCount::getFixed(0), 128,
199 FpSemantics::S_PPCDoubleDouble};
200 }
201
202 /// Get a low-level fixed-width vector of some number of elements and element
203 /// width.
204 static constexpr LLT fixed_vector(unsigned NumElements,
205 unsigned ScalarSizeInBits) {
206 return vector(ElementCount::getFixed(NumElements),
207 LLT::scalar(ScalarSizeInBits));
208 }
209
210 /// Get a low-level fixed-width vector of some number of elements and element
211 /// type.
212 static constexpr LLT fixed_vector(unsigned NumElements, LLT ScalarTy) {
213 return vector(ElementCount::getFixed(NumElements), ScalarTy);
214 }
215
216 /// Get a low-level scalable vector of some number of elements and element
217 /// width.
218 static constexpr LLT scalable_vector(unsigned MinNumElements,
219 unsigned ScalarSizeInBits) {
220 return vector(ElementCount::getScalable(MinNumElements),
221 LLT::scalar(ScalarSizeInBits));
222 }
223
224 /// Get a low-level scalable vector of some number of elements and element
225 /// type.
226 static constexpr LLT scalable_vector(unsigned MinNumElements, LLT ScalarTy) {
227 return vector(ElementCount::getScalable(MinNumElements), ScalarTy);
228 }
229
230 static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy) {
231 return EC.isScalar() ? ScalarTy : LLT::vector(EC, ScalarTy);
232 }
233
234 static constexpr LLT scalarOrVector(ElementCount EC, uint64_t ScalarSize) {
235 assert(ScalarSize <= std::numeric_limits<unsigned>::max() &&
236 "Not enough bits in LLT to represent size");
237 return scalarOrVector(EC, LLT::scalar(static_cast<unsigned>(ScalarSize)));
238 }
239
240 explicit constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits)
241 : LLT() {
242 init(Info, EC, SizeInBits);
243 }
244
245 explicit constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits,
246 unsigned AddressSpace)
247 : LLT() {
248 init(Info, EC, SizeInBits, AddressSpace);
249 }
250
251 explicit constexpr LLT(Kind Info, ElementCount EC, uint64_t SizeInBits,
252 FpSemantics Sem)
253 : LLT() {
254 init(Info, EC, SizeInBits, Sem);
255 }
256
257 LLVM_ABI explicit LLT(MVT VT);
258 explicit constexpr LLT() : RawData(0), Info(static_cast<Kind>(0)) {}
259
260 constexpr bool isToken() const {
261 return Info == Kind::ANY_SCALAR && RawData == 0;
262 }
263 constexpr bool isValid() const { return isToken() || RawData != 0; }
264 constexpr bool isAnyScalar() const { return Info == Kind::ANY_SCALAR; }
265 constexpr bool isInteger() const { return Info == Kind::INTEGER; }
266 constexpr bool isFloat() const { return Info == Kind::FLOAT; }
267 constexpr bool isPointer() const { return Info == Kind::POINTER; }
268 constexpr bool isAnyVector() const { return Info == Kind::VECTOR_ANY; }
269 constexpr bool isIntegerVector() const {
270 return Info == Kind::VECTOR_INTEGER;
271 }
272 constexpr bool isFloatVector() const { return Info == Kind::VECTOR_FLOAT; }
273 constexpr bool isPointerVector() const {
274 return Info == Kind::VECTOR_POINTER;
275 }
276 constexpr bool isPointerOrPointerVector() const {
277 return isPointer() || isPointerVector();
278 }
279 constexpr bool isFloatOrFloatVector() const {
280 return isFloat() || isFloatVector();
281 }
282
283 constexpr bool isScalar() const {
284 return Info == Kind::ANY_SCALAR || Info == Kind::INTEGER ||
285 Info == Kind::FLOAT;
286 }
287 constexpr bool isScalar(unsigned Size) const {
288 return isScalar() && getScalarSizeInBits() == Size;
289 }
290 constexpr bool isVector() const {
291 return Info == Kind::VECTOR_ANY || Info == Kind::VECTOR_INTEGER ||
292 Info == Kind::VECTOR_FLOAT || Info == Kind::VECTOR_POINTER;
293 }
294
295 constexpr bool isInteger(unsigned Size) const {
296 return isInteger() && getScalarSizeInBits() == Size;
297 }
298
299 constexpr bool isFloat(unsigned Size) const {
300 return isFloat() && getScalarSizeInBits() == Size;
301 }
302 constexpr bool isFloat(FpSemantics Sem) const {
303 return isFloat() && getFpSemantics() == Sem;
304 }
305 // FIXME: Remove or rework this predicate
312
313 bool isFloat16() const {
314 if (!getUseExtended())
315 return isAnyScalar() && getSizeInBits() == 16;
317 }
318 bool isFloat32() const {
319 if (!getUseExtended())
320 return isAnyScalar() && getSizeInBits() == 32;
322 }
323 bool isFloat64() const {
324 if (!getUseExtended())
325 return isAnyScalar() && getSizeInBits() == 64;
327 }
328 bool isFloat128() const {
329 if (!getUseExtended())
330 return isAnyScalar() && getSizeInBits() == 128;
332 }
333 bool isBFloat16() const {
334 if (!getUseExtended())
335 return false;
336 return isFloat(FpSemantics::S_BFloat);
337 }
338 bool isX86FP80() const {
339 if (!getUseExtended())
340 return false;
341 return isFloat(FpSemantics::S_x87DoubleExtended);
342 }
343 bool isPPCF128() const {
344 if (!getUseExtended())
345 return false;
346 return isFloat(FpSemantics::S_PPCDoubleDouble);
347 }
348
349 /// Returns the number of elements in a vector LLT. Must only be called on
350 /// vector types.
351 constexpr uint16_t getNumElements() const {
352 if (isScalable())
354 "Possible incorrect use of LLT::getNumElements() for "
355 "scalable vector. Scalable flag may be dropped, use "
356 "LLT::getElementCount() instead");
358 }
359
360 /// Returns true if the LLT is a scalable vector. Must only be called on
361 /// vector types.
362 constexpr bool isScalable() const {
363 assert(isVector() && "Expected a vector type");
364 return getFieldValue(VectorScalableFieldInfo);
365 }
366
367 /// Returns true if the LLT is a fixed vector. Returns false otherwise, even
368 /// if the LLT is not a vector type.
369 constexpr bool isFixedVector() const { return isVector() && !isScalable(); }
370
371 constexpr bool isFixedVector(unsigned NumElements,
372 unsigned ScalarSize) const {
373 return isFixedVector() && getNumElements() == NumElements &&
374 getScalarSizeInBits() == ScalarSize;
375 }
376
377 /// Returns true if the LLT is a scalable vector. Returns false otherwise,
378 /// even if the LLT is not a vector type.
379 constexpr bool isScalableVector() const { return isVector() && isScalable(); }
380
381 constexpr ElementCount getElementCount() const {
382 assert(isVector() && "cannot get number of elements on scalar/aggregate");
383 return ElementCount::get(getFieldValue(VectorElementsFieldInfo),
384 isScalable());
385 }
386
387 /// Returns the total size of the type. Must only be called on sized types.
388 constexpr TypeSize getSizeInBits() const {
389 if (isPointer() || isScalar())
391 auto EC = getElementCount();
392 return TypeSize(getScalarSizeInBits() * EC.getKnownMinValue(),
393 EC.isScalable());
394 }
395
396 /// Returns the total size of the type in bytes, i.e. number of whole bytes
397 /// needed to represent the size in bits. Must only be called on sized types.
398 constexpr TypeSize getSizeInBytes() const {
399 TypeSize BaseSize = getSizeInBits();
400 return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()};
401 }
402
403 LLT getScalarType() const { return isVector() ? getElementType() : *this; }
404
405 constexpr FpSemantics getFpSemantics() const {
406 assert((isFloat() || isFloatVector()) &&
407 "cannot get FP info for non float type");
408 return FpSemantics(getFieldValue(FpSemanticFieldInfo));
409 }
410
411 constexpr Kind getKind() const { return Info; }
412
413 /// Returns a vector with the same number of elements but the new element
414 /// type. Must only be called on vector types.
415 constexpr LLT changeVectorElementType(LLT NewEltTy) const {
416 return LLT::vector(getElementCount(), NewEltTy);
417 }
418
419 /// If this type is a vector, return a vector with the same number of elements
420 /// but the new element type. Otherwise, return the new element type.
421 constexpr LLT changeElementType(LLT NewEltTy) const {
422 return isVector() ? changeVectorElementType(NewEltTy) : NewEltTy;
423 }
424
425 /// If this type is a vector, return a vector with the same number of elements
426 /// but the new element size. Otherwise, return the new element type. Invalid
427 /// for pointer types. For these, use changeElementType.
428 LLT changeElementSize(unsigned NewEltSize) const {
430 "invalid to directly change element size for pointers");
431 if (isVector())
433 getElementType().changeElementSize(NewEltSize));
434
435 if (isInteger())
436 return LLT::integer(NewEltSize);
437
438 if (isFloatIEEE())
439 return LLT::floatIEEE(NewEltSize);
440
441 return LLT::scalar(NewEltSize);
442 }
443
444 /// Return a vector with the same element type and the new element count. Must
445 /// be called on vector types.
447 assert(isVector() &&
448 "cannot change vector element count of non-vector type");
449 return LLT::vector(EC, getElementType());
450 }
451
452 /// Return a vector or scalar with the same element type and the new element
453 /// count.
457
458 LLT changeElementCount(unsigned NumElements) const {
459 return changeElementCount(ElementCount::getFixed(NumElements));
460 }
461
462 /// Return a type that is \p Factor times smaller. Reduces the number of
463 /// elements if this is a vector, or the bitwidth for scalar/pointers. Does
464 /// not attempt to handle cases that aren't evenly divisible.
465 LLT divide(int Factor) const {
466 assert(Factor != 1);
467 assert((!isScalar() || getScalarSizeInBits() != 0) && !isFloat() &&
468 "cannot divide scalar of size zero and floats");
469 if (isVector()) {
470 assert(getElementCount().isKnownMultipleOf(Factor));
471 return scalarOrVector(getElementCount().divideCoefficientBy(Factor),
473 }
474
475 assert(getScalarSizeInBits() % Factor == 0);
476 if (isInteger())
477 return integer(getScalarSizeInBits() / Factor);
478
479 return scalar(getScalarSizeInBits() / Factor);
480 }
481
482 /// Produce a vector type that is \p Factor times bigger, preserving the
483 /// element type. For a scalar or pointer, this will produce a new vector with
484 /// \p Factor elements.
485 LLT multiplyElements(int Factor) const {
486 if (isVector()) {
487 return scalarOrVector(getElementCount() * Factor, getElementType());
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() {
708 return ExtendedLLT.load(std::memory_order_relaxed);
709 }
710 static void setUseExtended(bool Enable) {
711 ExtendedLLT.store(Enable, std::memory_order_relaxed);
712 }
713
714private:
715 // Enabled during target construction, which may run concurrently. Relaxed
716 // ordering suffices because the flag publishes no other state.
717 //
718 // FIXME: Scope this per target rather than globally:
719 // https://github.com/llvm/llvm-project/issues/219517.
720 LLVM_ABI static std::atomic<bool> ExtendedLLT;
721};
722
723inline raw_ostream &operator<<(raw_ostream &OS, const LLT &Ty) {
724 Ty.print(OS);
725 return OS;
726}
727
728template <> struct DenseMapInfo<LLT> {
729 static inline unsigned getHashValue(const LLT &Ty) {
730 uint64_t Val = Ty.getUniqueRAWLLTData();
732 }
733 static bool isEqual(const LLT &LHS, const LLT &RHS) { return LHS == RHS; }
734};
735
736} // namespace llvm
737
738#endif // LLVM_CODEGEN_LOWLEVELTYPE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
This file declares a class to represent arbitrary precision floating point values and provide a varie...
#define LLVM_ABI
Definition Compiler.h:215
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:678
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:134
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:382
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition TypeSize.h:308
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:305
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition TypeSize.h:311
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:339
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...