Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:10

0001 //===- llvm/Type.h - Classes for handling data types ------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file contains the declaration of the Type class.  For more "Type"
0010 // stuff, look in DerivedTypes.h.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_IR_TYPE_H
0015 #define LLVM_IR_TYPE_H
0016 
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/Support/CBindingWrapping.h"
0019 #include "llvm/Support/Casting.h"
0020 #include "llvm/Support/Compiler.h"
0021 #include "llvm/Support/ErrorHandling.h"
0022 #include "llvm/Support/TypeSize.h"
0023 #include <cassert>
0024 #include <cstdint>
0025 #include <iterator>
0026 
0027 namespace llvm {
0028 
0029 class IntegerType;
0030 struct fltSemantics;
0031 class LLVMContext;
0032 class PointerType;
0033 class raw_ostream;
0034 class StringRef;
0035 template <typename PtrType> class SmallPtrSetImpl;
0036 
0037 /// The instances of the Type class are immutable: once they are created,
0038 /// they are never changed.  Also note that only one instance of a particular
0039 /// type is ever created.  Thus seeing if two types are equal is a matter of
0040 /// doing a trivial pointer comparison. To enforce that no two equal instances
0041 /// are created, Type instances can only be created via static factory methods
0042 /// in class Type and in derived classes.  Once allocated, Types are never
0043 /// free'd.
0044 ///
0045 class Type {
0046 public:
0047   //===--------------------------------------------------------------------===//
0048   /// Definitions of all of the base types for the Type system.  Based on this
0049   /// value, you can cast to a class defined in DerivedTypes.h.
0050   /// Note: If you add an element to this, you need to add an element to the
0051   /// Type::getPrimitiveType function, or else things will break!
0052   /// Also update LLVMTypeKind and LLVMGetTypeKind () in the C binding.
0053   ///
0054   enum TypeID {
0055     // PrimitiveTypes
0056     HalfTyID = 0,  ///< 16-bit floating point type
0057     BFloatTyID,    ///< 16-bit floating point type (7-bit significand)
0058     FloatTyID,     ///< 32-bit floating point type
0059     DoubleTyID,    ///< 64-bit floating point type
0060     X86_FP80TyID,  ///< 80-bit floating point type (X87)
0061     FP128TyID,     ///< 128-bit floating point type (112-bit significand)
0062     PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC)
0063     VoidTyID,      ///< type with no size
0064     LabelTyID,     ///< Labels
0065     MetadataTyID,  ///< Metadata
0066     X86_AMXTyID,   ///< AMX vectors (8192 bits, X86 specific)
0067     TokenTyID,     ///< Tokens
0068 
0069     // Derived types... see DerivedTypes.h file.
0070     IntegerTyID,        ///< Arbitrary bit width integers
0071     FunctionTyID,       ///< Functions
0072     PointerTyID,        ///< Pointers
0073     StructTyID,         ///< Structures
0074     ArrayTyID,          ///< Arrays
0075     FixedVectorTyID,    ///< Fixed width SIMD vector type
0076     ScalableVectorTyID, ///< Scalable SIMD vector type
0077     TypedPointerTyID,   ///< Typed pointer used by some GPU targets
0078     TargetExtTyID,      ///< Target extension type
0079   };
0080 
0081 private:
0082   /// This refers to the LLVMContext in which this type was uniqued.
0083   LLVMContext &Context;
0084 
0085   TypeID   ID : 8;            // The current base type of this type.
0086   unsigned SubclassData : 24; // Space for subclasses to store data.
0087                               // Note that this should be synchronized with
0088                               // MAX_INT_BITS value in IntegerType class.
0089 
0090 protected:
0091   friend class LLVMContextImpl;
0092 
0093   explicit Type(LLVMContext &C, TypeID tid)
0094     : Context(C), ID(tid), SubclassData(0) {}
0095   ~Type() = default;
0096 
0097   unsigned getSubclassData() const { return SubclassData; }
0098 
0099   void setSubclassData(unsigned val) {
0100     SubclassData = val;
0101     // Ensure we don't have any accidental truncation.
0102     assert(getSubclassData() == val && "Subclass data too large for field");
0103   }
0104 
0105   /// Keeps track of how many Type*'s there are in the ContainedTys list.
0106   unsigned NumContainedTys = 0;
0107 
0108   /// A pointer to the array of Types contained by this Type. For example, this
0109   /// includes the arguments of a function type, the elements of a structure,
0110   /// the pointee of a pointer, the element type of an array, etc. This pointer
0111   /// may be 0 for types that don't contain other types (Integer, Double,
0112   /// Float).
0113   Type * const *ContainedTys = nullptr;
0114 
0115 public:
0116   /// Print the current type.
0117   /// Omit the type details if \p NoDetails == true.
0118   /// E.g., let %st = type { i32, i16 }
0119   /// When \p NoDetails is true, we only print %st.
0120   /// Put differently, \p NoDetails prints the type as if
0121   /// inlined with the operands when printing an instruction.
0122   void print(raw_ostream &O, bool IsForDebug = false,
0123              bool NoDetails = false) const;
0124 
0125   void dump() const;
0126 
0127   /// Return the LLVMContext in which this type was uniqued.
0128   LLVMContext &getContext() const { return Context; }
0129 
0130   //===--------------------------------------------------------------------===//
0131   // Accessors for working with types.
0132   //
0133 
0134   /// Return the type id for the type. This will return one of the TypeID enum
0135   /// elements defined above.
0136   TypeID getTypeID() const { return ID; }
0137 
0138   /// Return true if this is 'void'.
0139   bool isVoidTy() const { return getTypeID() == VoidTyID; }
0140 
0141   /// Return true if this is 'half', a 16-bit IEEE fp type.
0142   bool isHalfTy() const { return getTypeID() == HalfTyID; }
0143 
0144   /// Return true if this is 'bfloat', a 16-bit bfloat type.
0145   bool isBFloatTy() const { return getTypeID() == BFloatTyID; }
0146 
0147   /// Return true if this is a 16-bit float type.
0148   bool is16bitFPTy() const {
0149     return getTypeID() == BFloatTyID || getTypeID() == HalfTyID;
0150   }
0151 
0152   /// Return true if this is 'float', a 32-bit IEEE fp type.
0153   bool isFloatTy() const { return getTypeID() == FloatTyID; }
0154 
0155   /// Return true if this is 'double', a 64-bit IEEE fp type.
0156   bool isDoubleTy() const { return getTypeID() == DoubleTyID; }
0157 
0158   /// Return true if this is x86 long double.
0159   bool isX86_FP80Ty() const { return getTypeID() == X86_FP80TyID; }
0160 
0161   /// Return true if this is 'fp128'.
0162   bool isFP128Ty() const { return getTypeID() == FP128TyID; }
0163 
0164   /// Return true if this is powerpc long double.
0165   bool isPPC_FP128Ty() const { return getTypeID() == PPC_FP128TyID; }
0166 
0167   /// Return true if this is a well-behaved IEEE-like type, which has a IEEE
0168   /// compatible layout as defined by APFloat::isIEEE(), and does not have
0169   /// non-IEEE values, such as x86_fp80's unnormal values.
0170   bool isIEEELikeFPTy() const {
0171     switch (getTypeID()) {
0172     case DoubleTyID:
0173     case FloatTyID:
0174     case HalfTyID:
0175     case BFloatTyID:
0176     case FP128TyID:
0177       return true;
0178     default:
0179       return false;
0180     }
0181   }
0182 
0183   /// Return true if this is one of the floating-point types
0184   bool isFloatingPointTy() const {
0185     return isIEEELikeFPTy() || getTypeID() == X86_FP80TyID ||
0186            getTypeID() == PPC_FP128TyID;
0187   }
0188 
0189   /// Returns true if this is a floating-point type that is an unevaluated sum
0190   /// of multiple floating-point units.
0191   /// An example of such a type is ppc_fp128, also known as double-double, which
0192   /// consists of two IEEE 754 doubles.
0193   bool isMultiUnitFPType() const {
0194     return getTypeID() == PPC_FP128TyID;
0195   }
0196 
0197   const fltSemantics &getFltSemantics() const;
0198 
0199   /// Return true if this is X86 AMX.
0200   bool isX86_AMXTy() const { return getTypeID() == X86_AMXTyID; }
0201 
0202   /// Return true if this is a target extension type.
0203   bool isTargetExtTy() const { return getTypeID() == TargetExtTyID; }
0204 
0205   /// Return true if this is a target extension type with a scalable layout.
0206   bool isScalableTargetExtTy() const;
0207 
0208   /// Return true if this is a type whose size is a known multiple of vscale.
0209   bool isScalableTy(SmallPtrSetImpl<const Type *> &Visited) const;
0210   bool isScalableTy() const;
0211 
0212   /// Return true if this type is or contains a target extension type that
0213   /// disallows being used as a global.
0214   bool
0215   containsNonGlobalTargetExtType(SmallPtrSetImpl<const Type *> &Visited) const;
0216   bool containsNonGlobalTargetExtType() const;
0217 
0218   /// Return true if this type is or contains a target extension type that
0219   /// disallows being used as a local.
0220   bool
0221   containsNonLocalTargetExtType(SmallPtrSetImpl<const Type *> &Visited) const;
0222   bool containsNonLocalTargetExtType() const;
0223 
0224   /// Return true if this is a FP type or a vector of FP.
0225   bool isFPOrFPVectorTy() const { return getScalarType()->isFloatingPointTy(); }
0226 
0227   /// Return true if this is 'label'.
0228   bool isLabelTy() const { return getTypeID() == LabelTyID; }
0229 
0230   /// Return true if this is 'metadata'.
0231   bool isMetadataTy() const { return getTypeID() == MetadataTyID; }
0232 
0233   /// Return true if this is 'token'.
0234   bool isTokenTy() const { return getTypeID() == TokenTyID; }
0235 
0236   /// True if this is an instance of IntegerType.
0237   bool isIntegerTy() const { return getTypeID() == IntegerTyID; }
0238 
0239   /// Return true if this is an IntegerType of the given width.
0240   bool isIntegerTy(unsigned Bitwidth) const;
0241 
0242   /// Return true if this is an integer type or a vector of integer types.
0243   bool isIntOrIntVectorTy() const { return getScalarType()->isIntegerTy(); }
0244 
0245   /// Return true if this is an integer type or a vector of integer types of
0246   /// the given width.
0247   bool isIntOrIntVectorTy(unsigned BitWidth) const {
0248     return getScalarType()->isIntegerTy(BitWidth);
0249   }
0250 
0251   /// Return true if this is an integer type or a pointer type.
0252   bool isIntOrPtrTy() const { return isIntegerTy() || isPointerTy(); }
0253 
0254   /// True if this is an instance of FunctionType.
0255   bool isFunctionTy() const { return getTypeID() == FunctionTyID; }
0256 
0257   /// True if this is an instance of StructType.
0258   bool isStructTy() const { return getTypeID() == StructTyID; }
0259 
0260   /// True if this is an instance of ArrayType.
0261   bool isArrayTy() const { return getTypeID() == ArrayTyID; }
0262 
0263   /// True if this is an instance of PointerType.
0264   bool isPointerTy() const { return getTypeID() == PointerTyID; }
0265 
0266   /// Return true if this is a pointer type or a vector of pointer types.
0267   bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); }
0268 
0269   /// True if this is an instance of VectorType.
0270   inline bool isVectorTy() const {
0271     return getTypeID() == ScalableVectorTyID || getTypeID() == FixedVectorTyID;
0272   }
0273 
0274   // True if this is an instance of TargetExtType of RISC-V vector tuple.
0275   bool isRISCVVectorTupleTy() const;
0276 
0277   /// Return true if this type could be converted with a lossless BitCast to
0278   /// type 'Ty'. For example, i8* to i32*. BitCasts are valid for types of the
0279   /// same size only where no re-interpretation of the bits is done.
0280   /// Determine if this type could be losslessly bitcast to Ty
0281   bool canLosslesslyBitCastTo(Type *Ty) const;
0282 
0283   /// Return true if this type is empty, that is, it has no elements or all of
0284   /// its elements are empty.
0285   bool isEmptyTy() const;
0286 
0287   /// Return true if the type is "first class", meaning it is a valid type for a
0288   /// Value.
0289   bool isFirstClassType() const {
0290     return getTypeID() != FunctionTyID && getTypeID() != VoidTyID;
0291   }
0292 
0293   /// Return true if the type is a valid type for a register in codegen. This
0294   /// includes all first-class types except struct and array types.
0295   bool isSingleValueType() const {
0296     return isFloatingPointTy() || isIntegerTy() || isPointerTy() ||
0297            isVectorTy() || isX86_AMXTy() || isTargetExtTy();
0298   }
0299 
0300   /// Return true if the type is an aggregate type. This means it is valid as
0301   /// the first operand of an insertvalue or extractvalue instruction. This
0302   /// includes struct and array types, but does not include vector types.
0303   bool isAggregateType() const {
0304     return getTypeID() == StructTyID || getTypeID() == ArrayTyID;
0305   }
0306 
0307   /// Return true if it makes sense to take the size of this type. To get the
0308   /// actual size for a particular target, it is reasonable to use the
0309   /// DataLayout subsystem to do this.
0310   bool isSized(SmallPtrSetImpl<Type*> *Visited = nullptr) const {
0311     // If it's a primitive, it is always sized.
0312     if (getTypeID() == IntegerTyID || isFloatingPointTy() ||
0313         getTypeID() == PointerTyID || getTypeID() == X86_AMXTyID)
0314       return true;
0315     // If it is not something that can have a size (e.g. a function or label),
0316     // it doesn't have a size.
0317     if (getTypeID() != StructTyID && getTypeID() != ArrayTyID &&
0318         !isVectorTy() && getTypeID() != TargetExtTyID)
0319       return false;
0320     // Otherwise we have to try harder to decide.
0321     return isSizedDerivedType(Visited);
0322   }
0323 
0324   /// Return the basic size of this type if it is a primitive type. These are
0325   /// fixed by LLVM and are not target-dependent.
0326   /// This will return zero if the type does not have a size or is not a
0327   /// primitive type.
0328   ///
0329   /// If this is a scalable vector type, the scalable property will be set and
0330   /// the runtime size will be a positive integer multiple of the base size.
0331   ///
0332   /// Note that this may not reflect the size of memory allocated for an
0333   /// instance of the type or the number of bytes that are written when an
0334   /// instance of the type is stored to memory. The DataLayout class provides
0335   /// additional query functions to provide this information.
0336   ///
0337   TypeSize getPrimitiveSizeInBits() const LLVM_READONLY;
0338 
0339   /// If this is a vector type, return the getPrimitiveSizeInBits value for the
0340   /// element type. Otherwise return the getPrimitiveSizeInBits value for this
0341   /// type.
0342   unsigned getScalarSizeInBits() const LLVM_READONLY;
0343 
0344   /// Return the width of the mantissa of this type. This is only valid on
0345   /// floating-point types. If the FP type does not have a stable mantissa (e.g.
0346   /// ppc long double), this method returns -1.
0347   int getFPMantissaWidth() const;
0348 
0349   /// Return whether the type is IEEE compatible, as defined by the eponymous
0350   /// method in APFloat.
0351   bool isIEEE() const;
0352 
0353   /// If this is a vector type, return the element type, otherwise return
0354   /// 'this'.
0355   inline Type *getScalarType() const {
0356     if (isVectorTy())
0357       return getContainedType(0);
0358     return const_cast<Type *>(this);
0359   }
0360 
0361   //===--------------------------------------------------------------------===//
0362   // Type Iteration support.
0363   //
0364   using subtype_iterator = Type * const *;
0365 
0366   subtype_iterator subtype_begin() const { return ContainedTys; }
0367   subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];}
0368   ArrayRef<Type*> subtypes() const {
0369     return ArrayRef(subtype_begin(), subtype_end());
0370   }
0371 
0372   using subtype_reverse_iterator = std::reverse_iterator<subtype_iterator>;
0373 
0374   subtype_reverse_iterator subtype_rbegin() const {
0375     return subtype_reverse_iterator(subtype_end());
0376   }
0377   subtype_reverse_iterator subtype_rend() const {
0378     return subtype_reverse_iterator(subtype_begin());
0379   }
0380 
0381   /// This method is used to implement the type iterator (defined at the end of
0382   /// the file). For derived types, this returns the types 'contained' in the
0383   /// derived type.
0384   Type *getContainedType(unsigned i) const {
0385     assert(i < NumContainedTys && "Index out of range!");
0386     return ContainedTys[i];
0387   }
0388 
0389   /// Return the number of types in the derived type.
0390   unsigned getNumContainedTypes() const { return NumContainedTys; }
0391 
0392   //===--------------------------------------------------------------------===//
0393   // Helper methods corresponding to subclass methods.  This forces a cast to
0394   // the specified subclass and calls its accessor.  "getArrayNumElements" (for
0395   // example) is shorthand for cast<ArrayType>(Ty)->getNumElements().  This is
0396   // only intended to cover the core methods that are frequently used, helper
0397   // methods should not be added here.
0398 
0399   inline unsigned getIntegerBitWidth() const;
0400 
0401   inline Type *getFunctionParamType(unsigned i) const;
0402   inline unsigned getFunctionNumParams() const;
0403   inline bool isFunctionVarArg() const;
0404 
0405   inline StringRef getStructName() const;
0406   inline unsigned getStructNumElements() const;
0407   inline Type *getStructElementType(unsigned N) const;
0408 
0409   inline uint64_t getArrayNumElements() const;
0410 
0411   Type *getArrayElementType() const {
0412     assert(getTypeID() == ArrayTyID);
0413     return ContainedTys[0];
0414   }
0415 
0416   inline StringRef getTargetExtName() const;
0417 
0418   /// Given vector type, change the element type,
0419   /// whilst keeping the old number of elements.
0420   /// For non-vectors simply returns \p EltTy.
0421   inline Type *getWithNewType(Type *EltTy) const;
0422 
0423   /// Given an integer or vector type, change the lane bitwidth to NewBitwidth,
0424   /// whilst keeping the old number of lanes.
0425   inline Type *getWithNewBitWidth(unsigned NewBitWidth) const;
0426 
0427   /// Given scalar/vector integer type, returns a type with elements twice as
0428   /// wide as in the original type. For vectors, preserves element count.
0429   inline Type *getExtendedType() const;
0430 
0431   /// Get the address space of this pointer or pointer vector type.
0432   inline unsigned getPointerAddressSpace() const;
0433 
0434   //===--------------------------------------------------------------------===//
0435   // Static members exported by the Type class itself.  Useful for getting
0436   // instances of Type.
0437   //
0438 
0439   /// Return a type based on an identifier.
0440   static Type *getPrimitiveType(LLVMContext &C, TypeID IDNumber);
0441 
0442   //===--------------------------------------------------------------------===//
0443   // These are the builtin types that are always available.
0444   //
0445   static Type *getVoidTy(LLVMContext &C);
0446   static Type *getLabelTy(LLVMContext &C);
0447   static Type *getHalfTy(LLVMContext &C);
0448   static Type *getBFloatTy(LLVMContext &C);
0449   static Type *getFloatTy(LLVMContext &C);
0450   static Type *getDoubleTy(LLVMContext &C);
0451   static Type *getMetadataTy(LLVMContext &C);
0452   static Type *getX86_FP80Ty(LLVMContext &C);
0453   static Type *getFP128Ty(LLVMContext &C);
0454   static Type *getPPC_FP128Ty(LLVMContext &C);
0455   static Type *getX86_AMXTy(LLVMContext &C);
0456   static Type *getTokenTy(LLVMContext &C);
0457   static IntegerType *getIntNTy(LLVMContext &C, unsigned N);
0458   static IntegerType *getInt1Ty(LLVMContext &C);
0459   static IntegerType *getInt8Ty(LLVMContext &C);
0460   static IntegerType *getInt16Ty(LLVMContext &C);
0461   static IntegerType *getInt32Ty(LLVMContext &C);
0462   static IntegerType *getInt64Ty(LLVMContext &C);
0463   static IntegerType *getInt128Ty(LLVMContext &C);
0464   template <typename ScalarTy> static Type *getScalarTy(LLVMContext &C) {
0465     int noOfBits = sizeof(ScalarTy) * CHAR_BIT;
0466     if (std::is_integral<ScalarTy>::value) {
0467       return (Type*) Type::getIntNTy(C, noOfBits);
0468     } else if (std::is_floating_point<ScalarTy>::value) {
0469       switch (noOfBits) {
0470       case 32:
0471         return Type::getFloatTy(C);
0472       case 64:
0473         return Type::getDoubleTy(C);
0474       }
0475     }
0476     llvm_unreachable("Unsupported type in Type::getScalarTy");
0477   }
0478   static Type *getFloatingPointTy(LLVMContext &C, const fltSemantics &S);
0479 
0480   //===--------------------------------------------------------------------===//
0481   // Convenience methods for getting pointer types.
0482   //
0483   static Type *getWasm_ExternrefTy(LLVMContext &C);
0484   static Type *getWasm_FuncrefTy(LLVMContext &C);
0485 
0486   /// Return a pointer to the current type. This is equivalent to
0487   /// PointerType::get(Ctx, AddrSpace).
0488   /// TODO: Remove this after opaque pointer transition is complete.
0489   LLVM_DEPRECATED("Use PointerType::get instead", "PointerType::get")
0490   PointerType *getPointerTo(unsigned AddrSpace = 0) const;
0491 
0492 private:
0493   /// Derived types like structures and arrays are sized iff all of the members
0494   /// of the type are sized as well. Since asking for their size is relatively
0495   /// uncommon, move this operation out-of-line.
0496   bool isSizedDerivedType(SmallPtrSetImpl<Type*> *Visited = nullptr) const;
0497 };
0498 
0499 // Printing of types.
0500 inline raw_ostream &operator<<(raw_ostream &OS, const Type &T) {
0501   T.print(OS);
0502   return OS;
0503 }
0504 
0505 // allow isa<PointerType>(x) to work without DerivedTypes.h included.
0506 template <> struct isa_impl<PointerType, Type> {
0507   static inline bool doit(const Type &Ty) {
0508     return Ty.getTypeID() == Type::PointerTyID;
0509   }
0510 };
0511 
0512 // Create wrappers for C Binding types (see CBindingWrapping.h).
0513 DEFINE_ISA_CONVERSION_FUNCTIONS(Type, LLVMTypeRef)
0514 
0515 /* Specialized opaque type conversions.
0516  */
0517 inline Type **unwrap(LLVMTypeRef* Tys) {
0518   return reinterpret_cast<Type**>(Tys);
0519 }
0520 
0521 inline LLVMTypeRef *wrap(Type **Tys) {
0522   return reinterpret_cast<LLVMTypeRef*>(const_cast<Type**>(Tys));
0523 }
0524 
0525 } // end namespace llvm
0526 
0527 #endif // LLVM_IR_TYPE_H