[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:
Valentin Clement
2021-02-24 20:22:49 -05:00
committed by clementval
parent a9b33ffb8f
commit 841f6995cd
4 changed files with 981 additions and 1404 deletions

View File

@@ -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();

View File

@@ -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

View File

@@ -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