mirror of
https://github.com/intel/llvm.git
synced 2026-02-03 10:39:35 +08:00
[flang][fir][NFC] Move remaining types to TableGen type definition
Move the remaing of FIR types to TableGen type definition. This follow suggestion in D96422. Reviewed By: schweitz, jeanPerier, rriddle Differential Revision: https://reviews.llvm.org/D96987
This commit is contained in:
committed by
clementval
parent
a9b33ffb8f
commit
841f6995cd
@@ -22,94 +22,6 @@ include "mlir/Interfaces/SideEffectInterfaces.td"
|
||||
|
||||
include "flang/Optimizer/Dialect/FIRTypes.td"
|
||||
|
||||
// Types and predicates
|
||||
|
||||
def fir_Type : Type<CPred<"fir::isa_fir_or_std_type($_self)">,
|
||||
"FIR dialect type">;
|
||||
|
||||
// Fortran intrinsic types
|
||||
def fir_IntegerType : Type<CPred<"$_self.isa<fir::IntegerType>()">,
|
||||
"FIR integer type">;
|
||||
def fir_LogicalType : Type<CPred<"$_self.isa<fir::LogicalType>()">,
|
||||
"FIR logical type">;
|
||||
def fir_RealType : Type<CPred<"$_self.isa<fir::RealType>()">,
|
||||
"FIR real type">;
|
||||
def fir_VectorType : Type<CPred<"$_self.isa<fir::VectorType>()">,
|
||||
"FIR vector type">;
|
||||
|
||||
// Generalized FIR and standard dialect types representing intrinsic types
|
||||
def AnyIntegerLike : TypeConstraint<Or<[SignlessIntegerLike.predicate,
|
||||
fir_IntegerType.predicate]>, "any integer">;
|
||||
def AnyLogicalLike : TypeConstraint<Or<[BoolLike.predicate,
|
||||
fir_LogicalType.predicate]>, "any logical">;
|
||||
def AnyRealLike : TypeConstraint<Or<[FloatLike.predicate,
|
||||
fir_RealType.predicate]>, "any real">;
|
||||
def AnyIntegerType : Type<AnyIntegerLike.predicate, "any integer">;
|
||||
|
||||
// Fortran derived (user defined) type
|
||||
def fir_RecordType : Type<CPred<"$_self.isa<fir::RecordType>()">,
|
||||
"FIR derived type">;
|
||||
|
||||
// Fortran array attribute
|
||||
def fir_SequenceType : Type<CPred<"$_self.isa<fir::SequenceType>()">,
|
||||
"array type">;
|
||||
|
||||
// Composable types
|
||||
def AnyCompositeLike : TypeConstraint<Or<[fir_RecordType.predicate,
|
||||
fir_SequenceType.predicate, fir_ComplexType.predicate,
|
||||
fir_VectorType.predicate, IsTupleTypePred]>, "any composite">;
|
||||
|
||||
// Reference to an entity type
|
||||
def fir_ReferenceType : Type<CPred<"$_self.isa<fir::ReferenceType>()">,
|
||||
"reference type">;
|
||||
|
||||
// Reference to an ALLOCATABLE attribute type
|
||||
def fir_HeapType : Type<CPred<"$_self.isa<fir::HeapType>()">,
|
||||
"allocatable type">;
|
||||
|
||||
// Reference to a POINTER attribute type
|
||||
def fir_PointerType : Type<CPred<"$_self.isa<fir::PointerType>()">,
|
||||
"pointer type">;
|
||||
|
||||
// Reference types
|
||||
def AnyReferenceLike : TypeConstraint<Or<[fir_ReferenceType.predicate,
|
||||
fir_HeapType.predicate, fir_PointerType.predicate]>, "any reference">;
|
||||
|
||||
def AnyBoxLike : TypeConstraint<Or<[fir_BoxType.predicate,
|
||||
fir_BoxCharType.predicate, fir_BoxProcType.predicate]>, "any box">;
|
||||
|
||||
def AnyRefOrBox : TypeConstraint<Or<[fir_ReferenceType.predicate,
|
||||
fir_HeapType.predicate, fir_PointerType.predicate, fir_BoxType.predicate]>,
|
||||
"any reference or box">;
|
||||
|
||||
def AnyShapeLike : TypeConstraint<Or<[fir_ShapeType.predicate,
|
||||
fir_ShapeShiftType.predicate]>, "any legal shape type">;
|
||||
def AnyShapeType : Type<AnyShapeLike.predicate, "any legal shape type">;
|
||||
def fir_SliceType : Type<CPred<"$_self.isa<fir::SliceType>()">, "slice type">;
|
||||
|
||||
def AnyEmboxLike : TypeConstraint<Or<[AnySignlessInteger.predicate,
|
||||
Index.predicate, fir_IntegerType.predicate]>,
|
||||
"any legal embox argument type">;
|
||||
def AnyEmboxArg : Type<AnyEmboxLike.predicate, "embox argument type">;
|
||||
|
||||
// A type descriptor's type
|
||||
def fir_TypeDescType : Type<CPred<"$_self.isa<fir::TypeDescType>()">,
|
||||
"type desc type">;
|
||||
|
||||
// A LEN parameter (in a RecordType) argument's type
|
||||
def fir_LenType : Type<CPred<"$_self.isa<fir::LenType>()">,
|
||||
"LEN parameter type">;
|
||||
|
||||
def AnyComponentLike : TypeConstraint<Or<[AnySignlessInteger.predicate,
|
||||
Index.predicate, fir_IntegerType.predicate, fir_FieldType.predicate]>,
|
||||
"any coordinate index">;
|
||||
def AnyComponentType : Type<AnyComponentLike.predicate, "coordinate type">;
|
||||
|
||||
def AnyCoordinateLike : TypeConstraint<Or<[AnySignlessInteger.predicate,
|
||||
Index.predicate, fir_IntegerType.predicate, fir_FieldType.predicate,
|
||||
fir_LenType.predicate]>, "any coordinate index">;
|
||||
def AnyCoordinateType : Type<AnyCoordinateLike.predicate, "coordinate type">;
|
||||
|
||||
// Base class for FIR operations.
|
||||
// All operations automatically get a prefix of "fir.".
|
||||
class fir_Op<string mnemonic, list<OpTrait> traits>
|
||||
@@ -2251,7 +2163,7 @@ def fir_StringLitOp : fir_Op<"string_lit", [NoSideEffect]> {
|
||||
if (!(type.isa<fir::CharacterType>() || type.isa<mlir::IntegerType>()))
|
||||
return parser.emitError(parser.getCurrentLocation(),
|
||||
"must have character type");
|
||||
type = fir::SequenceType::get({sz.getInt()}, type);
|
||||
type = fir::SequenceType::get(type.getContext(), {sz.getInt()}, type, {});
|
||||
if (!type || parser.addTypesToList(type, result.types))
|
||||
return mlir::failure();
|
||||
return mlir::success();
|
||||
|
||||
@@ -41,18 +41,7 @@ class FIROpsDialect;
|
||||
using KindTy = unsigned;
|
||||
|
||||
namespace detail {
|
||||
struct HeapTypeStorage;
|
||||
struct IntegerTypeStorage;
|
||||
struct LenTypeStorage;
|
||||
struct LogicalTypeStorage;
|
||||
struct PointerTypeStorage;
|
||||
struct RealTypeStorage;
|
||||
struct RecordTypeStorage;
|
||||
struct ReferenceTypeStorage;
|
||||
struct SequenceTypeStorage;
|
||||
struct SliceTypeStorage;
|
||||
struct TypeDescTypeStorage;
|
||||
struct VectorTypeStorage;
|
||||
} // namespace detail
|
||||
|
||||
// These isa_ routines follow the precedent of llvm::isa_or_null<>
|
||||
@@ -91,213 +80,6 @@ bool isa_aggregate(mlir::Type t);
|
||||
/// not a memory reference type, then returns a null `Type`.
|
||||
mlir::Type dyn_cast_ptrEleTy(mlir::Type t);
|
||||
|
||||
// Intrinsic types
|
||||
|
||||
/// Model of a Fortran INTEGER intrinsic type, including the KIND type
|
||||
/// parameter.
|
||||
class IntegerType : public mlir::Type::TypeBase<fir::IntegerType, mlir::Type,
|
||||
detail::IntegerTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static fir::IntegerType get(mlir::MLIRContext *ctxt, KindTy kind);
|
||||
KindTy getFKind() const;
|
||||
};
|
||||
|
||||
/// Model of a Fortran LOGICAL intrinsic type, including the KIND type
|
||||
/// parameter.
|
||||
class LogicalType : public mlir::Type::TypeBase<LogicalType, mlir::Type,
|
||||
detail::LogicalTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static LogicalType get(mlir::MLIRContext *ctxt, KindTy kind);
|
||||
KindTy getFKind() const;
|
||||
};
|
||||
|
||||
/// Model of a Fortran REAL (and DOUBLE PRECISION) intrinsic type, including the
|
||||
/// KIND type parameter.
|
||||
class RealType : public mlir::Type::TypeBase<RealType, mlir::Type,
|
||||
detail::RealTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static RealType get(mlir::MLIRContext *ctxt, KindTy kind);
|
||||
KindTy getFKind() const;
|
||||
};
|
||||
|
||||
// FIR support types
|
||||
|
||||
/// Type of a vector that represents an array slice operation on an array.
|
||||
/// Fortran slices are triples of lower bound, upper bound, and stride. The rank
|
||||
/// of a SliceType must be at least 1.
|
||||
class SliceType : public mlir::Type::TypeBase<SliceType, mlir::Type,
|
||||
detail::SliceTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static SliceType get(mlir::MLIRContext *ctx, unsigned rank);
|
||||
unsigned getRank() const;
|
||||
};
|
||||
|
||||
/// The type of a heap pointer. Fortran entities with the ALLOCATABLE attribute
|
||||
/// may be allocated on the heap at runtime. These pointers are explicitly
|
||||
/// distinguished to disallow the composition of multiple levels of
|
||||
/// indirection. For example, an ALLOCATABLE POINTER is invalid.
|
||||
class HeapType : public mlir::Type::TypeBase<HeapType, mlir::Type,
|
||||
detail::HeapTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static HeapType get(mlir::Type elementType);
|
||||
|
||||
mlir::Type getEleTy() const;
|
||||
|
||||
static mlir::LogicalResult
|
||||
verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
|
||||
mlir::Type eleTy);
|
||||
};
|
||||
|
||||
/// The type of a LEN parameter name. Implementations may defer the layout of a
|
||||
/// Fortran derived type until runtime. This implies that the runtime must be
|
||||
/// able to determine the offset of LEN type parameters related to an entity.
|
||||
class LenType
|
||||
: public mlir::Type::TypeBase<LenType, mlir::Type, detail::LenTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static LenType get(mlir::MLIRContext *ctxt);
|
||||
};
|
||||
|
||||
/// The type of entities with the POINTER attribute. These pointers are
|
||||
/// explicitly distinguished to disallow the composition of multiple levels of
|
||||
/// indirection. For example, an ALLOCATABLE POINTER is invalid.
|
||||
class PointerType : public mlir::Type::TypeBase<PointerType, mlir::Type,
|
||||
detail::PointerTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static PointerType get(mlir::Type elementType);
|
||||
|
||||
mlir::Type getEleTy() const;
|
||||
|
||||
static mlir::LogicalResult
|
||||
verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
|
||||
mlir::Type eleTy);
|
||||
};
|
||||
|
||||
/// The type of a reference to an entity in memory.
|
||||
class ReferenceType
|
||||
: public mlir::Type::TypeBase<ReferenceType, mlir::Type,
|
||||
detail::ReferenceTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static ReferenceType get(mlir::Type elementType);
|
||||
|
||||
mlir::Type getEleTy() const;
|
||||
|
||||
static mlir::LogicalResult
|
||||
verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
|
||||
mlir::Type eleTy);
|
||||
};
|
||||
|
||||
/// A sequence type is a multi-dimensional array of values. The sequence type
|
||||
/// may have an unknown number of dimensions or the extent of dimensions may be
|
||||
/// unknown. A sequence type models a Fortran array entity, giving it a type in
|
||||
/// FIR. A sequence type is assumed to be stored in a column-major order, which
|
||||
/// differs from LLVM IR and other dialects of MLIR.
|
||||
class SequenceType : public mlir::Type::TypeBase<SequenceType, mlir::Type,
|
||||
detail::SequenceTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
using Extent = int64_t;
|
||||
using Shape = llvm::SmallVector<Extent, 8>;
|
||||
|
||||
/// Return a sequence type with the specified shape and element type
|
||||
static SequenceType get(const Shape &shape, mlir::Type elementType,
|
||||
mlir::AffineMapAttr map = {});
|
||||
|
||||
/// The element type of this sequence
|
||||
mlir::Type getEleTy() const;
|
||||
|
||||
/// The shape of the sequence. If the sequence has an unknown shape, the shape
|
||||
/// returned will be empty.
|
||||
Shape getShape() const;
|
||||
|
||||
mlir::AffineMapAttr getLayoutMap() const;
|
||||
|
||||
/// The number of dimensions of the sequence
|
||||
unsigned getDimension() const { return getShape().size(); }
|
||||
|
||||
/// Number of rows of constant extent
|
||||
unsigned getConstantRows() const;
|
||||
|
||||
/// Is the shape of the sequence constant?
|
||||
bool hasConstantShape() const { return getConstantRows() == getDimension(); }
|
||||
|
||||
/// Does the sequence have unknown shape? (`array<* x T>`)
|
||||
bool hasUnknownShape() const { return getShape().empty(); }
|
||||
|
||||
/// Is the interior of the sequence constant? Check if the array is
|
||||
/// one of constant shape (`array<C...xCxT>`), unknown shape
|
||||
/// (`array<*xT>`), or rows with shape and ending with column(s) of
|
||||
/// unknown extent (`array<C...xCx?...x?xT>`).
|
||||
bool hasConstantInterior() const;
|
||||
|
||||
/// The value `-1` represents an unknown extent for a dimension
|
||||
static constexpr Extent getUnknownExtent() { return -1; }
|
||||
|
||||
static mlir::LogicalResult
|
||||
verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
|
||||
const Shape &shape, mlir::Type eleTy, mlir::AffineMapAttr map);
|
||||
};
|
||||
|
||||
bool operator==(const SequenceType::Shape &, const SequenceType::Shape &);
|
||||
llvm::hash_code hash_value(const SequenceType::Extent &);
|
||||
llvm::hash_code hash_value(const SequenceType::Shape &);
|
||||
|
||||
/// The type of a type descriptor object. The runtime may generate type
|
||||
/// descriptor objects to determine the type of an entity at runtime, etc.
|
||||
class TypeDescType : public mlir::Type::TypeBase<TypeDescType, mlir::Type,
|
||||
detail::TypeDescTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static TypeDescType get(mlir::Type ofType);
|
||||
mlir::Type getOfTy() const;
|
||||
|
||||
static mlir::LogicalResult
|
||||
verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
|
||||
mlir::Type ofType);
|
||||
};
|
||||
|
||||
// Derived types
|
||||
|
||||
/// Model of Fortran's derived type, TYPE. The name of the TYPE includes any
|
||||
/// KIND type parameters. The record includes runtime slots for LEN type
|
||||
/// parameters and for data components.
|
||||
class RecordType : public mlir::Type::TypeBase<RecordType, mlir::Type,
|
||||
detail::RecordTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
using TypePair = std::pair<std::string, mlir::Type>;
|
||||
using TypeList = std::vector<TypePair>;
|
||||
|
||||
llvm::StringRef getName();
|
||||
TypeList getTypeList();
|
||||
TypeList getLenParamList();
|
||||
|
||||
mlir::Type getType(llvm::StringRef ident);
|
||||
mlir::Type getType(unsigned index) {
|
||||
assert(index < getNumFields());
|
||||
return getTypeList()[index].second;
|
||||
}
|
||||
unsigned getNumFields() { return getTypeList().size(); }
|
||||
unsigned getNumLenParams() { return getLenParamList().size(); }
|
||||
|
||||
static RecordType get(mlir::MLIRContext *ctxt, llvm::StringRef name);
|
||||
void finalize(llvm::ArrayRef<TypePair> lenPList,
|
||||
llvm::ArrayRef<TypePair> typeList);
|
||||
|
||||
detail::RecordTypeStorage const *uniqueKey() const;
|
||||
|
||||
static mlir::LogicalResult
|
||||
verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
|
||||
llvm::StringRef name);
|
||||
};
|
||||
|
||||
/// Is `t` a FIR Real or MLIR Float type?
|
||||
inline bool isa_real(mlir::Type t) {
|
||||
return t.isa<fir::RealType>() || t.isa<mlir::FloatType>();
|
||||
@@ -309,26 +91,6 @@ inline bool isa_integer(mlir::Type t) {
|
||||
t.isa<fir::IntegerType>();
|
||||
}
|
||||
|
||||
/// Replacement for the builtin vector type.
|
||||
/// The FIR vector type is always rank one. It's size is always a constant.
|
||||
/// A vector's element type must be real or integer.
|
||||
class VectorType : public mlir::Type::TypeBase<fir::VectorType, mlir::Type,
|
||||
detail::VectorTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
|
||||
static fir::VectorType get(uint64_t len, mlir::Type eleTy);
|
||||
mlir::Type getEleTy() const;
|
||||
uint64_t getLen() const;
|
||||
|
||||
static mlir::LogicalResult
|
||||
verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError, uint64_t len,
|
||||
mlir::Type eleTy);
|
||||
static bool isValidElementType(mlir::Type t) {
|
||||
return isa_real(t) || isa_integer(t);
|
||||
}
|
||||
};
|
||||
|
||||
mlir::Type parseFirType(FIROpsDialect *, mlir::DialectAsmParser &parser);
|
||||
|
||||
void printFirType(FIROpsDialect *, mlir::Type ty, mlir::DialectAsmPrinter &p);
|
||||
@@ -353,6 +115,14 @@ inline bool isa_char_string(mlir::Type t) {
|
||||
/// of unknown rank or type.
|
||||
bool isa_unknown_size_box(mlir::Type t);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// !fir.ptr<X> and !fir.heap<X> where X is !fir.ptr, !fir.heap, or !fir.ref
|
||||
// is undefined and disallowed.
|
||||
inline bool singleIndirectionLevel(mlir::Type ty) {
|
||||
return !fir::isa_ref_type(ty);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace fir
|
||||
|
||||
#endif // OPTIMIZER_DIALECT_FIRTYPE_H
|
||||
|
||||
@@ -23,6 +23,9 @@ class FIR_Type<string name, string typeMnemonic> : TypeDef<fir_Dialect, name> {
|
||||
let mnemonic = typeMnemonic;
|
||||
}
|
||||
|
||||
def fir_Type : Type<CPred<"fir::isa_fir_or_std_type($_self)">,
|
||||
"FIR dialect type">;
|
||||
|
||||
def fir_BoxCharType : FIR_Type<"BoxChar", "boxchar"> {
|
||||
let summary = "CHARACTER type descriptor.";
|
||||
|
||||
@@ -34,10 +37,6 @@ def fir_BoxCharType : FIR_Type<"BoxChar", "boxchar"> {
|
||||
|
||||
let parameters = (ins "KindTy":$kind);
|
||||
|
||||
let printer = [{
|
||||
$_printer << "boxchar<" << getImpl()->kind << ">";
|
||||
}];
|
||||
|
||||
let genAccessors = 1;
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
@@ -61,13 +60,6 @@ def fir_BoxProcType : FIR_Type<"BoxProc", "boxproc"> {
|
||||
|
||||
let parameters = (ins "mlir::Type":$eleTy);
|
||||
|
||||
let printer = [{
|
||||
$_printer << "boxproc<";
|
||||
$_printer.printType(getEleTy());
|
||||
$_printer << '>';
|
||||
}];
|
||||
|
||||
let genAccessors = 1;
|
||||
let genVerifyDecl = 1;
|
||||
}
|
||||
|
||||
@@ -82,15 +74,21 @@ def fir_BoxType : FIR_Type<"Box", "box"> {
|
||||
|
||||
let parameters = (ins "mlir::Type":$eleTy, "mlir::AffineMapAttr":$map);
|
||||
|
||||
let skipDefaultBuilders = 1;
|
||||
|
||||
let builders = [
|
||||
TypeBuilderWithInferredContext<(ins
|
||||
"mlir::Type":$eleTy,
|
||||
CArg<"mlir::AffineMapAttr", "{}">:$map), [{
|
||||
return Base::get(eleTy.getContext(), eleTy, map);
|
||||
}]>,
|
||||
];
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
mlir::Type getElementType() const { return getEleTy(); }
|
||||
mlir::AffineMapAttr getLayoutMap() const { return getMap(); }
|
||||
static BoxType get(mlir::Type eleTy, mlir::AffineMapAttr map = {}) {
|
||||
return get(eleTy.getContext(), eleTy, map);
|
||||
}
|
||||
}];
|
||||
|
||||
let genAccessors = 1;
|
||||
let genVerifyDecl = 1;
|
||||
}
|
||||
|
||||
@@ -138,12 +136,6 @@ def fir_ComplexType : FIR_Type<"Complex", "complex"> {
|
||||
|
||||
let parameters = (ins "KindTy":$fKind);
|
||||
|
||||
let printer = [{
|
||||
$_printer << "complex<" << getFKind() << '>';
|
||||
}];
|
||||
|
||||
let genAccessors = 1;
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
using KindTy = unsigned;
|
||||
|
||||
@@ -159,14 +151,176 @@ def fir_FieldType : FIR_Type<"Field", "field"> {
|
||||
derived type until runtime. This implies that the runtime must be able to
|
||||
determine the offset of fields within the entity.
|
||||
}];
|
||||
}
|
||||
|
||||
let printer = [{
|
||||
$_printer << "field";
|
||||
def fir_HeapType : FIR_Type<"Heap", "heap"> {
|
||||
let summary = "Reference to an ALLOCATABLE attribute type";
|
||||
|
||||
let description = [{
|
||||
The type of a heap pointer. Fortran entities with the ALLOCATABLE attribute
|
||||
may be allocated on the heap at runtime. These pointers are explicitly
|
||||
distinguished to disallow the composition of multiple levels of
|
||||
indirection. For example, an ALLOCATABLE POINTER is invalid.
|
||||
}];
|
||||
|
||||
let parser = [{
|
||||
return get(context);
|
||||
let parameters = (ins "mlir::Type":$eleTy);
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
|
||||
let skipDefaultBuilders = 1;
|
||||
|
||||
let builders = [
|
||||
TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{
|
||||
assert(singleIndirectionLevel(elementType) && "invalid element type");
|
||||
return Base::get(elementType.getContext(), elementType);
|
||||
}]>,
|
||||
];
|
||||
}
|
||||
|
||||
def fir_IntegerType : FIR_Type<"Integer", "int"> {
|
||||
let summary = "FIR integer type";
|
||||
|
||||
let description = [{
|
||||
Model of a Fortran INTEGER intrinsic type, including the KIND type
|
||||
parameter.
|
||||
}];
|
||||
|
||||
let parameters = (ins "KindTy":$fKind);
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
using KindTy = unsigned;
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_LenType : FIR_Type<"Len", "len"> {
|
||||
let summary = "A LEN parameter (in a RecordType) argument's type";
|
||||
|
||||
let description = [{
|
||||
The type of a LEN parameter name. Implementations may defer the layout of a
|
||||
Fortran derived type until runtime. This implies that the runtime must be
|
||||
able to determine the offset of LEN type parameters related to an entity.
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_LogicalType : FIR_Type<"Logical", "logical"> {
|
||||
let summary = "FIR logical type";
|
||||
|
||||
let description = [{
|
||||
Model of a Fortran LOGICAL intrinsic type, including the KIND type
|
||||
parameter.
|
||||
}];
|
||||
|
||||
let parameters = (ins "KindTy":$fKind);
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
using KindTy = unsigned;
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_PointerType : FIR_Type<"Pointer", "ptr"> {
|
||||
let summary = "Reference to a POINTER attribute type";
|
||||
|
||||
let description = [{
|
||||
The type of entities with the POINTER attribute. These pointers are
|
||||
explicitly distinguished to disallow the composition of multiple levels of
|
||||
indirection. For example, an ALLOCATABLE POINTER is invalid.
|
||||
}];
|
||||
|
||||
let parameters = (ins "mlir::Type":$eleTy);
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
|
||||
let skipDefaultBuilders = 1;
|
||||
|
||||
let builders = [
|
||||
TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{
|
||||
assert(singleIndirectionLevel(elementType) && "invalid element type");
|
||||
return Base::get(elementType.getContext(), elementType);
|
||||
}]>,
|
||||
];
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
mlir::Type getElementType() const { return getEleTy(); }
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_RealType : FIR_Type<"Real", "real"> {
|
||||
let summary = "FIR real type";
|
||||
|
||||
let description = [{
|
||||
Model of a Fortran REAL (and DOUBLE PRECISION) intrinsic type, including the
|
||||
KIND type parameter.
|
||||
}];
|
||||
|
||||
let parameters = (ins "KindTy":$fKind);
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
using KindTy = unsigned;
|
||||
}];
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
}
|
||||
|
||||
def fir_RecordType : FIR_Type<"Record", "type"> {
|
||||
let summary = "FIR derived type";
|
||||
|
||||
let description = [{
|
||||
Model of Fortran's derived type, TYPE. The name of the TYPE includes any
|
||||
KIND type parameters. The record includes runtime slots for LEN type
|
||||
parameters and for data components.
|
||||
}];
|
||||
|
||||
let parameters = (ins StringRefParameter<"name">:$name);
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
let genStorageClass = 0;
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
using TypePair = std::pair<std::string, mlir::Type>;
|
||||
using TypeList = std::vector<TypePair>;
|
||||
TypeList getTypeList() const;
|
||||
TypeList getLenParamList() const;
|
||||
|
||||
mlir::Type getType(llvm::StringRef ident);
|
||||
// Returns the index of the field \p ident in the type list.
|
||||
// Returns maximum unsigned if ident is not a field of this RecordType.
|
||||
unsigned getFieldIndex(llvm::StringRef ident);
|
||||
mlir::Type getType(unsigned index) {
|
||||
assert(index < getNumFields());
|
||||
return getTypeList()[index].second;
|
||||
}
|
||||
unsigned getNumFields() { return getTypeList().size(); }
|
||||
unsigned getNumLenParams() { return getLenParamList().size(); }
|
||||
|
||||
void finalize(llvm::ArrayRef<TypePair> lenPList,
|
||||
llvm::ArrayRef<TypePair> typeList);
|
||||
|
||||
detail::RecordTypeStorage const *uniqueKey() const;
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_ReferenceType : FIR_Type<"Reference", "ref"> {
|
||||
let summary = "Reference to an entity type";
|
||||
|
||||
let description = [{
|
||||
The type of a reference to an entity in memory.
|
||||
}];
|
||||
|
||||
let parameters = (ins "mlir::Type":$eleTy);
|
||||
|
||||
let skipDefaultBuilders = 1;
|
||||
|
||||
let builders = [
|
||||
TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{
|
||||
return Base::get(elementType.getContext(), elementType);
|
||||
}]>,
|
||||
];
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
mlir::Type getElementType() const { return getEleTy(); }
|
||||
}];
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
}
|
||||
|
||||
def fir_ShapeType : FIR_Type<"Shape", "shape"> {
|
||||
@@ -179,18 +333,6 @@ def fir_ShapeType : FIR_Type<"Shape", "shape"> {
|
||||
}];
|
||||
|
||||
let parameters = (ins "unsigned":$rank);
|
||||
|
||||
let printer = [{
|
||||
$_printer << "shape<" << getImpl()->rank << ">";
|
||||
}];
|
||||
|
||||
let parser = [{
|
||||
int rank;
|
||||
if ($_parser.parseLess() || $_parser.parseInteger(rank) ||
|
||||
$_parser.parseGreater())
|
||||
return Type();
|
||||
return get(context, rank);
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_ShapeShiftType : FIR_Type<"ShapeShift", "shapeshift"> {
|
||||
@@ -204,18 +346,6 @@ def fir_ShapeShiftType : FIR_Type<"ShapeShift", "shapeshift"> {
|
||||
}];
|
||||
|
||||
let parameters = (ins "unsigned":$rank);
|
||||
|
||||
let printer = [{
|
||||
$_printer << "shapeshift<" << getImpl()->rank << ">";
|
||||
}];
|
||||
|
||||
let parser = [{
|
||||
int rank;
|
||||
if ($_parser.parseLess() || $_parser.parseInteger(rank) ||
|
||||
$_parser.parseGreater())
|
||||
return Type();
|
||||
return get(context, rank);
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_ShiftType : FIR_Type<"Shift", "shift"> {
|
||||
@@ -229,17 +359,189 @@ def fir_ShiftType : FIR_Type<"Shift", "shift"> {
|
||||
|
||||
let parameters = (ins "unsigned":$rank);
|
||||
|
||||
let printer = [{
|
||||
$_printer << "shift<" << getImpl()->rank << ">";
|
||||
}];
|
||||
let extraClassDeclaration = [{
|
||||
using KindTy = unsigned;
|
||||
|
||||
let parser = [{
|
||||
int rank;
|
||||
if ($_parser.parseLess() || $_parser.parseInteger(rank) ||
|
||||
$_parser.parseGreater())
|
||||
return Type();
|
||||
return get(context, rank);
|
||||
// a !fir.boxchar<k> always wraps a !fir.char<k, ?>
|
||||
CharacterType getElementType(mlir::MLIRContext *context) const;
|
||||
|
||||
CharacterType getEleTy() const;
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_SequenceType : FIR_Type<"Sequence", "array"> {
|
||||
let summary = "FIR array type";
|
||||
|
||||
let description = [{
|
||||
A sequence type is a multi-dimensional array of values. The sequence type
|
||||
may have an unknown number of dimensions or the extent of dimensions may be
|
||||
unknown. A sequence type models a Fortran array entity, giving it a type in
|
||||
FIR. A sequence type is assumed to be stored in a column-major order, which
|
||||
differs from LLVM IR and other dialects of MLIR.
|
||||
}];
|
||||
|
||||
let parameters = (ins
|
||||
ArrayRefParameter<"int64_t", "Sequence shape">:$shape,
|
||||
"mlir::Type":$eleTy,
|
||||
"mlir::AffineMapAttr":$layoutMap
|
||||
);
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
|
||||
let builders = [
|
||||
TypeBuilderWithInferredContext<(ins
|
||||
"llvm::ArrayRef<int64_t>":$shape,
|
||||
"mlir::Type":$eleTy), [{
|
||||
return get(eleTy.getContext(), shape, eleTy, {});
|
||||
}]>,
|
||||
];
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
using Extent = int64_t;
|
||||
using Shape = llvm::SmallVector<Extent, 8>;
|
||||
using ShapeRef = llvm::ArrayRef<int64_t>;
|
||||
unsigned getConstantRows() const;
|
||||
|
||||
// The number of dimensions of the sequence
|
||||
unsigned getDimension() const { return getShape().size(); }
|
||||
|
||||
// Is the interior of the sequence constant? Check if the array is
|
||||
// one of constant shape (`array<C...xCxT>`), unknown shape
|
||||
// (`array<*xT>`), or rows with shape and ending with column(s) of
|
||||
// unknown extent (`array<C...xCx?...x?xT>`).
|
||||
bool hasConstantInterior() const;
|
||||
|
||||
// Is the shape of the sequence constant?
|
||||
bool hasConstantShape() const { return getConstantRows() == getDimension(); }
|
||||
|
||||
// Does the sequence have unknown shape? (`array<* x T>`)
|
||||
bool hasUnknownShape() const { return getShape().empty(); }
|
||||
|
||||
// The value `-1` represents an unknown extent for a dimension
|
||||
static constexpr Extent getUnknownExtent() { return -1; }
|
||||
}];
|
||||
}
|
||||
|
||||
def fir_SliceType : FIR_Type<"Slice", "slice"> {
|
||||
let summary = "FIR slice";
|
||||
|
||||
let description = [{
|
||||
Type of a vector that represents an array slice operation on an array.
|
||||
Fortran slices are triples of lower bound, upper bound, and stride. The rank
|
||||
of a SliceType must be at least 1.
|
||||
}];
|
||||
|
||||
let parameters = (ins "unsigned":$rank);
|
||||
}
|
||||
|
||||
def fir_TypeDescType : FIR_Type<"TypeDesc", "tdesc"> {
|
||||
let summary = "FIR Type descriptor type";
|
||||
|
||||
let description = [{
|
||||
The type of a type descriptor object. The runtime may generate type
|
||||
descriptor objects to determine the type of an entity at runtime, etc.
|
||||
}];
|
||||
|
||||
let parameters = (ins "mlir::Type":$ofTy);
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
|
||||
let skipDefaultBuilders = 1;
|
||||
|
||||
let builders = [
|
||||
TypeBuilderWithInferredContext<(ins "mlir::Type":$elementType), [{
|
||||
return Base::get(elementType.getContext(), elementType);
|
||||
}]>,
|
||||
];
|
||||
}
|
||||
|
||||
def fir_VectorType : FIR_Type<"Vector", "vector"> {
|
||||
let summary = "FIR vector type";
|
||||
|
||||
let description = [{
|
||||
Replacement for the builtin vector type.
|
||||
The FIR vector type is always rank one. It's size is always a constant.
|
||||
A vector's element type must be real or integer.
|
||||
}];
|
||||
|
||||
let parameters = (ins "uint64_t":$len, "mlir::Type":$eleTy);
|
||||
|
||||
let genVerifyDecl = 1;
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
static bool isValidElementType(mlir::Type t);
|
||||
}];
|
||||
|
||||
let skipDefaultBuilders = 1;
|
||||
|
||||
let builders = [
|
||||
TypeBuilderWithInferredContext<(ins
|
||||
"uint64_t":$len,
|
||||
"mlir::Type":$eleTy), [{
|
||||
return Base::get(eleTy.getContext(), len, eleTy);
|
||||
}]>,
|
||||
];
|
||||
}
|
||||
|
||||
def fir_VoidType : FIR_Type<"Void", "void"> {
|
||||
let genStorageClass = 0;
|
||||
}
|
||||
|
||||
// Generalized FIR and standard dialect types representing intrinsic types
|
||||
def AnyIntegerLike : TypeConstraint<Or<[SignlessIntegerLike.predicate,
|
||||
AnySignedInteger.predicate, fir_IntegerType.predicate]>, "any integer">;
|
||||
def AnyLogicalLike : TypeConstraint<Or<[BoolLike.predicate,
|
||||
fir_LogicalType.predicate]>, "any logical">;
|
||||
def AnyRealLike : TypeConstraint<Or<[FloatLike.predicate,
|
||||
fir_RealType.predicate]>, "any real">;
|
||||
def AnyIntegerType : Type<AnyIntegerLike.predicate, "any integer">;
|
||||
|
||||
// Composable types
|
||||
def AnyCompositeLike : TypeConstraint<Or<[fir_RecordType.predicate,
|
||||
fir_SequenceType.predicate, fir_ComplexType.predicate,
|
||||
fir_VectorType.predicate, IsTupleTypePred, fir_CharacterType.predicate]>,
|
||||
"any composite">;
|
||||
|
||||
// Reference types
|
||||
def AnyReferenceLike : TypeConstraint<Or<[fir_ReferenceType.predicate,
|
||||
fir_HeapType.predicate, fir_PointerType.predicate]>, "any reference">;
|
||||
|
||||
def AnyBoxLike : TypeConstraint<Or<[fir_BoxType.predicate,
|
||||
fir_BoxCharType.predicate, fir_BoxProcType.predicate]>, "any box">;
|
||||
|
||||
def AnyRefOrBoxLike : TypeConstraint<Or<[AnyReferenceLike.predicate,
|
||||
AnyBoxLike.predicate]>,
|
||||
"any reference or box like">;
|
||||
def AnyRefOrBox : TypeConstraint<Or<[fir_ReferenceType.predicate,
|
||||
fir_HeapType.predicate, fir_PointerType.predicate, fir_BoxType.predicate]>,
|
||||
"any reference or box">;
|
||||
|
||||
def AnyShapeLike : TypeConstraint<Or<[fir_ShapeType.predicate,
|
||||
fir_ShapeShiftType.predicate]>, "any legal shape type">;
|
||||
def AnyShapeType : Type<AnyShapeLike.predicate, "any legal shape type">;
|
||||
def AnyShapeOrShiftLike : TypeConstraint<Or<[fir_ShapeType.predicate,
|
||||
fir_ShapeShiftType.predicate, fir_ShiftType.predicate]>,
|
||||
"any legal shape or shift type">;
|
||||
def AnyShapeOrShiftType : Type<AnyShapeOrShiftLike.predicate,
|
||||
"any legal shape or shift type">;
|
||||
|
||||
def AnyEmboxLike : TypeConstraint<Or<[AnySignlessInteger.predicate,
|
||||
Index.predicate, fir_IntegerType.predicate]>,
|
||||
"any legal embox argument type">;
|
||||
def AnyEmboxArg : Type<AnyEmboxLike.predicate, "embox argument type">;
|
||||
|
||||
def AnyComponentLike : TypeConstraint<Or<[AnySignlessInteger.predicate,
|
||||
Index.predicate, fir_IntegerType.predicate, fir_FieldType.predicate]>,
|
||||
"any coordinate index">;
|
||||
def AnyComponentType : Type<AnyComponentLike.predicate, "coordinate type">;
|
||||
|
||||
def AnyCoordinateLike : TypeConstraint<Or<[AnySignlessInteger.predicate,
|
||||
Index.predicate, fir_IntegerType.predicate, fir_FieldType.predicate,
|
||||
fir_LenType.predicate]>, "any coordinate index">;
|
||||
def AnyCoordinateType : Type<AnyCoordinateLike.predicate, "coordinate type">;
|
||||
|
||||
// The legal types of global symbols
|
||||
def AnyAddressableLike : TypeConstraint<Or<[fir_ReferenceType.predicate,
|
||||
FunctionType.predicate]>, "any addressable">;
|
||||
|
||||
#endif // FIR_DIALECT_FIR_TYPES
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user