diff --git a/flang/include/flang/Optimizer/Dialect/FIRDialect.td b/flang/include/flang/Optimizer/Dialect/FIRDialect.td new file mode 100644 --- /dev/null +++ b/flang/include/flang/Optimizer/Dialect/FIRDialect.td @@ -0,0 +1,22 @@ +//===-- FIRDialect.td - FIR dialect definition -------------*- tablegen -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Definition of the FIR dialect +/// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_DIALECT_FIR_DIALECT +#define FORTRAN_DIALECT_FIR_DIALECT + +def fir_Dialect : Dialect { + let name = "fir"; + let cppNamespace = "::fir"; +} + +#endif // FORTRAN_DIALECT_FIR_DIALECT 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 @@ -20,11 +20,6 @@ include "mlir/Interfaces/LoopLikeInterface.td" include "mlir/Interfaces/SideEffectInterfaces.td" -def fir_Dialect : Dialect { - let name = "fir"; - let cppNamespace = "::fir"; -} - include "flang/Optimizer/Dialect/FIRTypes.td" // Types and predicates @@ -80,15 +75,15 @@ def AnyReferenceLike : TypeConstraint, "any reference">; -def AnyBoxLike : TypeConstraint, "any box">; def AnyRefOrBox : TypeConstraint, + fir_HeapType.predicate, fir_PointerType.predicate, fir_BoxType.predicate]>, "any reference or box">; -def AnyShapeLike : TypeConstraint, "any legal shape type">; +def AnyShapeLike : TypeConstraint, "any legal shape type">; def AnyShapeType : Type; def fir_SliceType : Type()">, "slice type">; @@ -1068,7 +1063,7 @@ let arguments = (ins AnyReferenceLike:$memref, Variadic:$args); - let results = (outs BoxType); + let results = (outs fir_BoxType); let parser = "return parseEmboxOp(parser, result);"; @@ -1277,7 +1272,7 @@ ``` }]; - let arguments = (ins BoxType:$box); + let arguments = (ins fir_BoxType:$box); let results = (outs fir_ReferenceType, // pointer to data @@ -1348,7 +1343,7 @@ ``` }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs AnyReferenceLike); @@ -1392,7 +1387,7 @@ 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); @@ -1421,7 +1416,7 @@ 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); } @@ -1444,7 +1439,7 @@ variable is an `ALLOCATABLE`. }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs BoolLike); } @@ -1465,7 +1460,7 @@ ``` }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs BoolLike); } @@ -1483,7 +1478,7 @@ ``` }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs BoolLike); } @@ -1527,7 +1522,7 @@ 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); } @@ -1545,7 +1540,7 @@ ``` }]; - let arguments = (ins BoxType:$val); + let arguments = (ins fir_BoxType:$val); let results = (outs fir_TypeDescType); } @@ -1606,7 +1601,7 @@ if (dyn_cast_or_null(co.getDefiningOp())) { if (getNumOperands() != 2) return emitOpError("len_param_index must be last argument"); - if (!ref().getType().dyn_cast()) + if (!ref().getType().dyn_cast()) return emitOpError("len_param_index must be used on box type"); } if (auto attr = (*this)->getAttr(CoordinateOp::baseType())) { @@ -2120,7 +2115,7 @@ let arguments = (ins StrAttr:$method, - BoxType:$object, + fir_BoxType:$object, Variadic:$args ); 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 @@ -13,6 +13,8 @@ #ifndef FIR_DIALECT_FIR_TYPES #define FIR_DIALECT_FIR_TYPES +include "flang/Optimizer/Dialect/FIRDialect.td" + //===----------------------------------------------------------------------===// // FIR Types //===----------------------------------------------------------------------===// @@ -21,6 +23,33 @@ let mnemonic = typeMnemonic; } +def fir_BoxCharType : FIR_Type<"BoxChar", "boxchar"> { + let summary = "CHARACTER type descriptor."; + + let description = [{ + 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). + }]; + + let parameters = (ins "KindTy":$kind); + + let printer = [{ + $_printer << "boxchar<" << getImpl()->kind << ">"; + }]; + + let genAccessors = 1; + + let extraClassDeclaration = [{ + using KindTy = unsigned; + + // a !fir.boxchar always wraps a !fir.char + CharacterType getElementType(mlir::MLIRContext *context) const; + + CharacterType getEleTy() const; + }]; +} + def fir_BoxProcType : FIR_Type<"BoxProc", "boxproc"> { let summary = ""; @@ -39,11 +68,10 @@ }]; let genAccessors = 1; - let genVerifyInvariantsDecl = 1; } -def BoxType : FIR_Type<"Box", "box"> { +def fir_BoxType : FIR_Type<"Box", "box"> { let summary = "The type of a Fortran descriptor"; let description = [{ @@ -63,25 +91,39 @@ }]; let genAccessors = 1; - let genVerifyInvariantsDecl = 1; } -def fir_FieldType : FIR_Type<"Field", "field"> { - let summary = "A field (in a RecordType) argument's type"; +def fir_CharacterType : FIR_Type<"Character", "char"> { + let summary = "FIR character type"; let description = [{ - The type of a field 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 fields within the entity. + Model of the Fortran CHARACTER intrinsic type, including the KIND type + parameter. The model optionally includes a LEN type parameter. A + CharacterType is thus the type of both a single character value and a + character with a LEN parameter. }]; - let printer = [{ - $_printer << "field"; - }]; + let parameters = (ins "KindTy":$FKind, "CharacterType::LenType":$len); - let parser = [{ - return get(context); + let extraClassDeclaration = [{ + using KindTy = unsigned; + using LenType = std::int64_t; + + // Return unknown length CHARACTER type. + static CharacterType getUnknownLen(mlir::MLIRContext *ctxt, KindTy kind) { + return get(ctxt, kind, unknownLen()); + } + + // Return length 1 CHARACTER type. + static CharacterType getSingleton(mlir::MLIRContext *ctxt, KindTy kind) { + return get(ctxt, kind, singleton()); + } + + // CHARACTER is a singleton and has a LEN of 1. + static constexpr LenType singleton() { return 1; } + // CHARACTER has an unknown LEN property. + static constexpr LenType unknownLen() { return -1; } }]; } @@ -109,7 +151,25 @@ }]; } -def ShapeType : FIR_Type<"Shape", "shape"> { +def fir_FieldType : FIR_Type<"Field", "field"> { + let summary = "A field (in a RecordType) argument's type"; + + let description = [{ + The type of a field 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 fields within the entity. + }]; + + let printer = [{ + $_printer << "field"; + }]; + + let parser = [{ + return get(context); + }]; +} + +def fir_ShapeType : FIR_Type<"Shape", "shape"> { let summary = "shape of a multidimensional array object"; let description = [{ @@ -133,7 +193,7 @@ }]; } -def ShapeShiftType : FIR_Type<"ShapeShift", "shapeshift"> { +def fir_ShapeShiftType : FIR_Type<"ShapeShift", "shapeshift"> { let summary = "shape and origin of a multidimensional array object"; let description = [{ @@ -150,74 +210,35 @@ }]; let parser = [{ - if ($_parser.parseLess()) - return Type(); int rank; - if ($_parser.parseInteger(rank)) - return Type(); - if ($_parser.parseGreater()) + if ($_parser.parseLess() || $_parser.parseInteger(rank) || + $_parser.parseGreater()) return Type(); return get(context, rank); }]; } -def fir_CharacterType : FIR_Type<"Character", "char"> { - let summary = "FIR character type"; +def fir_ShiftType : FIR_Type<"Shift", "shift"> { + let summary = "lower bounds of a multidimensional array object"; let description = [{ - Model of the Fortran CHARACTER intrinsic type, including the KIND type - parameter. The model optionally includes a LEN type parameter. A - CharacterType is thus the type of both a single character value and a - character with a LEN parameter. + Type of a vector of runtime values that define the lower bounds of a + multidimensional array object. The vector is the lower bounds of each array + dimension. The rank of a ShiftType must be at least 1. }]; - let parameters = (ins "KindTy":$FKind, "CharacterType::LenType":$len); - - let extraClassDeclaration = [{ - using KindTy = unsigned; - using LenType = std::int64_t; - - // Return unknown length CHARACTER type. - static CharacterType getUnknownLen(mlir::MLIRContext *ctxt, KindTy kind) { - return get(ctxt, kind, unknownLen()); - } - - // Return length 1 CHARACTER type. - static CharacterType getSingleton(mlir::MLIRContext *ctxt, KindTy kind) { - return get(ctxt, kind, singleton()); - } - - // CHARACTER is a singleton and has a LEN of 1. - static constexpr LenType singleton() { return 1; } - // CHARACTER has an unknown LEN property. - static constexpr LenType unknownLen() { return -1; } - }]; -} - -def fir_BoxCharType : FIR_Type<"BoxChar", "boxchar"> { - let summary = "CHARACTER type descriptor."; - - let description = [{ - 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). - }]; - - let parameters = (ins "KindTy":$kind); + let parameters = (ins "unsigned":$rank); let printer = [{ - $_printer << "boxchar<" << getImpl()->kind << ">"; + $_printer << "shift<" << getImpl()->rank << ">"; }]; - let genAccessors = 1; - - let extraClassDeclaration = [{ - using KindTy = unsigned; - - // a !fir.boxchar always wraps a !fir.char - CharacterType getElementType(mlir::MLIRContext *context) const; - - CharacterType getEleTy() const; + let parser = [{ + int rank; + if ($_parser.parseLess() || $_parser.parseInteger(rank) || + $_parser.parseGreater()) + return Type(); + return get(context, rank); }]; }