Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===- llvm/SandboxIR/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 is a thin wrapper over llvm::Type.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_SANDBOXIR_TYPE_H
0014 #define LLVM_SANDBOXIR_TYPE_H
0015 
0016 #include "llvm/ADT/SmallPtrSet.h"
0017 #include "llvm/IR/DerivedTypes.h"
0018 #include "llvm/IR/Type.h"
0019 #include "llvm/Support/Debug.h"
0020 #include "llvm/Support/raw_ostream.h"
0021 
0022 namespace llvm::sandboxir {
0023 
0024 class Context;
0025 // Forward declare friend classes for MSVC.
0026 class PointerType;
0027 class VectorType;
0028 class FixedVectorType;
0029 class ScalableVectorType;
0030 class IntegerType;
0031 class FunctionType;
0032 class ArrayType;
0033 class StructType;
0034 class TargetExtType;
0035 class Module;
0036 class FPMathOperator;
0037 #define DEF_INSTR(ID, OPCODE, CLASS) class CLASS;
0038 #define DEF_CONST(ID, CLASS) class CLASS;
0039 #include "llvm/SandboxIR/Values.def"
0040 
0041 /// Just like llvm::Type these are immutable, unique, never get freed and
0042 /// can only be created via static factory methods.
0043 class Type {
0044 protected:
0045   llvm::Type *LLVMTy;
0046   friend class ArrayType;          // For LLVMTy.
0047   friend class StructType;         // For LLVMTy.
0048   friend class VectorType;         // For LLVMTy.
0049   friend class FixedVectorType;    // For LLVMTy.
0050   friend class ScalableVectorType; // For LLVMTy.
0051   friend class PointerType;        // For LLVMTy.
0052   friend class FunctionType;       // For LLVMTy.
0053   friend class IntegerType;        // For LLVMTy.
0054   friend class Function;           // For LLVMTy.
0055   friend class CallBase;           // For LLVMTy.
0056   friend class ConstantInt;        // For LLVMTy.
0057   friend class ConstantArray;      // For LLVMTy.
0058   friend class ConstantStruct;     // For LLVMTy.
0059   friend class ConstantVector;     // For LLVMTy.
0060   friend class CmpInst;            // For LLVMTy. TODO: Cleanup after
0061                                    // sandboxir::VectorType is more complete.
0062   friend class Utils;              // for LLVMTy
0063   friend class TargetExtType;      // For LLVMTy.
0064   friend class Module;             // For LLVMTy.
0065   friend class FPMathOperator;     // For LLVMTy.
0066 
0067   // Friend all instruction classes because `create()` functions use LLVMTy.
0068 #define DEF_INSTR(ID, OPCODE, CLASS) friend class CLASS;
0069 #define DEF_CONST(ID, CLASS) friend class CLASS;
0070 #include "llvm/SandboxIR/Values.def"
0071   Context &Ctx;
0072 
0073   Type(llvm::Type *LLVMTy, Context &Ctx) : LLVMTy(LLVMTy), Ctx(Ctx) {}
0074   friend class Context; // For constructor and ~Type().
0075   ~Type() = default;
0076 
0077 public:
0078   /// Print the current type.
0079   /// Omit the type details if \p NoDetails == true.
0080   /// E.g., let %st = type { i32, i16 }
0081   /// When \p NoDetails is true, we only print %st.
0082   /// Put differently, \p NoDetails prints the type as if
0083   /// inlined with the operands when printing an instruction.
0084   void print(raw_ostream &OS, bool IsForDebug = false,
0085              bool NoDetails = false) const {
0086     LLVMTy->print(OS, IsForDebug, NoDetails);
0087   }
0088 
0089   Context &getContext() const { return Ctx; }
0090 
0091   /// Return true if this is 'void'.
0092   bool isVoidTy() const { return LLVMTy->isVoidTy(); }
0093 
0094   /// Return true if this is 'half', a 16-bit IEEE fp type.
0095   bool isHalfTy() const { return LLVMTy->isHalfTy(); }
0096 
0097   /// Return true if this is 'bfloat', a 16-bit bfloat type.
0098   bool isBFloatTy() const { return LLVMTy->isBFloatTy(); }
0099 
0100   /// Return true if this is a 16-bit float type.
0101   bool is16bitFPTy() const { return LLVMTy->is16bitFPTy(); }
0102 
0103   /// Return true if this is 'float', a 32-bit IEEE fp type.
0104   bool isFloatTy() const { return LLVMTy->isFloatTy(); }
0105 
0106   /// Return true if this is 'double', a 64-bit IEEE fp type.
0107   bool isDoubleTy() const { return LLVMTy->isDoubleTy(); }
0108 
0109   /// Return true if this is x86 long double.
0110   bool isX86_FP80Ty() const { return LLVMTy->isX86_FP80Ty(); }
0111 
0112   /// Return true if this is 'fp128'.
0113   bool isFP128Ty() const { return LLVMTy->isFP128Ty(); }
0114 
0115   /// Return true if this is powerpc long double.
0116   bool isPPC_FP128Ty() const { return LLVMTy->isPPC_FP128Ty(); }
0117 
0118   /// Return true if this is a well-behaved IEEE-like type, which has a IEEE
0119   /// compatible layout as defined by APFloat::isIEEE(), and does not have
0120   /// non-IEEE values, such as x86_fp80's unnormal values.
0121   bool isIEEELikeFPTy() const { return LLVMTy->isIEEELikeFPTy(); }
0122 
0123   /// Return true if this is one of the floating-point types
0124   bool isFloatingPointTy() const { return LLVMTy->isFloatingPointTy(); }
0125 
0126   /// Returns true if this is a floating-point type that is an unevaluated sum
0127   /// of multiple floating-point units.
0128   /// An example of such a type is ppc_fp128, also known as double-double, which
0129   /// consists of two IEEE 754 doubles.
0130   bool isMultiUnitFPType() const { return LLVMTy->isMultiUnitFPType(); }
0131 
0132   const fltSemantics &getFltSemantics() const {
0133     return LLVMTy->getFltSemantics();
0134   }
0135 
0136   /// Return true if this is X86 AMX.
0137   bool isX86_AMXTy() const { return LLVMTy->isX86_AMXTy(); }
0138 
0139   /// Return true if this is a target extension type.
0140   bool isTargetExtTy() const { return LLVMTy->isTargetExtTy(); }
0141 
0142   /// Return true if this is a target extension type with a scalable layout.
0143   bool isScalableTargetExtTy() const { return LLVMTy->isScalableTargetExtTy(); }
0144 
0145   /// Return true if this is a type whose size is a known multiple of vscale.
0146   bool isScalableTy() const { return LLVMTy->isScalableTy(); }
0147 
0148   /// Return true if this is a FP type or a vector of FP.
0149   bool isFPOrFPVectorTy() const { return LLVMTy->isFPOrFPVectorTy(); }
0150 
0151   /// Return true if this is 'label'.
0152   bool isLabelTy() const { return LLVMTy->isLabelTy(); }
0153 
0154   /// Return true if this is 'metadata'.
0155   bool isMetadataTy() const { return LLVMTy->isMetadataTy(); }
0156 
0157   /// Return true if this is 'token'.
0158   bool isTokenTy() const { return LLVMTy->isTokenTy(); }
0159 
0160   /// True if this is an instance of IntegerType.
0161   bool isIntegerTy() const { return LLVMTy->isIntegerTy(); }
0162 
0163   /// Return true if this is an IntegerType of the given width.
0164   bool isIntegerTy(unsigned Bitwidth) const {
0165     return LLVMTy->isIntegerTy(Bitwidth);
0166   }
0167 
0168   /// Return true if this is an integer type or a vector of integer types.
0169   bool isIntOrIntVectorTy() const { return LLVMTy->isIntOrIntVectorTy(); }
0170 
0171   /// Return true if this is an integer type or a vector of integer types of
0172   /// the given width.
0173   bool isIntOrIntVectorTy(unsigned BitWidth) const {
0174     return LLVMTy->isIntOrIntVectorTy(BitWidth);
0175   }
0176 
0177   /// Return true if this is an integer type or a pointer type.
0178   bool isIntOrPtrTy() const { return LLVMTy->isIntOrPtrTy(); }
0179 
0180   /// True if this is an instance of FunctionType.
0181   bool isFunctionTy() const { return LLVMTy->isFunctionTy(); }
0182 
0183   /// True if this is an instance of StructType.
0184   bool isStructTy() const { return LLVMTy->isStructTy(); }
0185 
0186   /// True if this is an instance of ArrayType.
0187   bool isArrayTy() const { return LLVMTy->isArrayTy(); }
0188 
0189   /// True if this is an instance of PointerType.
0190   bool isPointerTy() const { return LLVMTy->isPointerTy(); }
0191 
0192   /// Return true if this is a pointer type or a vector of pointer types.
0193   bool isPtrOrPtrVectorTy() const { return LLVMTy->isPtrOrPtrVectorTy(); }
0194 
0195   /// True if this is an instance of VectorType.
0196   inline bool isVectorTy() const { return LLVMTy->isVectorTy(); }
0197 
0198   /// Return true if this type could be converted with a lossless BitCast to
0199   /// type 'Ty'. For example, i8* to i32*. BitCasts are valid for types of the
0200   /// same size only where no re-interpretation of the bits is done.
0201   /// Determine if this type could be losslessly bitcast to Ty
0202   bool canLosslesslyBitCastTo(Type *Ty) const {
0203     return LLVMTy->canLosslesslyBitCastTo(Ty->LLVMTy);
0204   }
0205 
0206   /// Return true if this type is empty, that is, it has no elements or all of
0207   /// its elements are empty.
0208   bool isEmptyTy() const { return LLVMTy->isEmptyTy(); }
0209 
0210   /// Return true if the type is "first class", meaning it is a valid type for a
0211   /// Value.
0212   bool isFirstClassType() const { return LLVMTy->isFirstClassType(); }
0213 
0214   /// Return true if the type is a valid type for a register in codegen. This
0215   /// includes all first-class types except struct and array types.
0216   bool isSingleValueType() const { return LLVMTy->isSingleValueType(); }
0217 
0218   /// Return true if the type is an aggregate type. This means it is valid as
0219   /// the first operand of an insertvalue or extractvalue instruction. This
0220   /// includes struct and array types, but does not include vector types.
0221   bool isAggregateType() const { return LLVMTy->isAggregateType(); }
0222 
0223   /// Return true if it makes sense to take the size of this type. To get the
0224   /// actual size for a particular target, it is reasonable to use the
0225   /// DataLayout subsystem to do this.
0226   bool isSized(SmallPtrSetImpl<Type *> *Visited = nullptr) const {
0227     SmallPtrSet<llvm::Type *, 8> LLVMVisited;
0228     LLVMVisited.reserve(Visited->size());
0229     for (Type *Ty : *Visited)
0230       LLVMVisited.insert(Ty->LLVMTy);
0231     return LLVMTy->isSized(&LLVMVisited);
0232   }
0233 
0234   /// Return the basic size of this type if it is a primitive type. These are
0235   /// fixed by LLVM and are not target-dependent.
0236   /// This will return zero if the type does not have a size or is not a
0237   /// primitive type.
0238   ///
0239   /// If this is a scalable vector type, the scalable property will be set and
0240   /// the runtime size will be a positive integer multiple of the base size.
0241   ///
0242   /// Note that this may not reflect the size of memory allocated for an
0243   /// instance of the type or the number of bytes that are written when an
0244   /// instance of the type is stored to memory. The DataLayout class provides
0245   /// additional query functions to provide this information.
0246   ///
0247   TypeSize getPrimitiveSizeInBits() const {
0248     return LLVMTy->getPrimitiveSizeInBits();
0249   }
0250 
0251   /// If this is a vector type, return the getPrimitiveSizeInBits value for the
0252   /// element type. Otherwise return the getPrimitiveSizeInBits value for this
0253   /// type.
0254   unsigned getScalarSizeInBits() const { return LLVMTy->getScalarSizeInBits(); }
0255 
0256   /// Return the width of the mantissa of this type. This is only valid on
0257   /// floating-point types. If the FP type does not have a stable mantissa (e.g.
0258   /// ppc long double), this method returns -1.
0259   int getFPMantissaWidth() const { return LLVMTy->getFPMantissaWidth(); }
0260 
0261   /// Return whether the type is IEEE compatible, as defined by the eponymous
0262   /// method in APFloat.
0263   bool isIEEE() const { return LLVMTy->isIEEE(); }
0264 
0265   /// If this is a vector type, return the element type, otherwise return
0266   /// 'this'.
0267   Type *getScalarType() const;
0268 
0269   // TODO: ADD MISSING
0270 
0271   static Type *getInt64Ty(Context &Ctx);
0272   static Type *getInt32Ty(Context &Ctx);
0273   static Type *getInt16Ty(Context &Ctx);
0274   static Type *getInt8Ty(Context &Ctx);
0275   static Type *getInt1Ty(Context &Ctx);
0276   static Type *getDoubleTy(Context &Ctx);
0277   static Type *getFloatTy(Context &Ctx);
0278   // TODO: missing get*
0279 
0280   /// Get the address space of this pointer or pointer vector type.
0281   inline unsigned getPointerAddressSpace() const {
0282     return LLVMTy->getPointerAddressSpace();
0283   }
0284 
0285 #ifndef NDEBUG
0286   void dumpOS(raw_ostream &OS);
0287   LLVM_DUMP_METHOD void dump();
0288 #endif // NDEBUG
0289 };
0290 
0291 class PointerType : public Type {
0292 public:
0293   // TODO: add missing functions
0294 
0295   static PointerType *get(Context &Ctx, unsigned AddressSpace);
0296 
0297   static bool classof(const Type *From) {
0298     return isa<llvm::PointerType>(From->LLVMTy);
0299   }
0300 };
0301 
0302 class ArrayType : public Type {
0303 public:
0304   static ArrayType *get(Type *ElementType, uint64_t NumElements);
0305   // TODO: add missing functions
0306   static bool classof(const Type *From) {
0307     return isa<llvm::ArrayType>(From->LLVMTy);
0308   }
0309 };
0310 
0311 class StructType : public Type {
0312 public:
0313   /// This static method is the primary way to create a literal StructType.
0314   static StructType *get(Context &Ctx, ArrayRef<Type *> Elements,
0315                          bool IsPacked = false);
0316 
0317   bool isPacked() const { return cast<llvm::StructType>(LLVMTy)->isPacked(); }
0318 
0319   // TODO: add missing functions
0320   static bool classof(const Type *From) {
0321     return isa<llvm::StructType>(From->LLVMTy);
0322   }
0323 };
0324 
0325 class VectorType : public Type {
0326 public:
0327   static VectorType *get(Type *ElementType, ElementCount EC);
0328   static VectorType *get(Type *ElementType, unsigned NumElements,
0329                          bool Scalable) {
0330     return VectorType::get(ElementType,
0331                            ElementCount::get(NumElements, Scalable));
0332   }
0333   Type *getElementType() const;
0334 
0335   static VectorType *get(Type *ElementType, const VectorType *Other) {
0336     return VectorType::get(ElementType, Other->getElementCount());
0337   }
0338 
0339   inline ElementCount getElementCount() const {
0340     return cast<llvm::VectorType>(LLVMTy)->getElementCount();
0341   }
0342   static VectorType *getInteger(VectorType *VTy);
0343   static VectorType *getExtendedElementVectorType(VectorType *VTy);
0344   static VectorType *getTruncatedElementVectorType(VectorType *VTy);
0345   static VectorType *getSubdividedVectorType(VectorType *VTy, int NumSubdivs);
0346   static VectorType *getHalfElementsVectorType(VectorType *VTy);
0347   static VectorType *getDoubleElementsVectorType(VectorType *VTy);
0348   static bool isValidElementType(Type *ElemTy);
0349 
0350   static bool classof(const Type *From) {
0351     return isa<llvm::VectorType>(From->LLVMTy);
0352   }
0353 };
0354 
0355 class FixedVectorType : public VectorType {
0356 public:
0357   static FixedVectorType *get(Type *ElementType, unsigned NumElts);
0358 
0359   static FixedVectorType *get(Type *ElementType, const FixedVectorType *FVTy) {
0360     return get(ElementType, FVTy->getNumElements());
0361   }
0362 
0363   static FixedVectorType *getInteger(FixedVectorType *VTy) {
0364     return cast<FixedVectorType>(VectorType::getInteger(VTy));
0365   }
0366 
0367   static FixedVectorType *getExtendedElementVectorType(FixedVectorType *VTy) {
0368     return cast<FixedVectorType>(VectorType::getExtendedElementVectorType(VTy));
0369   }
0370 
0371   static FixedVectorType *getTruncatedElementVectorType(FixedVectorType *VTy) {
0372     return cast<FixedVectorType>(
0373         VectorType::getTruncatedElementVectorType(VTy));
0374   }
0375 
0376   static FixedVectorType *getSubdividedVectorType(FixedVectorType *VTy,
0377                                                   int NumSubdivs) {
0378     return cast<FixedVectorType>(
0379         VectorType::getSubdividedVectorType(VTy, NumSubdivs));
0380   }
0381 
0382   static FixedVectorType *getHalfElementsVectorType(FixedVectorType *VTy) {
0383     return cast<FixedVectorType>(VectorType::getHalfElementsVectorType(VTy));
0384   }
0385 
0386   static FixedVectorType *getDoubleElementsVectorType(FixedVectorType *VTy) {
0387     return cast<FixedVectorType>(VectorType::getDoubleElementsVectorType(VTy));
0388   }
0389 
0390   static bool classof(const Type *T) {
0391     return isa<llvm::FixedVectorType>(T->LLVMTy);
0392   }
0393 
0394   unsigned getNumElements() const {
0395     return cast<llvm::FixedVectorType>(LLVMTy)->getNumElements();
0396   }
0397 };
0398 
0399 class ScalableVectorType : public VectorType {
0400 public:
0401   static ScalableVectorType *get(Type *ElementType, unsigned MinNumElts);
0402 
0403   static ScalableVectorType *get(Type *ElementType,
0404                                  const ScalableVectorType *SVTy) {
0405     return get(ElementType, SVTy->getMinNumElements());
0406   }
0407 
0408   static ScalableVectorType *getInteger(ScalableVectorType *VTy) {
0409     return cast<ScalableVectorType>(VectorType::getInteger(VTy));
0410   }
0411 
0412   static ScalableVectorType *
0413   getExtendedElementVectorType(ScalableVectorType *VTy) {
0414     return cast<ScalableVectorType>(
0415         VectorType::getExtendedElementVectorType(VTy));
0416   }
0417 
0418   static ScalableVectorType *
0419   getTruncatedElementVectorType(ScalableVectorType *VTy) {
0420     return cast<ScalableVectorType>(
0421         VectorType::getTruncatedElementVectorType(VTy));
0422   }
0423 
0424   static ScalableVectorType *getSubdividedVectorType(ScalableVectorType *VTy,
0425                                                      int NumSubdivs) {
0426     return cast<ScalableVectorType>(
0427         VectorType::getSubdividedVectorType(VTy, NumSubdivs));
0428   }
0429 
0430   static ScalableVectorType *
0431   getHalfElementsVectorType(ScalableVectorType *VTy) {
0432     return cast<ScalableVectorType>(VectorType::getHalfElementsVectorType(VTy));
0433   }
0434 
0435   static ScalableVectorType *
0436   getDoubleElementsVectorType(ScalableVectorType *VTy) {
0437     return cast<ScalableVectorType>(
0438         VectorType::getDoubleElementsVectorType(VTy));
0439   }
0440 
0441   unsigned getMinNumElements() const {
0442     return cast<llvm::ScalableVectorType>(LLVMTy)->getMinNumElements();
0443   }
0444 
0445   static bool classof(const Type *T) {
0446     return isa<llvm::ScalableVectorType>(T->LLVMTy);
0447   }
0448 };
0449 
0450 class FunctionType : public Type {
0451 public:
0452   // TODO: add missing functions
0453   static bool classof(const Type *From) {
0454     return isa<llvm::FunctionType>(From->LLVMTy);
0455   }
0456 };
0457 
0458 /// Class to represent integer types. Note that this class is also used to
0459 /// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
0460 /// Int64Ty.
0461 /// Integer representation type
0462 class IntegerType : public Type {
0463 public:
0464   static IntegerType *get(Context &C, unsigned NumBits);
0465   // TODO: add missing functions
0466   static bool classof(const Type *From) {
0467     return isa<llvm::IntegerType>(From->LLVMTy);
0468   }
0469   operator llvm::IntegerType &() const {
0470     return *cast<llvm::IntegerType>(LLVMTy);
0471   }
0472 };
0473 
0474 } // namespace llvm::sandboxir
0475 
0476 #endif // LLVM_SANDBOXIR_TYPE_H