File indexing completed on 2026-05-10 08:43:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CODEGEN_VALUETYPES_H
0016 #define LLVM_CODEGEN_VALUETYPES_H
0017
0018 #include "llvm/CodeGenTypes/MachineValueType.h"
0019 #include "llvm/Support/Compiler.h"
0020 #include "llvm/Support/MathExtras.h"
0021 #include "llvm/Support/TypeSize.h"
0022 #include <cassert>
0023 #include <cstdint>
0024 #include <string>
0025
0026 namespace llvm {
0027
0028 class LLVMContext;
0029 class Type;
0030 struct fltSemantics;
0031
0032
0033
0034
0035 struct EVT {
0036 private:
0037 MVT V = MVT::INVALID_SIMPLE_VALUE_TYPE;
0038 Type *LLVMTy = nullptr;
0039
0040 public:
0041 constexpr EVT() = default;
0042 constexpr EVT(MVT::SimpleValueType SVT) : V(SVT) {}
0043 constexpr EVT(MVT S) : V(S) {}
0044
0045 bool operator==(EVT VT) const {
0046 return !(*this != VT);
0047 }
0048 bool operator!=(EVT VT) const {
0049 if (V.SimpleTy != VT.V.SimpleTy)
0050 return true;
0051 if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE)
0052 return LLVMTy != VT.LLVMTy;
0053 return false;
0054 }
0055
0056
0057
0058
0059 static EVT getFloatingPointVT(unsigned BitWidth) {
0060 return MVT::getFloatingPointVT(BitWidth);
0061 }
0062
0063
0064
0065 static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) {
0066 MVT M = MVT::getIntegerVT(BitWidth);
0067 if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
0068 return M;
0069 return getExtendedIntegerVT(Context, BitWidth);
0070 }
0071
0072
0073
0074 static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements,
0075 bool IsScalable = false) {
0076 MVT M = MVT::getVectorVT(VT.V, NumElements, IsScalable);
0077 if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
0078 return M;
0079 return getExtendedVectorVT(Context, VT, NumElements, IsScalable);
0080 }
0081
0082
0083
0084 static EVT getVectorVT(LLVMContext &Context, EVT VT, ElementCount EC) {
0085 MVT M = MVT::getVectorVT(VT.V, EC);
0086 if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
0087 return M;
0088 return getExtendedVectorVT(Context, VT, EC);
0089 }
0090
0091
0092
0093
0094 EVT changeVectorElementTypeToInteger() const {
0095 if (isSimple())
0096 return getSimpleVT().changeVectorElementTypeToInteger();
0097 return changeExtendedVectorElementTypeToInteger();
0098 }
0099
0100
0101
0102 EVT changeVectorElementType(EVT EltVT) const {
0103 if (isSimple()) {
0104 assert(EltVT.isSimple() &&
0105 "Can't change simple vector VT to have extended element VT");
0106 return getSimpleVT().changeVectorElementType(EltVT.getSimpleVT());
0107 }
0108 return changeExtendedVectorElementType(EltVT);
0109 }
0110
0111
0112
0113 EVT changeElementType(EVT EltVT) const {
0114 EltVT = EltVT.getScalarType();
0115 return isVector() ? changeVectorElementType(EltVT) : EltVT;
0116 }
0117
0118
0119
0120
0121 EVT changeTypeToInteger() const {
0122 if (isVector())
0123 return changeVectorElementTypeToInteger();
0124
0125 if (isSimple())
0126 return getSimpleVT().changeTypeToInteger();
0127 return changeExtendedTypeToInteger();
0128 }
0129
0130
0131
0132 bool isZeroSized() const {
0133 return getSizeInBits().isZero();
0134 }
0135
0136
0137 bool isSimple() const {
0138 return V.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE;
0139 }
0140
0141
0142 bool isExtended() const {
0143 return !isSimple();
0144 }
0145
0146
0147 bool isFloatingPoint() const {
0148 return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint();
0149 }
0150
0151
0152 bool isInteger() const {
0153 return isSimple() ? V.isInteger() : isExtendedInteger();
0154 }
0155
0156
0157 bool isScalarInteger() const {
0158 return isSimple() ? V.isScalarInteger() : isExtendedScalarInteger();
0159 }
0160
0161
0162
0163 bool isScalableTargetExtVT() const {
0164 return isSimple() && V.isScalableTargetExtVT();
0165 }
0166
0167
0168 bool isVector() const {
0169 return isSimple() ? V.isVector() : isExtendedVector();
0170 }
0171
0172
0173
0174 bool isScalableVector() const {
0175 return isSimple() ? V.isScalableVector() : isExtendedScalableVector();
0176 }
0177
0178
0179 bool isRISCVVectorTuple() const { return V.isRISCVVectorTuple(); }
0180
0181 bool isFixedLengthVector() const {
0182 return isSimple() ? V.isFixedLengthVector()
0183 : isExtendedFixedLengthVector();
0184 }
0185
0186
0187 bool isScalableVT() const {
0188 return isScalableVector() || isScalableTargetExtVT();
0189 }
0190
0191
0192 bool is16BitVector() const {
0193 return isSimple() ? V.is16BitVector() : isExtended16BitVector();
0194 }
0195
0196
0197 bool is32BitVector() const {
0198 return isSimple() ? V.is32BitVector() : isExtended32BitVector();
0199 }
0200
0201
0202 bool is64BitVector() const {
0203 return isSimple() ? V.is64BitVector() : isExtended64BitVector();
0204 }
0205
0206
0207 bool is128BitVector() const {
0208 return isSimple() ? V.is128BitVector() : isExtended128BitVector();
0209 }
0210
0211
0212 bool is256BitVector() const {
0213 return isSimple() ? V.is256BitVector() : isExtended256BitVector();
0214 }
0215
0216
0217 bool is512BitVector() const {
0218 return isSimple() ? V.is512BitVector() : isExtended512BitVector();
0219 }
0220
0221
0222 bool is1024BitVector() const {
0223 return isSimple() ? V.is1024BitVector() : isExtended1024BitVector();
0224 }
0225
0226
0227 bool is2048BitVector() const {
0228 return isSimple() ? V.is2048BitVector() : isExtended2048BitVector();
0229 }
0230
0231
0232 bool isOverloaded() const {
0233 return (V == MVT::iAny || V == MVT::fAny || V == MVT::vAny ||
0234 V == MVT::pAny);
0235 }
0236
0237
0238 bool isByteSized() const {
0239 return !isZeroSized() && getSizeInBits().isKnownMultipleOf(8);
0240 }
0241
0242
0243 bool isRound() const {
0244 if (isScalableVector())
0245 return false;
0246 unsigned BitSize = getSizeInBits();
0247 return BitSize >= 8 && !(BitSize & (BitSize - 1));
0248 }
0249
0250
0251 bool bitsEq(EVT VT) const {
0252 if (EVT::operator==(VT)) return true;
0253 return getSizeInBits() == VT.getSizeInBits();
0254 }
0255
0256
0257 bool knownBitsGT(EVT VT) const {
0258 return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits());
0259 }
0260
0261
0262
0263 bool knownBitsGE(EVT VT) const {
0264 return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits());
0265 }
0266
0267
0268 bool knownBitsLT(EVT VT) const {
0269 return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits());
0270 }
0271
0272
0273
0274 bool knownBitsLE(EVT VT) const {
0275 return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits());
0276 }
0277
0278
0279 bool bitsGT(EVT VT) const {
0280 if (EVT::operator==(VT)) return false;
0281 assert(isScalableVector() == VT.isScalableVector() &&
0282 "Comparison between scalable and fixed types");
0283 return knownBitsGT(VT);
0284 }
0285
0286
0287 bool bitsGE(EVT VT) const {
0288 if (EVT::operator==(VT)) return true;
0289 assert(isScalableVector() == VT.isScalableVector() &&
0290 "Comparison between scalable and fixed types");
0291 return knownBitsGE(VT);
0292 }
0293
0294
0295 bool bitsLT(EVT VT) const {
0296 if (EVT::operator==(VT)) return false;
0297 assert(isScalableVector() == VT.isScalableVector() &&
0298 "Comparison between scalable and fixed types");
0299 return knownBitsLT(VT);
0300 }
0301
0302
0303 bool bitsLE(EVT VT) const {
0304 if (EVT::operator==(VT)) return true;
0305 assert(isScalableVector() == VT.isScalableVector() &&
0306 "Comparison between scalable and fixed types");
0307 return knownBitsLE(VT);
0308 }
0309
0310
0311 MVT getSimpleVT() const {
0312 assert(isSimple() && "Expected a SimpleValueType!");
0313 return V;
0314 }
0315
0316
0317
0318 EVT getScalarType() const {
0319 return isVector() ? getVectorElementType() : *this;
0320 }
0321
0322
0323 EVT getVectorElementType() const {
0324 assert(isVector() && "Invalid vector type!");
0325 if (isSimple())
0326 return V.getVectorElementType();
0327 return getExtendedVectorElementType();
0328 }
0329
0330
0331 unsigned getVectorNumElements() const {
0332 assert(isVector() && "Invalid vector type!");
0333
0334 if (isScalableVector())
0335 llvm::reportInvalidSizeRequest(
0336 "Possible incorrect use of EVT::getVectorNumElements() for "
0337 "scalable vector. Scalable flag may be dropped, use "
0338 "EVT::getVectorElementCount() instead");
0339
0340 return isSimple() ? V.getVectorNumElements()
0341 : getExtendedVectorNumElements();
0342 }
0343
0344
0345 ElementCount getVectorElementCount() const {
0346 assert((isVector()) && "Invalid vector type!");
0347 if (isSimple())
0348 return V.getVectorElementCount();
0349
0350 return getExtendedVectorElementCount();
0351 }
0352
0353
0354 unsigned getVectorMinNumElements() const {
0355 return getVectorElementCount().getKnownMinValue();
0356 }
0357
0358
0359 unsigned getRISCVVectorTupleNumFields() const {
0360 return V.getRISCVVectorTupleNumFields();
0361 }
0362
0363
0364
0365
0366
0367
0368 TypeSize getSizeInBits() const {
0369 if (isSimple())
0370 return V.getSizeInBits();
0371 return getExtendedSizeInBits();
0372 }
0373
0374
0375
0376 uint64_t getFixedSizeInBits() const {
0377 return getSizeInBits().getFixedValue();
0378 }
0379
0380 uint64_t getScalarSizeInBits() const {
0381 return getScalarType().getSizeInBits().getFixedValue();
0382 }
0383
0384
0385
0386
0387
0388
0389
0390 TypeSize getStoreSize() const {
0391 TypeSize BaseSize = getSizeInBits();
0392 return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()};
0393 }
0394
0395
0396
0397 uint64_t getScalarStoreSize() const {
0398 return getScalarType().getStoreSize().getFixedValue();
0399 }
0400
0401
0402
0403
0404
0405
0406
0407 TypeSize getStoreSizeInBits() const {
0408 return getStoreSize() * 8;
0409 }
0410
0411
0412
0413
0414 EVT getRoundIntegerType(LLVMContext &Context) const {
0415 assert(isInteger() && !isVector() && "Invalid integer type!");
0416 unsigned BitWidth = getSizeInBits();
0417 if (BitWidth <= 8)
0418 return EVT(MVT::i8);
0419 return getIntegerVT(Context, llvm::bit_ceil(BitWidth));
0420 }
0421
0422
0423
0424
0425 EVT getHalfSizedIntegerVT(LLVMContext &Context) const {
0426 assert(isInteger() && !isVector() && "Invalid integer type!");
0427 unsigned EVTSize = getSizeInBits();
0428 for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE;
0429 IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) {
0430 EVT HalfVT = EVT((MVT::SimpleValueType)IntVT);
0431 if (HalfVT.getSizeInBits() * 2 >= EVTSize)
0432 return HalfVT;
0433 }
0434 return getIntegerVT(Context, (EVTSize + 1) / 2);
0435 }
0436
0437
0438
0439 EVT widenIntegerVectorElementType(LLVMContext &Context) const {
0440 EVT EltVT = getVectorElementType();
0441 EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits());
0442 return EVT::getVectorVT(Context, EltVT, getVectorElementCount());
0443 }
0444
0445
0446
0447
0448 EVT getHalfNumVectorElementsVT(LLVMContext &Context) const {
0449 EVT EltVT = getVectorElementType();
0450 auto EltCnt = getVectorElementCount();
0451 assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!");
0452 return EVT::getVectorVT(Context, EltVT, EltCnt.divideCoefficientBy(2));
0453 }
0454
0455
0456
0457
0458 EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const {
0459 EVT EltVT = getVectorElementType();
0460 auto EltCnt = getVectorElementCount();
0461 return EVT::getVectorVT(Context, EltVT, EltCnt * 2);
0462 }
0463
0464
0465 bool isPow2VectorType() const {
0466 unsigned NElts = getVectorMinNumElements();
0467 return !(NElts & (NElts - 1));
0468 }
0469
0470
0471
0472 EVT getPow2VectorType(LLVMContext &Context) const {
0473 if (!isPow2VectorType()) {
0474 ElementCount NElts = getVectorElementCount();
0475 unsigned NewMinCount = 1 << Log2_32_Ceil(NElts.getKnownMinValue());
0476 NElts = ElementCount::get(NewMinCount, NElts.isScalable());
0477 return EVT::getVectorVT(Context, getVectorElementType(), NElts);
0478 }
0479 else {
0480 return *this;
0481 }
0482 }
0483
0484
0485 std::string getEVTString() const;
0486
0487
0488 void dump() const;
0489
0490
0491 void print(raw_ostream &OS) const {
0492 OS << getEVTString();
0493 }
0494
0495
0496
0497
0498 Type *getTypeForEVT(LLVMContext &Context) const;
0499
0500
0501
0502
0503
0504
0505 static EVT getEVT(Type *Ty, bool HandleUnknown = false);
0506
0507 intptr_t getRawBits() const {
0508 if (isSimple())
0509 return V.SimpleTy;
0510 else
0511 return (intptr_t)(LLVMTy);
0512 }
0513
0514
0515
0516 struct compareRawBits {
0517 bool operator()(EVT L, EVT R) const {
0518 if (L.V.SimpleTy == R.V.SimpleTy)
0519 return L.LLVMTy < R.LLVMTy;
0520 else
0521 return L.V.SimpleTy < R.V.SimpleTy;
0522 }
0523 };
0524
0525
0526
0527 const fltSemantics &getFltSemantics() const;
0528
0529 private:
0530
0531
0532
0533 EVT changeExtendedTypeToInteger() const;
0534 EVT changeExtendedVectorElementType(EVT EltVT) const;
0535 EVT changeExtendedVectorElementTypeToInteger() const;
0536 static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
0537 static EVT getExtendedVectorVT(LLVMContext &C, EVT VT, unsigned NumElements,
0538 bool IsScalable);
0539 static EVT getExtendedVectorVT(LLVMContext &Context, EVT VT,
0540 ElementCount EC);
0541 bool isExtendedFloatingPoint() const LLVM_READONLY;
0542 bool isExtendedInteger() const LLVM_READONLY;
0543 bool isExtendedScalarInteger() const LLVM_READONLY;
0544 bool isExtendedVector() const LLVM_READONLY;
0545 bool isExtended16BitVector() const LLVM_READONLY;
0546 bool isExtended32BitVector() const LLVM_READONLY;
0547 bool isExtended64BitVector() const LLVM_READONLY;
0548 bool isExtended128BitVector() const LLVM_READONLY;
0549 bool isExtended256BitVector() const LLVM_READONLY;
0550 bool isExtended512BitVector() const LLVM_READONLY;
0551 bool isExtended1024BitVector() const LLVM_READONLY;
0552 bool isExtended2048BitVector() const LLVM_READONLY;
0553 bool isExtendedFixedLengthVector() const LLVM_READONLY;
0554 bool isExtendedScalableVector() const LLVM_READONLY;
0555 EVT getExtendedVectorElementType() const;
0556 unsigned getExtendedVectorNumElements() const LLVM_READONLY;
0557 ElementCount getExtendedVectorElementCount() const LLVM_READONLY;
0558 TypeSize getExtendedSizeInBits() const LLVM_READONLY;
0559 };
0560
0561 inline raw_ostream &operator<<(raw_ostream &OS, const EVT &V) {
0562 V.print(OS);
0563 return OS;
0564 }
0565 }
0566
0567 #endif