From 661f9e2a92302b1c7140528423fdbfc133a68b41 Mon Sep 17 00:00:00 2001 From: clementval Date: Thu, 11 Feb 2021 11:36:35 -0500 Subject: [PATCH] Revert "[flang][fir][NFC] Move BoxType to TableGen type definition" This reverts commit d96bb48f7874d636ffd0ee233e2d66fff0614b8f. --- .../include/flang/Optimizer/Dialect/FIROps.h | 1 - .../include/flang/Optimizer/Dialect/FIROps.td | 29 +++-- .../include/flang/Optimizer/Dialect/FIRType.h | 18 +++ .../flang/Optimizer/Dialect/FIRTypes.td | 23 ---- flang/lib/Optimizer/Dialect/FIRType.cpp | 123 ++++++++++++------ 5 files changed, 115 insertions(+), 79 deletions(-) diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.h b/flang/include/flang/Optimizer/Dialect/FIROps.h index c9541c8b1e3a..66477846589a 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.h +++ b/flang/include/flang/Optimizer/Dialect/FIROps.h @@ -9,7 +9,6 @@ #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 index ebed9f5b2522..918fdd400c3c 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -83,6 +83,9 @@ def fir_PointerType : Type()">, 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">; @@ -91,11 +94,11 @@ def fir_BoxCharType : Type()">, def fir_BoxProcType : Type()">, "box procedure type">; -def AnyBoxLike : TypeConstraint, "any box">; def AnyRefOrBox : TypeConstraint, + fir_HeapType.predicate, fir_PointerType.predicate, fir_BoxType.predicate]>, "any reference or box">; def AnyShapeLike : TypeConstraint { let arguments = (ins AnyReferenceLike:$memref, Variadic:$args); - let results = (outs BoxType); + let results = (outs fir_BoxType); let parser = "return parseEmboxOp(parser, result);"; @@ -1254,7 +1257,7 @@ def fir_UnboxOp : fir_SimpleOp<"unbox", [NoSideEffect]> { ``` }]; - let arguments = (ins BoxType:$box); + let arguments = (ins fir_BoxType:$box); let results = (outs fir_ReferenceType, // pointer to data @@ -1325,7 +1328,7 @@ def fir_BoxAddrOp : fir_SimpleOneResultOp<"box_addr", [NoSideEffect]> { ``` }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs AnyReferenceLike); @@ -1369,7 +1372,7 @@ def fir_BoxDimsOp : fir_Op<"box_dims", [NoSideEffect]> { the box. The triple will be the lower bound, upper bound, and stride. }]; - let arguments = (ins BoxType:$val, AnyIntegerLike:$dim); + let arguments = (ins fir_BoxType:$val, AnyIntegerLike:$dim); let results = (outs AnyIntegerLike, AnyIntegerLike, AnyIntegerLike); @@ -1398,7 +1401,7 @@ def fir_BoxEleSizeOp : fir_SimpleOneResultOp<"box_elesize", [NoSideEffect]> { must box an array of REAL values (with dynamic rank and extent). }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs AnyIntegerLike); } @@ -1421,7 +1424,7 @@ def fir_BoxIsAllocOp : fir_SimpleOp<"box_isalloc", [NoSideEffect]> { variable is an `ALLOCATABLE`. }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs BoolLike); } @@ -1442,7 +1445,7 @@ def fir_BoxIsArrayOp : fir_SimpleOp<"box_isarray", [NoSideEffect]> { ``` }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs BoolLike); } @@ -1460,7 +1463,7 @@ def fir_BoxIsPtrOp : fir_SimpleOp<"box_isptr", [NoSideEffect]> { ``` }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs BoolLike); } @@ -1504,7 +1507,7 @@ def fir_BoxRankOp : fir_SimpleOneResultOp<"box_rank", [NoSideEffect]> { descriptor may be either an array or a scalar, so the value is nonnegative. }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs AnyIntegerType); } @@ -1522,7 +1525,7 @@ def fir_BoxTypeDescOp : fir_SimpleOneResultOp<"box_tdesc", [NoSideEffect]> { ``` }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs fir_TypeDescType); } @@ -2097,7 +2100,7 @@ def fir_DispatchOp : fir_Op<"dispatch", let arguments = (ins StrAttr:$method, - BoxType:$object, + fir_BoxType:$object, Variadic:$args ); diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h index a531a514f224..44e676ce9736 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRType.h +++ b/flang/include/flang/Optimizer/Dialect/FIRType.h @@ -42,6 +42,7 @@ class FIROpsDialect; using KindTy = unsigned; namespace detail { +struct BoxTypeStorage; struct BoxCharTypeStorage; struct BoxProcTypeStorage; struct CharacterTypeStorage; @@ -177,6 +178,23 @@ public: // 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 index 5a25d9e5f26f..99f1c179da87 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td +++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td @@ -21,29 +21,6 @@ class FIR_Type : TypeDef { 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, 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 index 35e71a7560ca..c0fd3d3f86df 100644 --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -58,6 +58,27 @@ TYPE parseTypeSingleton(mlir::DialectAsmParser &parser, mlir::Location) { 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); @@ -334,7 +355,7 @@ mlir::Type fir::parseFirType(FIROpsDialect *dialect, if (typeNameLit == "array") return parseSequence(parser, loc); if (typeNameLit == "box") - return generatedTypeParser(dialect->getContext(), parser, typeNameLit); + return parseBox(parser, loc); if (typeNameLit == "boxchar") return parseBoxChar(parser); if (typeNameLit == "boxproc") @@ -573,6 +594,41 @@ private: 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; @@ -957,6 +1013,20 @@ RealType fir::RealType::get(mlir::MLIRContext *ctxt, KindTy kind) { 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) { @@ -1270,6 +1340,16 @@ void fir::verifyIntegralType(mlir::Type type) { 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() << '>'; @@ -1420,44 +1500,3 @@ bool fir::isa_unknown_size_box(mlir::Type t) { } 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