[llvm] [SandboxIR] Implement SandboxIR Type (PR #106294)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 29 15:51:52 PDT 2024
================
@@ -0,0 +1,288 @@
+//===- llvm/SandboxIR/Type.h - Classes for handling data types --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a thin wrapper over llvm::Type.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SANDBOXIR_TYPE_H
+#define LLVM_SANDBOXIR_TYPE_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm::sandboxir {
+
+class Context;
+// Forward declare friend classes for MSVC.
+class PointerType;
+class VectorType;
+class FunctionType;
+#define DEF_INSTR(ID, OPCODE, CLASS) class CLASS;
+#include "llvm/SandboxIR/SandboxIRValues.def"
+
+/// Just like llvm::Type these are immutable, unique, never get freed and can
+/// only be created via static factory methods.
+class Type {
+protected:
+ llvm::Type *LLVMTy;
+ friend class VectorType; // For LLVMTy.
+ friend class PointerType; // For LLVMTy.
+ friend class FunctionType; // For LLVMTy.
+ friend class Function; // For LLVMTy.
+ friend class CallBase; // For LLVMTy.
+ friend class ConstantInt; // For LLVMTy.
+ // Friend all instruction classes because `create()` functions use LLVMTy.
+#define DEF_INSTR(ID, OPCODE, CLASS) friend class CLASS;
+ // TODO: Friend DEF_CONST()
+#include "llvm/SandboxIR/SandboxIRValues.def"
+ Context &Ctx;
+
+ Type(llvm::Type *LLVMTy, Context &Ctx) : LLVMTy(LLVMTy), Ctx(Ctx) {}
+ friend class Context; // For constructor and ~Type().
+ ~Type() = default;
+
+public:
+ Context &getContext() const { return Ctx; }
+
+ /// Return true if this is 'void'.
+ bool isVoidTy() const { return LLVMTy->isVoidTy(); }
+
+ /// Return true if this is 'half', a 16-bit IEEE fp type.
+ bool isHalfTy() const { return LLVMTy->isHalfTy(); }
+
+ /// Return true if this is 'bfloat', a 16-bit bfloat type.
+ bool isBFloatTy() const { return LLVMTy->isBFloatTy(); }
+
+ /// Return true if this is a 16-bit float type.
+ bool is16bitFPTy() const { return LLVMTy->is16bitFPTy(); }
+
+ /// Return true if this is 'float', a 32-bit IEEE fp type.
+ bool isFloatTy() const { return LLVMTy->isFloatTy(); }
+
+ /// Return true if this is 'double', a 64-bit IEEE fp type.
+ bool isDoubleTy() const { return LLVMTy->isDoubleTy(); }
+
+ /// Return true if this is x86 long double.
+ bool isX86_FP80Ty() const { return LLVMTy->isX86_FP80Ty(); }
+
+ /// Return true if this is 'fp128'.
+ bool isFP128Ty() const { return LLVMTy->isFP128Ty(); }
+
+ /// Return true if this is powerpc long double.
+ bool isPPC_FP128Ty() const { return LLVMTy->isPPC_FP128Ty(); }
+
+ /// Return true if this is a well-behaved IEEE-like type, which has a IEEE
+ /// compatible layout as defined by APFloat::isIEEE(), and does not have
+ /// non-IEEE values, such as x86_fp80's unnormal values.
+ bool isIEEELikeFPTy() const { return LLVMTy->isIEEELikeFPTy(); }
+
+ /// Return true if this is one of the floating-point types
+ bool isFloatingPointTy() const { return LLVMTy->isFloatingPointTy(); }
+
+ /// Returns true if this is a floating-point type that is an unevaluated sum
+ /// of multiple floating-point units.
+ /// An example of such a type is ppc_fp128, also known as double-double, which
+ /// consists of two IEEE 754 doubles.
+ bool isMultiUnitFPType() const { return LLVMTy->isMultiUnitFPType(); }
+
+ const fltSemantics &getFltSemantics() const {
+ return LLVMTy->getFltSemantics();
+ }
+
+ /// Return true if this is X86 AMX.
+ bool isX86_AMXTy() const { return LLVMTy->isX86_AMXTy(); }
+
+ /// Return true if this is a target extension type.
+ bool isTargetExtTy() const { return LLVMTy->isTargetExtTy(); }
+
+ /// Return true if this is a target extension type with a scalable layout.
+ bool isScalableTargetExtTy() const { return LLVMTy->isScalableTargetExtTy(); }
+
+ /// Return true if this is a type whose size is a known multiple of vscale.
+ bool isScalableTy() const { return LLVMTy->isScalableTy(); }
+
+ /// Return true if this is a FP type or a vector of FP.
+ bool isFPOrFPVectorTy() const { return LLVMTy->isFPOrFPVectorTy(); }
+
+ /// Return true if this is 'label'.
+ bool isLabelTy() const { return LLVMTy->isLabelTy(); }
+
+ /// Return true if this is 'metadata'.
+ bool isMetadataTy() const { return LLVMTy->isMetadataTy(); }
+
+ /// Return true if this is 'token'.
+ bool isTokenTy() const { return LLVMTy->isTokenTy(); }
+
+ /// True if this is an instance of IntegerType.
+ bool isIntegerTy() const { return LLVMTy->isIntegerTy(); }
+
+ /// Return true if this is an IntegerType of the given width.
+ bool isIntegerTy(unsigned Bitwidth) const {
+ return LLVMTy->isIntegerTy(Bitwidth);
+ }
+
+ /// Return true if this is an integer type or a vector of integer types.
+ bool isIntOrIntVectorTy() const { return LLVMTy->isIntOrIntVectorTy(); }
+
+ /// Return true if this is an integer type or a vector of integer types of
+ /// the given width.
+ bool isIntOrIntVectorTy(unsigned BitWidth) const {
+ return LLVMTy->isIntOrIntVectorTy(BitWidth);
+ }
+
+ /// Return true if this is an integer type or a pointer type.
+ bool isIntOrPtrTy() const { return LLVMTy->isIntOrPtrTy(); }
+
+ /// True if this is an instance of FunctionType.
+ bool isFunctionTy() const { return LLVMTy->isFunctionTy(); }
+
+ /// True if this is an instance of StructType.
+ bool isStructTy() const { return LLVMTy->isStructTy(); }
+
+ /// True if this is an instance of ArrayType.
+ bool isArrayTy() const { return LLVMTy->isArrayTy(); }
+
+ /// True if this is an instance of PointerType.
+ bool isPointerTy() const { return LLVMTy->isPointerTy(); }
+
+ /// Return true if this is a pointer type or a vector of pointer types.
+ bool isPtrOrPtrVectorTy() const { return LLVMTy->isPtrOrPtrVectorTy(); }
+
+ /// True if this is an instance of VectorType.
+ inline bool isVectorTy() const { return LLVMTy->isVectorTy(); }
+
+ /// Return true if this type could be converted with a lossless BitCast to
+ /// type 'Ty'. For example, i8* to i32*. BitCasts are valid for types of the
+ /// same size only where no re-interpretation of the bits is done.
+ /// Determine if this type could be losslessly bitcast to Ty
+ bool canLosslesslyBitCastTo(Type *Ty) const {
+ return LLVMTy->canLosslesslyBitCastTo(Ty->LLVMTy);
+ }
+
+ /// Return true if this type is empty, that is, it has no elements or all of
+ /// its elements are empty.
+ bool isEmptyTy() const { return LLVMTy->isEmptyTy(); }
+
+ /// Return true if the type is "first class", meaning it is a valid type for a
+ /// Value.
+ bool isFirstClassType() const { return LLVMTy->isFirstClassType(); }
+
+ /// Return true if the type is a valid type for a register in codegen. This
+ /// includes all first-class types except struct and array types.
+ bool isSingleValueType() const { return LLVMTy->isSingleValueType(); }
+
+ /// Return true if the type is an aggregate type. This means it is valid as
+ /// the first operand of an insertvalue or extractvalue instruction. This
+ /// includes struct and array types, but does not include vector types.
+ bool isAggregateType() const { return LLVMTy->isAggregateType(); }
+
+ /// Return true if it makes sense to take the size of this type. To get the
+ /// actual size for a particular target, it is reasonable to use the
+ /// DataLayout subsystem to do this.
+ bool isSized(SmallPtrSetImpl<Type *> *Visited = nullptr) const {
+ SmallPtrSet<llvm::Type *, 8> LLVMVisited;
+ LLVMVisited.reserve(Visited->size());
+ for (Type *Ty : *Visited)
+ LLVMVisited.insert(Ty->LLVMTy);
+ return LLVMTy->isSized(&LLVMVisited);
+ }
+
+ /// Return the basic size of this type if it is a primitive type. These are
+ /// fixed by LLVM and are not target-dependent.
+ /// This will return zero if the type does not have a size or is not a
+ /// primitive type.
+ ///
+ /// If this is a scalable vector type, the scalable property will be set and
+ /// the runtime size will be a positive integer multiple of the base size.
+ ///
+ /// Note that this may not reflect the size of memory allocated for an
+ /// instance of the type or the number of bytes that are written when an
+ /// instance of the type is stored to memory. The DataLayout class provides
+ /// additional query functions to provide this information.
+ ///
+ TypeSize getPrimitiveSizeInBits() const {
+ return LLVMTy->getPrimitiveSizeInBits();
+ }
+
+ /// If this is a vector type, return the getPrimitiveSizeInBits value for the
+ /// element type. Otherwise return the getPrimitiveSizeInBits value for this
+ /// type.
+ unsigned getScalarSizeInBits() const { return LLVMTy->getScalarSizeInBits(); }
+
+ /// Return the width of the mantissa of this type. This is only valid on
+ /// floating-point types. If the FP type does not have a stable mantissa (e.g.
+ /// ppc long double), this method returns -1.
+ int getFPMantissaWidth() const { return LLVMTy->getFPMantissaWidth(); }
+
+ /// Return whether the type is IEEE compatible, as defined by the eponymous
+ /// method in APFloat.
+ bool isIEEE() const { return LLVMTy->isIEEE(); }
+
+ /// If this is a vector type, return the element type, otherwise return
+ /// 'this'.
+ Type *getScalarType() const;
+
+ // TODO: ADD MISSING
+
+ static Type *getInt64Ty(Context &Ctx);
+ static Type *getInt32Ty(Context &Ctx);
+ static Type *getInt16Ty(Context &Ctx);
+ static Type *getInt8Ty(Context &Ctx);
+ static Type *getInt1Ty(Context &Ctx);
+ static Type *getDoubleTy(Context &Ctx);
+ static Type *getFloatTy(Context &Ctx);
+ // TODO: missing get*
+
+ /// Get the address space of this pointer or pointer vector type.
+ inline unsigned getPointerAddressSpace() const {
+ return LLVMTy->getPointerAddressSpace();
+ }
+
+#ifndef NDEBUG
+ void dumpOS(raw_ostream &OS) { LLVMTy->print(OS); }
+ LLVM_DUMP_METHOD void dump() {
+ dumpOS(dbgs());
+ dbgs() << "\n";
+ }
+#endif // NDEBUG
----------------
vporpo wrote:
Hmm we could wrap that too, but I don't think I have any use for it for now. In LLVM IR it seems to be used in a couple of places though.
https://github.com/llvm/llvm-project/pull/106294
More information about the llvm-commits
mailing list