diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.h b/flang/include/flang/Optimizer/Dialect/FIROps.h --- a/flang/include/flang/Optimizer/Dialect/FIROps.h +++ b/flang/include/flang/Optimizer/Dialect/FIROps.h @@ -9,6 +9,7 @@ #ifndef OPTIMIZER_DIALECT_FIROPS_H #define OPTIMIZER_DIALECT_FIROPS_H +#include "flang/Optimizer/Dialect/FIRType.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" #include "mlir/Interfaces/LoopLikeInterface.h" #include "mlir/Interfaces/SideEffectInterfaces.h" diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -83,9 +83,6 @@ def AnyReferenceLike : TypeConstraint, "any reference">; -// A descriptor tuple (captures a reference to an entity and other information) -def fir_BoxType : Type()">, "box type">; - // CHARACTER type descriptor. A pair of a data reference and a LEN value. def fir_BoxCharType : Type()">, "box character type">; @@ -94,11 +91,11 @@ def fir_BoxProcType : Type()">, "box procedure type">; -def AnyBoxLike : TypeConstraint, "any box">; def AnyRefOrBox : TypeConstraint, + fir_HeapType.predicate, fir_PointerType.predicate, BoxType.predicate]>, "any reference or box">; def AnyShapeLike : TypeConstraint:$args); - let results = (outs fir_BoxType); + let results = (outs BoxType); let parser = "return parseEmboxOp(parser, result);"; @@ -1257,7 +1254,7 @@ ``` }]; - let arguments = (ins fir_BoxType:$box); + let arguments = (ins BoxType:$box); let results = (outs fir_ReferenceType, // pointer to data @@ -1328,7 +1325,7 @@ ``` }]; - let arguments = (ins fir_BoxType:$val); + let arguments = (ins BoxType:$val); let results = (outs AnyReferenceLike); @@ -1372,7 +1369,7 @@ the box. The triple will be the lower bound, upper bound, and stride. }]; - let arguments = (ins fir_BoxType:$val, AnyIntegerLike:$dim); + let arguments = (ins BoxType:$val, AnyIntegerLike:$dim); let results = (outs AnyIntegerLike, AnyIntegerLike, AnyIntegerLike); @@ -1401,7 +1398,7 @@ must box an array of REAL values (with dynamic rank and extent). }]; - let arguments = (ins fir_BoxType:$val); + let arguments = (ins BoxType:$val); let results = (outs AnyIntegerLike); } @@ -1424,7 +1421,7 @@ variable is an `ALLOCATABLE`. }]; - let arguments = (ins fir_BoxType:$val); + let arguments = (ins BoxType:$val); let results = (outs BoolLike); } @@ -1445,7 +1442,7 @@ ``` }]; - let arguments = (ins fir_BoxType:$val); + let arguments = (ins BoxType:$val); let results = (outs BoolLike); } @@ -1463,7 +1460,7 @@ ``` }]; - let arguments = (ins fir_BoxType:$val); + let arguments = (ins BoxType:$val); let results = (outs BoolLike); } @@ -1507,7 +1504,7 @@ descriptor may be either an array or a scalar, so the value is nonnegative. }]; - let arguments = (ins fir_BoxType:$val); + let arguments = (ins BoxType:$val); let results = (outs AnyIntegerType); } @@ -1525,7 +1522,7 @@ ``` }]; - let arguments = (ins fir_BoxType:$val); + let arguments = (ins BoxType:$val); let results = (outs fir_TypeDescType); } @@ -2100,7 +2097,7 @@ let arguments = (ins StrAttr:$method, - fir_BoxType:$object, + BoxType:$object, Variadic:$args ); diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h --- a/flang/include/flang/Optimizer/Dialect/FIRType.h +++ b/flang/include/flang/Optimizer/Dialect/FIRType.h @@ -42,7 +42,6 @@ using KindTy = unsigned; namespace detail { -struct BoxTypeStorage; struct BoxCharTypeStorage; struct BoxProcTypeStorage; struct CharacterTypeStorage; @@ -178,23 +177,6 @@ // FIR support types -/// The type of a Fortran descriptor. Descriptors are tuples of information that -/// describe an entity being passed from a calling context. This information -/// might include (but is not limited to) whether the entity is an array, its -/// size, or what type it has. -class BoxType - : public mlir::Type::TypeBase { -public: - using Base::Base; - static BoxType get(mlir::Type eleTy, mlir::AffineMapAttr map = {}); - mlir::Type getEleTy() const; - mlir::AffineMapAttr getLayoutMap() const; - - static mlir::LogicalResult - verifyConstructionInvariants(mlir::Location, mlir::Type eleTy, - mlir::AffineMapAttr map); -}; - /// The type of a pair that describes a CHARACTER variable. Specifically, a /// CHARACTER consists of a reference to a buffer (the string value) and a LEN /// type parameter (the runtime length of the buffer). diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td --- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td +++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td @@ -21,6 +21,29 @@ let mnemonic = typeMnemonic; } +def BoxType : FIR_Type<"Box", "box"> { + let summary = "The type of a Fortran descriptor"; + + let description = [{ + Descriptors are tuples of information that describe an entity being passed + from a calling context. This information might include (but is not limited + to) whether the entity is an array, its size, or what type it has. + }]; + + let parameters = (ins "mlir::Type":$eleTy, "mlir::AffineMapAttr":$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 genVerifyInvariantsDecl = 1; +} + def ShapeType : FIR_Type<"Shape", "shape"> { let summary = "shape of a multidimensional array object"; diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -58,27 +58,6 @@ return TYPE::get(ty); } -// `box` `<` type (',' affine-map)? `>` -BoxType parseBox(mlir::DialectAsmParser &parser, mlir::Location loc) { - mlir::Type ofTy; - if (parser.parseLess() || parser.parseType(ofTy)) { - parser.emitError(parser.getCurrentLocation(), "expected type parameter"); - return {}; - } - - mlir::AffineMapAttr map; - if (!parser.parseOptionalComma()) - if (parser.parseAttribute(map)) { - parser.emitError(parser.getCurrentLocation(), "expected affine map"); - return {}; - } - if (parser.parseGreater()) { - parser.emitError(parser.getCurrentLocation(), "expected '>'"); - return {}; - } - return BoxType::get(ofTy, map); -} - // `boxchar` `<` kind `>` BoxCharType parseBoxChar(mlir::DialectAsmParser &parser) { return parseKindSingleton(parser); @@ -355,7 +334,7 @@ if (typeNameLit == "array") return parseSequence(parser, loc); if (typeNameLit == "box") - return parseBox(parser, loc); + return generatedTypeParser(dialect->getContext(), parser, typeNameLit); if (typeNameLit == "boxchar") return parseBoxChar(parser); if (typeNameLit == "boxproc") @@ -594,41 +573,6 @@ explicit RealTypeStorage(KindTy kind) : kind{kind} {} }; -/// Boxed object (a Fortran descriptor) -struct BoxTypeStorage : public mlir::TypeStorage { - using KeyTy = std::tuple; - - static unsigned hashKey(const KeyTy &key) { - auto hashVal{llvm::hash_combine(std::get(key))}; - return llvm::hash_combine( - hashVal, llvm::hash_combine(std::get(key))); - } - - bool operator==(const KeyTy &key) const { - return std::get(key) == getElementType() && - std::get(key) == getLayoutMap(); - } - - static BoxTypeStorage *construct(mlir::TypeStorageAllocator &allocator, - const KeyTy &key) { - auto *storage = allocator.allocate(); - return new (storage) BoxTypeStorage{std::get(key), - std::get(key)}; - } - - mlir::Type getElementType() const { return eleTy; } - mlir::AffineMapAttr getLayoutMap() const { return map; } - -protected: - mlir::Type eleTy; - mlir::AffineMapAttr map; - -private: - BoxTypeStorage() = delete; - explicit BoxTypeStorage(mlir::Type eleTy, mlir::AffineMapAttr map) - : eleTy{eleTy}, map{map} {} -}; - /// Boxed CHARACTER object type struct BoxCharTypeStorage : public mlir::TypeStorage { using KeyTy = KindTy; @@ -1013,20 +957,6 @@ KindTy fir::RealType::getFKind() const { return getImpl()->getFKind(); } -// Box - -BoxType fir::BoxType::get(mlir::Type elementType, mlir::AffineMapAttr map) { - return Base::get(elementType.getContext(), elementType, map); -} - -mlir::Type fir::BoxType::getEleTy() const { - return getImpl()->getElementType(); -} - -mlir::AffineMapAttr fir::BoxType::getLayoutMap() const { - return getImpl()->getLayoutMap(); -} - mlir::LogicalResult fir::BoxType::verifyConstructionInvariants(mlir::Location, mlir::Type eleTy, mlir::AffineMapAttr map) { @@ -1340,16 +1270,6 @@ void fir::printFirType(FIROpsDialect *, mlir::Type ty, mlir::DialectAsmPrinter &p) { auto &os = p.getStream(); - if (auto type = ty.dyn_cast()) { - os << "box<"; - p.printType(type.getEleTy()); - if (auto map = type.getLayoutMap()) { - os << ", "; - p.printAttribute(map); - } - os << '>'; - return; - } if (auto type = ty.dyn_cast()) { os << "boxchar<" << type.getEleTy().cast().getFKind() << '>'; @@ -1500,3 +1420,44 @@ } return false; } + +namespace fir { + +//===----------------------------------------------------------------------===// +// BoxType +//===----------------------------------------------------------------------===// + +// `box` `<` type (',' affine-map)? `>` +mlir::Type BoxType::parse(mlir::MLIRContext *context, + mlir::DialectAsmParser &parser) { + mlir::Type ofTy; + if (parser.parseLess() || parser.parseType(ofTy)) { + parser.emitError(parser.getCurrentLocation(), "expected type parameter"); + return Type(); + } + + mlir::AffineMapAttr map; + if (!parser.parseOptionalComma()) { + if (parser.parseAttribute(map)) { + parser.emitError(parser.getCurrentLocation(), "expected affine map"); + return Type(); + } + } + if (parser.parseGreater()) { + parser.emitError(parser.getCurrentLocation(), "expected '>'"); + return Type(); + } + return get(ofTy, map); +} + +void BoxType::print(::mlir::DialectAsmPrinter &printer) const { + printer << "box<"; + printer.printType(getEleTy()); + if (auto map = getLayoutMap()) { + printer << ", "; + printer.printAttribute(map); + } + printer << '>'; +} + +} // namespace fir