10b57cec5SDimitry Andric //===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines the set of low-level target independent types which various 100b57cec5SDimitry Andric // values in the code generator are. This allows the target specific behavior 110b57cec5SDimitry Andric // of instructions to be described to target independent passes. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_VALUETYPES_H 160b57cec5SDimitry Andric #define LLVM_CODEGEN_VALUETYPES_H 170b57cec5SDimitry Andric 1806c3fb27SDimitry Andric #include "llvm/CodeGen/MachineValueType.h" 190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 200b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 21480093f4SDimitry Andric #include "llvm/Support/TypeSize.h" 220b57cec5SDimitry Andric #include <cassert> 230b57cec5SDimitry Andric #include <cstdint> 240b57cec5SDimitry Andric #include <string> 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace llvm { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric class LLVMContext; 290b57cec5SDimitry Andric class Type; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric /// Extended Value Type. Capable of holding value types which are not native 320b57cec5SDimitry Andric /// for any processor (such as the i12345 type), as well as the types an MVT 330b57cec5SDimitry Andric /// can represent. 340b57cec5SDimitry Andric struct EVT { 350b57cec5SDimitry Andric private: 360b57cec5SDimitry Andric MVT V = MVT::INVALID_SIMPLE_VALUE_TYPE; 370b57cec5SDimitry Andric Type *LLVMTy = nullptr; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric public: 400b57cec5SDimitry Andric constexpr EVT() = default; EVTEVT410b57cec5SDimitry Andric constexpr EVT(MVT::SimpleValueType SVT) : V(SVT) {} EVTEVT420b57cec5SDimitry Andric constexpr EVT(MVT S) : V(S) {} 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric bool operator==(EVT VT) const { 450b57cec5SDimitry Andric return !(*this != VT); 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric bool operator!=(EVT VT) const { 480b57cec5SDimitry Andric if (V.SimpleTy != VT.V.SimpleTy) 490b57cec5SDimitry Andric return true; 500b57cec5SDimitry Andric if (V.SimpleTy == MVT::INVALID_SIMPLE_VALUE_TYPE) 510b57cec5SDimitry Andric return LLVMTy != VT.LLVMTy; 520b57cec5SDimitry Andric return false; 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric /// Returns the EVT that represents a floating-point type with the given 560b57cec5SDimitry Andric /// number of bits. There are two floating-point types with 128 bits - this 570b57cec5SDimitry Andric /// returns f128 rather than ppcf128. getFloatingPointVTEVT580b57cec5SDimitry Andric static EVT getFloatingPointVT(unsigned BitWidth) { 590b57cec5SDimitry Andric return MVT::getFloatingPointVT(BitWidth); 600b57cec5SDimitry Andric } 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric /// Returns the EVT that represents an integer with the given number of 630b57cec5SDimitry Andric /// bits. getIntegerVTEVT640b57cec5SDimitry Andric static EVT getIntegerVT(LLVMContext &Context, unsigned BitWidth) { 650b57cec5SDimitry Andric MVT M = MVT::getIntegerVT(BitWidth); 660b57cec5SDimitry Andric if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) 670b57cec5SDimitry Andric return M; 680b57cec5SDimitry Andric return getExtendedIntegerVT(Context, BitWidth); 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric /// Returns the EVT that represents a vector NumElements in length, where 720b57cec5SDimitry Andric /// each element is of type VT. 730b57cec5SDimitry Andric static EVT getVectorVT(LLVMContext &Context, EVT VT, unsigned NumElements, 740b57cec5SDimitry Andric bool IsScalable = false) { 750b57cec5SDimitry Andric MVT M = MVT::getVectorVT(VT.V, NumElements, IsScalable); 760b57cec5SDimitry Andric if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) 770b57cec5SDimitry Andric return M; 785ffd83dbSDimitry Andric return getExtendedVectorVT(Context, VT, NumElements, IsScalable); 790b57cec5SDimitry Andric } 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// Returns the EVT that represents a vector EC.Min elements in length, 820b57cec5SDimitry Andric /// where each element is of type VT. getVectorVTEVT838bcb0991SDimitry Andric static EVT getVectorVT(LLVMContext &Context, EVT VT, ElementCount EC) { 840b57cec5SDimitry Andric MVT M = MVT::getVectorVT(VT.V, EC); 850b57cec5SDimitry Andric if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE) 860b57cec5SDimitry Andric return M; 875ffd83dbSDimitry Andric return getExtendedVectorVT(Context, VT, EC); 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric /// Return a vector with the same number of elements as this vector, but 910b57cec5SDimitry Andric /// with the element type converted to an integer type with the same 920b57cec5SDimitry Andric /// bitwidth. changeVectorElementTypeToIntegerEVT930b57cec5SDimitry Andric EVT changeVectorElementTypeToInteger() const { 94e8d8bef9SDimitry Andric if (isSimple()) 95e8d8bef9SDimitry Andric return getSimpleVT().changeVectorElementTypeToInteger(); 960b57cec5SDimitry Andric return changeExtendedVectorElementTypeToInteger(); 975ffd83dbSDimitry Andric } 985ffd83dbSDimitry Andric 995ffd83dbSDimitry Andric /// Return a VT for a vector type whose attributes match ourselves 1005ffd83dbSDimitry Andric /// with the exception of the element type that is chosen by the caller. changeVectorElementTypeEVT1015ffd83dbSDimitry Andric EVT changeVectorElementType(EVT EltVT) const { 102fe6060f1SDimitry Andric if (isSimple()) { 103fe6060f1SDimitry Andric assert(EltVT.isSimple() && 104fe6060f1SDimitry Andric "Can't change simple vector VT to have extended element VT"); 105e8d8bef9SDimitry Andric return getSimpleVT().changeVectorElementType(EltVT.getSimpleVT()); 106fe6060f1SDimitry Andric } 1075ffd83dbSDimitry Andric return changeExtendedVectorElementType(EltVT); 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric /// Return the type converted to an equivalently sized integer or vector 1110b57cec5SDimitry Andric /// with integer element type. Similar to changeVectorElementTypeToInteger, 1120b57cec5SDimitry Andric /// but also handles scalars. changeTypeToIntegerEVT11306c3fb27SDimitry Andric EVT changeTypeToInteger() const { 1140b57cec5SDimitry Andric if (isVector()) 1150b57cec5SDimitry Andric return changeVectorElementTypeToInteger(); 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric if (isSimple()) 118e8d8bef9SDimitry Andric return getSimpleVT().changeTypeToInteger(); 1190b57cec5SDimitry Andric return changeExtendedTypeToInteger(); 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 122fe6060f1SDimitry Andric /// Test if the given EVT has zero size, this will fail if called on a 123fe6060f1SDimitry Andric /// scalable type isZeroSizedEVT124fe6060f1SDimitry Andric bool isZeroSized() const { 12506c3fb27SDimitry Andric return getSizeInBits().isZero(); 126fe6060f1SDimitry Andric } 127fe6060f1SDimitry Andric 1280b57cec5SDimitry Andric /// Test if the given EVT is simple (as opposed to being extended). isSimpleEVT1290b57cec5SDimitry Andric bool isSimple() const { 1300b57cec5SDimitry Andric return V.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE; 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric /// Test if the given EVT is extended (as opposed to being simple). isExtendedEVT1340b57cec5SDimitry Andric bool isExtended() const { 1350b57cec5SDimitry Andric return !isSimple(); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric /// Return true if this is a FP or a vector FP type. isFloatingPointEVT1390b57cec5SDimitry Andric bool isFloatingPoint() const { 1400b57cec5SDimitry Andric return isSimple() ? V.isFloatingPoint() : isExtendedFloatingPoint(); 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric /// Return true if this is an integer or a vector integer type. isIntegerEVT1440b57cec5SDimitry Andric bool isInteger() const { 1450b57cec5SDimitry Andric return isSimple() ? V.isInteger() : isExtendedInteger(); 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric /// Return true if this is an integer, but not a vector. isScalarIntegerEVT1490b57cec5SDimitry Andric bool isScalarInteger() const { 1500b57cec5SDimitry Andric return isSimple() ? V.isScalarInteger() : isExtendedScalarInteger(); 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 15306c3fb27SDimitry Andric /// Return true if this is a vector type where the runtime 15406c3fb27SDimitry Andric /// length is machine dependent isScalableTargetExtVTEVT15506c3fb27SDimitry Andric bool isScalableTargetExtVT() const { 15606c3fb27SDimitry Andric return isSimple() && V.isScalableTargetExtVT(); 15706c3fb27SDimitry Andric } 15806c3fb27SDimitry Andric 1590b57cec5SDimitry Andric /// Return true if this is a vector value type. isVectorEVT1600b57cec5SDimitry Andric bool isVector() const { 1610b57cec5SDimitry Andric return isSimple() ? V.isVector() : isExtendedVector(); 1620b57cec5SDimitry Andric } 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric /// Return true if this is a vector type where the runtime 1650b57cec5SDimitry Andric /// length is machine dependent isScalableVectorEVT1660b57cec5SDimitry Andric bool isScalableVector() const { 1675ffd83dbSDimitry Andric return isSimple() ? V.isScalableVector() : isExtendedScalableVector(); 1685ffd83dbSDimitry Andric } 1695ffd83dbSDimitry Andric isFixedLengthVectorEVT1705ffd83dbSDimitry Andric bool isFixedLengthVector() const { 1715ffd83dbSDimitry Andric return isSimple() ? V.isFixedLengthVector() 1725ffd83dbSDimitry Andric : isExtendedFixedLengthVector(); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 17506c3fb27SDimitry Andric /// Return true if the type is a scalable type. isScalableVTEVT17606c3fb27SDimitry Andric bool isScalableVT() const { 17706c3fb27SDimitry Andric return isScalableVector() || isScalableTargetExtVT(); 17806c3fb27SDimitry Andric } 17906c3fb27SDimitry Andric 1800b57cec5SDimitry Andric /// Return true if this is a 16-bit vector type. is16BitVectorEVT1810b57cec5SDimitry Andric bool is16BitVector() const { 1820b57cec5SDimitry Andric return isSimple() ? V.is16BitVector() : isExtended16BitVector(); 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric /// Return true if this is a 32-bit vector type. is32BitVectorEVT1860b57cec5SDimitry Andric bool is32BitVector() const { 1870b57cec5SDimitry Andric return isSimple() ? V.is32BitVector() : isExtended32BitVector(); 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric /// Return true if this is a 64-bit vector type. is64BitVectorEVT1910b57cec5SDimitry Andric bool is64BitVector() const { 1920b57cec5SDimitry Andric return isSimple() ? V.is64BitVector() : isExtended64BitVector(); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric /// Return true if this is a 128-bit vector type. is128BitVectorEVT1960b57cec5SDimitry Andric bool is128BitVector() const { 1970b57cec5SDimitry Andric return isSimple() ? V.is128BitVector() : isExtended128BitVector(); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric /// Return true if this is a 256-bit vector type. is256BitVectorEVT2010b57cec5SDimitry Andric bool is256BitVector() const { 2020b57cec5SDimitry Andric return isSimple() ? V.is256BitVector() : isExtended256BitVector(); 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric /// Return true if this is a 512-bit vector type. is512BitVectorEVT2060b57cec5SDimitry Andric bool is512BitVector() const { 2070b57cec5SDimitry Andric return isSimple() ? V.is512BitVector() : isExtended512BitVector(); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric 2100b57cec5SDimitry Andric /// Return true if this is a 1024-bit vector type. is1024BitVectorEVT2110b57cec5SDimitry Andric bool is1024BitVector() const { 2120b57cec5SDimitry Andric return isSimple() ? V.is1024BitVector() : isExtended1024BitVector(); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric /// Return true if this is a 2048-bit vector type. is2048BitVectorEVT2160b57cec5SDimitry Andric bool is2048BitVector() const { 2170b57cec5SDimitry Andric return isSimple() ? V.is2048BitVector() : isExtended2048BitVector(); 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric /// Return true if this is an overloaded type for TableGen. isOverloadedEVT2210b57cec5SDimitry Andric bool isOverloaded() const { 2220b57cec5SDimitry Andric return (V==MVT::iAny || V==MVT::fAny || V==MVT::vAny || V==MVT::iPTRAny); 2230b57cec5SDimitry Andric } 2240b57cec5SDimitry Andric 2250b57cec5SDimitry Andric /// Return true if the bit size is a multiple of 8. isByteSizedEVT226fe6060f1SDimitry Andric bool isByteSized() const { 227fe6060f1SDimitry Andric return !isZeroSized() && getSizeInBits().isKnownMultipleOf(8); 228fe6060f1SDimitry Andric } 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric /// Return true if the size is a power-of-two number of bytes. isRoundEVT2310b57cec5SDimitry Andric bool isRound() const { 232480093f4SDimitry Andric if (isScalableVector()) 233480093f4SDimitry Andric return false; 2340b57cec5SDimitry Andric unsigned BitSize = getSizeInBits(); 2350b57cec5SDimitry Andric return BitSize >= 8 && !(BitSize & (BitSize - 1)); 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric /// Return true if this has the same number of bits as VT. bitsEqEVT2390b57cec5SDimitry Andric bool bitsEq(EVT VT) const { 2400b57cec5SDimitry Andric if (EVT::operator==(VT)) return true; 2410b57cec5SDimitry Andric return getSizeInBits() == VT.getSizeInBits(); 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 244e8d8bef9SDimitry Andric /// Return true if we know at compile time this has more bits than VT. knownBitsGTEVT245e8d8bef9SDimitry Andric bool knownBitsGT(EVT VT) const { 246e8d8bef9SDimitry Andric return TypeSize::isKnownGT(getSizeInBits(), VT.getSizeInBits()); 247e8d8bef9SDimitry Andric } 248e8d8bef9SDimitry Andric 249e8d8bef9SDimitry Andric /// Return true if we know at compile time this has more than or the same 250e8d8bef9SDimitry Andric /// bits as VT. knownBitsGEEVT251e8d8bef9SDimitry Andric bool knownBitsGE(EVT VT) const { 252e8d8bef9SDimitry Andric return TypeSize::isKnownGE(getSizeInBits(), VT.getSizeInBits()); 253e8d8bef9SDimitry Andric } 254e8d8bef9SDimitry Andric 255e8d8bef9SDimitry Andric /// Return true if we know at compile time this has fewer bits than VT. knownBitsLTEVT256e8d8bef9SDimitry Andric bool knownBitsLT(EVT VT) const { 257e8d8bef9SDimitry Andric return TypeSize::isKnownLT(getSizeInBits(), VT.getSizeInBits()); 258e8d8bef9SDimitry Andric } 259e8d8bef9SDimitry Andric 260e8d8bef9SDimitry Andric /// Return true if we know at compile time this has fewer than or the same 261e8d8bef9SDimitry Andric /// bits as VT. knownBitsLEEVT262e8d8bef9SDimitry Andric bool knownBitsLE(EVT VT) const { 263e8d8bef9SDimitry Andric return TypeSize::isKnownLE(getSizeInBits(), VT.getSizeInBits()); 264e8d8bef9SDimitry Andric } 265e8d8bef9SDimitry Andric 2660b57cec5SDimitry Andric /// Return true if this has more bits than VT. bitsGTEVT2670b57cec5SDimitry Andric bool bitsGT(EVT VT) const { 2680b57cec5SDimitry Andric if (EVT::operator==(VT)) return false; 269e8d8bef9SDimitry Andric assert(isScalableVector() == VT.isScalableVector() && 270e8d8bef9SDimitry Andric "Comparison between scalable and fixed types"); 271e8d8bef9SDimitry Andric return knownBitsGT(VT); 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric /// Return true if this has no less bits than VT. bitsGEEVT2750b57cec5SDimitry Andric bool bitsGE(EVT VT) const { 2760b57cec5SDimitry Andric if (EVT::operator==(VT)) return true; 277e8d8bef9SDimitry Andric assert(isScalableVector() == VT.isScalableVector() && 278e8d8bef9SDimitry Andric "Comparison between scalable and fixed types"); 279e8d8bef9SDimitry Andric return knownBitsGE(VT); 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric /// Return true if this has less bits than VT. bitsLTEVT2830b57cec5SDimitry Andric bool bitsLT(EVT VT) const { 2840b57cec5SDimitry Andric if (EVT::operator==(VT)) return false; 285e8d8bef9SDimitry Andric assert(isScalableVector() == VT.isScalableVector() && 286e8d8bef9SDimitry Andric "Comparison between scalable and fixed types"); 287e8d8bef9SDimitry Andric return knownBitsLT(VT); 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric /// Return true if this has no more bits than VT. bitsLEEVT2910b57cec5SDimitry Andric bool bitsLE(EVT VT) const { 2920b57cec5SDimitry Andric if (EVT::operator==(VT)) return true; 293e8d8bef9SDimitry Andric assert(isScalableVector() == VT.isScalableVector() && 294e8d8bef9SDimitry Andric "Comparison between scalable and fixed types"); 295e8d8bef9SDimitry Andric return knownBitsLE(VT); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric /// Return the SimpleValueType held in the specified simple EVT. getSimpleVTEVT2990b57cec5SDimitry Andric MVT getSimpleVT() const { 3000b57cec5SDimitry Andric assert(isSimple() && "Expected a SimpleValueType!"); 3010b57cec5SDimitry Andric return V; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric /// If this is a vector type, return the element type, otherwise return 3050b57cec5SDimitry Andric /// this. getScalarTypeEVT3060b57cec5SDimitry Andric EVT getScalarType() const { 3070b57cec5SDimitry Andric return isVector() ? getVectorElementType() : *this; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric /// Given a vector type, return the type of each element. getVectorElementTypeEVT3110b57cec5SDimitry Andric EVT getVectorElementType() const { 3120b57cec5SDimitry Andric assert(isVector() && "Invalid vector type!"); 3130b57cec5SDimitry Andric if (isSimple()) 3140b57cec5SDimitry Andric return V.getVectorElementType(); 3150b57cec5SDimitry Andric return getExtendedVectorElementType(); 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric /// Given a vector type, return the number of elements it contains. getVectorNumElementsEVT3190b57cec5SDimitry Andric unsigned getVectorNumElements() const { 3200b57cec5SDimitry Andric assert(isVector() && "Invalid vector type!"); 321fe6060f1SDimitry Andric 3225ffd83dbSDimitry Andric if (isScalableVector()) 323fe6060f1SDimitry Andric llvm::reportInvalidSizeRequest( 324fe6060f1SDimitry Andric "Possible incorrect use of EVT::getVectorNumElements() for " 3255ffd83dbSDimitry Andric "scalable vector. Scalable flag may be dropped, use " 326fe6060f1SDimitry Andric "EVT::getVectorElementCount() instead"); 327fe6060f1SDimitry Andric 328fe6060f1SDimitry Andric return isSimple() ? V.getVectorNumElements() 329fe6060f1SDimitry Andric : getExtendedVectorNumElements(); 3300b57cec5SDimitry Andric } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric // Given a (possibly scalable) vector type, return the ElementCount getVectorElementCountEVT3338bcb0991SDimitry Andric ElementCount getVectorElementCount() const { 3340b57cec5SDimitry Andric assert((isVector()) && "Invalid vector type!"); 3350b57cec5SDimitry Andric if (isSimple()) 3360b57cec5SDimitry Andric return V.getVectorElementCount(); 3370b57cec5SDimitry Andric 3385ffd83dbSDimitry Andric return getExtendedVectorElementCount(); 3395ffd83dbSDimitry Andric } 3405ffd83dbSDimitry Andric 3415ffd83dbSDimitry Andric /// Given a vector type, return the minimum number of elements it contains. getVectorMinNumElementsEVT3425ffd83dbSDimitry Andric unsigned getVectorMinNumElements() const { 343e8d8bef9SDimitry Andric return getVectorElementCount().getKnownMinValue(); 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric /// Return the size of the specified value type in bits. 347480093f4SDimitry Andric /// 348480093f4SDimitry Andric /// If the value type is a scalable vector type, the scalable property will 349480093f4SDimitry Andric /// be set and the runtime size will be a positive integer multiple of the 350480093f4SDimitry Andric /// base size. getSizeInBitsEVT351480093f4SDimitry Andric TypeSize getSizeInBits() const { 3520b57cec5SDimitry Andric if (isSimple()) 3530b57cec5SDimitry Andric return V.getSizeInBits(); 3540b57cec5SDimitry Andric return getExtendedSizeInBits(); 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric 357e8d8bef9SDimitry Andric /// Return the size of the specified fixed width value type in bits. The 358e8d8bef9SDimitry Andric /// function will assert if the type is scalable. getFixedSizeInBitsEVT359e8d8bef9SDimitry Andric uint64_t getFixedSizeInBits() const { 360bdd1243dSDimitry Andric return getSizeInBits().getFixedValue(); 361e8d8bef9SDimitry Andric } 362e8d8bef9SDimitry Andric getScalarSizeInBitsEVT363e8d8bef9SDimitry Andric uint64_t getScalarSizeInBits() const { 364bdd1243dSDimitry Andric return getScalarType().getSizeInBits().getFixedValue(); 3650b57cec5SDimitry Andric } 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric /// Return the number of bytes overwritten by a store of the specified value 3680b57cec5SDimitry Andric /// type. 369480093f4SDimitry Andric /// 370480093f4SDimitry Andric /// If the value type is a scalable vector type, the scalable property will 371480093f4SDimitry Andric /// be set and the runtime size will be a positive integer multiple of the 372480093f4SDimitry Andric /// base size. getStoreSizeEVT373480093f4SDimitry Andric TypeSize getStoreSize() const { 374480093f4SDimitry Andric TypeSize BaseSize = getSizeInBits(); 375bdd1243dSDimitry Andric return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()}; 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 37881ad6265SDimitry Andric // Return the number of bytes overwritten by a store of this value type or 37981ad6265SDimitry Andric // this value type's element type in the case of a vector. getScalarStoreSizeEVT38081ad6265SDimitry Andric uint64_t getScalarStoreSize() const { 381bdd1243dSDimitry Andric return getScalarType().getStoreSize().getFixedValue(); 38281ad6265SDimitry Andric } 38381ad6265SDimitry Andric 3840b57cec5SDimitry Andric /// Return the number of bits overwritten by a store of the specified value 3850b57cec5SDimitry Andric /// type. 386480093f4SDimitry Andric /// 387480093f4SDimitry Andric /// If the value type is a scalable vector type, the scalable property will 388480093f4SDimitry Andric /// be set and the runtime size will be a positive integer multiple of the 389480093f4SDimitry Andric /// base size. getStoreSizeInBitsEVT390480093f4SDimitry Andric TypeSize getStoreSizeInBits() const { 3910b57cec5SDimitry Andric return getStoreSize() * 8; 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric /// Rounds the bit-width of the given integer EVT up to the nearest power of 3950b57cec5SDimitry Andric /// two (and at least to eight), and returns the integer EVT with that 3960b57cec5SDimitry Andric /// number of bits. getRoundIntegerTypeEVT3970b57cec5SDimitry Andric EVT getRoundIntegerType(LLVMContext &Context) const { 3980b57cec5SDimitry Andric assert(isInteger() && !isVector() && "Invalid integer type!"); 3990b57cec5SDimitry Andric unsigned BitWidth = getSizeInBits(); 4000b57cec5SDimitry Andric if (BitWidth <= 8) 4010b57cec5SDimitry Andric return EVT(MVT::i8); 402bdd1243dSDimitry Andric return getIntegerVT(Context, llvm::bit_ceil(BitWidth)); 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric /// Finds the smallest simple value type that is greater than or equal to 4060b57cec5SDimitry Andric /// half the width of this EVT. If no simple value type can be found, an 4070b57cec5SDimitry Andric /// extended integer value type of half the size (rounded up) is returned. getHalfSizedIntegerVTEVT4080b57cec5SDimitry Andric EVT getHalfSizedIntegerVT(LLVMContext &Context) const { 4090b57cec5SDimitry Andric assert(isInteger() && !isVector() && "Invalid integer type!"); 4100b57cec5SDimitry Andric unsigned EVTSize = getSizeInBits(); 4110b57cec5SDimitry Andric for (unsigned IntVT = MVT::FIRST_INTEGER_VALUETYPE; 4120b57cec5SDimitry Andric IntVT <= MVT::LAST_INTEGER_VALUETYPE; ++IntVT) { 4130b57cec5SDimitry Andric EVT HalfVT = EVT((MVT::SimpleValueType)IntVT); 4140b57cec5SDimitry Andric if (HalfVT.getSizeInBits() * 2 >= EVTSize) 4150b57cec5SDimitry Andric return HalfVT; 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric return getIntegerVT(Context, (EVTSize + 1) / 2); 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric /// Return a VT for an integer vector type with the size of the 4210b57cec5SDimitry Andric /// elements doubled. The typed returned may be an extended type. widenIntegerVectorElementTypeEVT4220b57cec5SDimitry Andric EVT widenIntegerVectorElementType(LLVMContext &Context) const { 4230b57cec5SDimitry Andric EVT EltVT = getVectorElementType(); 4240b57cec5SDimitry Andric EltVT = EVT::getIntegerVT(Context, 2 * EltVT.getSizeInBits()); 4250b57cec5SDimitry Andric return EVT::getVectorVT(Context, EltVT, getVectorElementCount()); 4260b57cec5SDimitry Andric } 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric // Return a VT for a vector type with the same element type but 4290b57cec5SDimitry Andric // half the number of elements. The type returned may be an 4300b57cec5SDimitry Andric // extended type. getHalfNumVectorElementsVTEVT4310b57cec5SDimitry Andric EVT getHalfNumVectorElementsVT(LLVMContext &Context) const { 4320b57cec5SDimitry Andric EVT EltVT = getVectorElementType(); 4330b57cec5SDimitry Andric auto EltCnt = getVectorElementCount(); 434e8d8bef9SDimitry Andric assert(EltCnt.isKnownEven() && "Splitting vector, but not in half!"); 435e8d8bef9SDimitry Andric return EVT::getVectorVT(Context, EltVT, EltCnt.divideCoefficientBy(2)); 436e8d8bef9SDimitry Andric } 437e8d8bef9SDimitry Andric 438e8d8bef9SDimitry Andric // Return a VT for a vector type with the same element type but 439e8d8bef9SDimitry Andric // double the number of elements. The type returned may be an 440e8d8bef9SDimitry Andric // extended type. getDoubleNumVectorElementsVTEVT441e8d8bef9SDimitry Andric EVT getDoubleNumVectorElementsVT(LLVMContext &Context) const { 442e8d8bef9SDimitry Andric EVT EltVT = getVectorElementType(); 443e8d8bef9SDimitry Andric auto EltCnt = getVectorElementCount(); 444e8d8bef9SDimitry Andric return EVT::getVectorVT(Context, EltVT, EltCnt * 2); 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric /// Returns true if the given vector is a power of 2. isPow2VectorTypeEVT4480b57cec5SDimitry Andric bool isPow2VectorType() const { 4495ffd83dbSDimitry Andric unsigned NElts = getVectorMinNumElements(); 4500b57cec5SDimitry Andric return !(NElts & (NElts - 1)); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric /// Widens the length of the given vector EVT up to the nearest power of 2 4540b57cec5SDimitry Andric /// and returns that type. getPow2VectorTypeEVT4550b57cec5SDimitry Andric EVT getPow2VectorType(LLVMContext &Context) const { 4560b57cec5SDimitry Andric if (!isPow2VectorType()) { 4575ffd83dbSDimitry Andric ElementCount NElts = getVectorElementCount(); 458e8d8bef9SDimitry Andric unsigned NewMinCount = 1 << Log2_32_Ceil(NElts.getKnownMinValue()); 459e8d8bef9SDimitry Andric NElts = ElementCount::get(NewMinCount, NElts.isScalable()); 4605ffd83dbSDimitry Andric return EVT::getVectorVT(Context, getVectorElementType(), NElts); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric else { 4630b57cec5SDimitry Andric return *this; 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric /// This function returns value type as a string, e.g. "i32". 4680b57cec5SDimitry Andric std::string getEVTString() const; 4690b57cec5SDimitry Andric 47006c3fb27SDimitry Andric /// Support for debugging, callable in GDB: VT.dump() 47106c3fb27SDimitry Andric void dump() const; 47206c3fb27SDimitry Andric 47306c3fb27SDimitry Andric /// Implement operator<<. printEVT47406c3fb27SDimitry Andric void print(raw_ostream &OS) const { 47506c3fb27SDimitry Andric OS << getEVTString(); 47606c3fb27SDimitry Andric } 47706c3fb27SDimitry Andric 4780b57cec5SDimitry Andric /// This method returns an LLVM type corresponding to the specified EVT. 4790b57cec5SDimitry Andric /// For integer types, this returns an unsigned type. Note that this will 4800b57cec5SDimitry Andric /// abort for types that cannot be represented. 4810b57cec5SDimitry Andric Type *getTypeForEVT(LLVMContext &Context) const; 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric /// Return the value type corresponding to the specified type. 4840b57cec5SDimitry Andric /// This returns all pointers as iPTR. If HandleUnknown is true, unknown 4850b57cec5SDimitry Andric /// types are returned as Other, otherwise they are invalid. 4860b57cec5SDimitry Andric static EVT getEVT(Type *Ty, bool HandleUnknown = false); 4870b57cec5SDimitry Andric getRawBitsEVT4880b57cec5SDimitry Andric intptr_t getRawBits() const { 4890b57cec5SDimitry Andric if (isSimple()) 4900b57cec5SDimitry Andric return V.SimpleTy; 4910b57cec5SDimitry Andric else 4920b57cec5SDimitry Andric return (intptr_t)(LLVMTy); 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric 4950b57cec5SDimitry Andric /// A meaningless but well-behaved order, useful for constructing 4960b57cec5SDimitry Andric /// containers. 4970b57cec5SDimitry Andric struct compareRawBits { operatorEVT::compareRawBits4980b57cec5SDimitry Andric bool operator()(EVT L, EVT R) const { 4990b57cec5SDimitry Andric if (L.V.SimpleTy == R.V.SimpleTy) 5000b57cec5SDimitry Andric return L.LLVMTy < R.LLVMTy; 5010b57cec5SDimitry Andric else 5020b57cec5SDimitry Andric return L.V.SimpleTy < R.V.SimpleTy; 5030b57cec5SDimitry Andric } 5040b57cec5SDimitry Andric }; 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric private: 5070b57cec5SDimitry Andric // Methods for handling the Extended-type case in functions above. 5080b57cec5SDimitry Andric // These are all out-of-line to prevent users of this header file 5090b57cec5SDimitry Andric // from having a dependency on Type.h. 5100b57cec5SDimitry Andric EVT changeExtendedTypeToInteger() const; 5115ffd83dbSDimitry Andric EVT changeExtendedVectorElementType(EVT EltVT) const; 5120b57cec5SDimitry Andric EVT changeExtendedVectorElementTypeToInteger() const; 5130b57cec5SDimitry Andric static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth); 5145ffd83dbSDimitry Andric static EVT getExtendedVectorVT(LLVMContext &C, EVT VT, unsigned NumElements, 5155ffd83dbSDimitry Andric bool IsScalable); 5165ffd83dbSDimitry Andric static EVT getExtendedVectorVT(LLVMContext &Context, EVT VT, 5175ffd83dbSDimitry Andric ElementCount EC); 5180b57cec5SDimitry Andric bool isExtendedFloatingPoint() const LLVM_READONLY; 5190b57cec5SDimitry Andric bool isExtendedInteger() const LLVM_READONLY; 5200b57cec5SDimitry Andric bool isExtendedScalarInteger() const LLVM_READONLY; 5210b57cec5SDimitry Andric bool isExtendedVector() const LLVM_READONLY; 5220b57cec5SDimitry Andric bool isExtended16BitVector() const LLVM_READONLY; 5230b57cec5SDimitry Andric bool isExtended32BitVector() const LLVM_READONLY; 5240b57cec5SDimitry Andric bool isExtended64BitVector() const LLVM_READONLY; 5250b57cec5SDimitry Andric bool isExtended128BitVector() const LLVM_READONLY; 5260b57cec5SDimitry Andric bool isExtended256BitVector() const LLVM_READONLY; 5270b57cec5SDimitry Andric bool isExtended512BitVector() const LLVM_READONLY; 5280b57cec5SDimitry Andric bool isExtended1024BitVector() const LLVM_READONLY; 5290b57cec5SDimitry Andric bool isExtended2048BitVector() const LLVM_READONLY; 5305ffd83dbSDimitry Andric bool isExtendedFixedLengthVector() const LLVM_READONLY; 5315ffd83dbSDimitry Andric bool isExtendedScalableVector() const LLVM_READONLY; 5320b57cec5SDimitry Andric EVT getExtendedVectorElementType() const; 5330b57cec5SDimitry Andric unsigned getExtendedVectorNumElements() const LLVM_READONLY; 5345ffd83dbSDimitry Andric ElementCount getExtendedVectorElementCount() const LLVM_READONLY; 535480093f4SDimitry Andric TypeSize getExtendedSizeInBits() const LLVM_READONLY; 5360b57cec5SDimitry Andric }; 5370b57cec5SDimitry Andric 53806c3fb27SDimitry Andric inline raw_ostream &operator<<(raw_ostream &OS, const EVT &V) { 53906c3fb27SDimitry Andric V.print(OS); 54006c3fb27SDimitry Andric return OS; 54106c3fb27SDimitry Andric } 5420b57cec5SDimitry Andric } // end namespace llvm 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric #endif // LLVM_CODEGEN_VALUETYPES_H 545