forked from OSchip/llvm-project
[flang][fir][NFC] Move CharacterType and BoxCharType to TableGen type definition
This patch is a follow up of D96422 and move CharacterType and BoxCharType to TableGen. Reviewed By: schweitz Differential Revision: https://reviews.llvm.org/D96446
This commit is contained in:
parent
cdcb60a820
commit
209bc67b78
|
@ -33,8 +33,6 @@ def fir_Type : Type<CPred<"fir::isa_fir_or_std_type($_self)">,
|
|||
"FIR dialect type">;
|
||||
|
||||
// Fortran intrinsic types
|
||||
def fir_CharacterType : Type<CPred<"$_self.isa<fir::CharacterType>()">,
|
||||
"FIR character type">;
|
||||
def fir_ComplexType : Type<CPred<"$_self.isa<fir::ComplexType>()">,
|
||||
"FIR complex type">;
|
||||
def fir_IntegerType : Type<CPred<"$_self.isa<fir::IntegerType>()">,
|
||||
|
@ -84,10 +82,6 @@ def fir_PointerType : Type<CPred<"$_self.isa<fir::PointerType>()">,
|
|||
def AnyReferenceLike : TypeConstraint<Or<[fir_ReferenceType.predicate,
|
||||
fir_HeapType.predicate, fir_PointerType.predicate]>, "any reference">;
|
||||
|
||||
// CHARACTER type descriptor. A pair of a data reference and a LEN value.
|
||||
def fir_BoxCharType : Type<CPred<"$_self.isa<fir::BoxCharType>()">,
|
||||
"box character type">;
|
||||
|
||||
// PROCEDURE POINTER descriptor. A pair that can capture a host closure.
|
||||
def fir_BoxProcType : Type<CPred<"$_self.isa<fir::BoxProcType>()">,
|
||||
"box procedure type">;
|
||||
|
|
|
@ -42,9 +42,7 @@ class FIROpsDialect;
|
|||
using KindTy = unsigned;
|
||||
|
||||
namespace detail {
|
||||
struct BoxCharTypeStorage;
|
||||
struct BoxProcTypeStorage;
|
||||
struct CharacterTypeStorage;
|
||||
struct ComplexTypeStorage;
|
||||
struct HeapTypeStorage;
|
||||
struct IntegerTypeStorage;
|
||||
|
@ -98,37 +96,6 @@ mlir::Type dyn_cast_ptrEleTy(mlir::Type t);
|
|||
|
||||
// Intrinsic types
|
||||
|
||||
/// 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.
|
||||
class CharacterType
|
||||
: public mlir::Type::TypeBase<CharacterType, mlir::Type,
|
||||
detail::CharacterTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
using LenType = std::int64_t;
|
||||
|
||||
static CharacterType get(mlir::MLIRContext *ctxt, KindTy kind, LenType len);
|
||||
/// 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());
|
||||
}
|
||||
KindTy getFKind() const;
|
||||
|
||||
/// 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; }
|
||||
|
||||
/// Access to a CHARACTER's LEN property. Defaults to 1.
|
||||
LenType getLen() const;
|
||||
};
|
||||
|
||||
/// Model of a Fortran COMPLEX intrinsic type, including the KIND type
|
||||
/// parameter. COMPLEX is a floating point type with a real and imaginary
|
||||
/// member.
|
||||
|
@ -176,17 +143,6 @@ public:
|
|||
|
||||
// FIR support types
|
||||
|
||||
/// 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).
|
||||
class BoxCharType : public mlir::Type::TypeBase<BoxCharType, mlir::Type,
|
||||
detail::BoxCharTypeStorage> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static BoxCharType get(mlir::MLIRContext *ctxt, KindTy kind);
|
||||
CharacterType getEleTy() const;
|
||||
};
|
||||
|
||||
/// The type of a pair that describes a PROCEDURE reference. Pointers to
|
||||
/// internal procedures must carry an additional reference to the host's
|
||||
/// variables that are referenced.
|
||||
|
|
|
@ -115,4 +115,64 @@ def ShapeShiftType : FIR_Type<"ShapeShift", "shapeshift"> {
|
|||
}];
|
||||
}
|
||||
|
||||
def fir_CharacterType : FIR_Type<"Character", "char"> {
|
||||
let summary = "FIR character type";
|
||||
|
||||
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.
|
||||
}];
|
||||
|
||||
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 printer = [{
|
||||
$_printer << "boxchar<" << getImpl()->kind << ">";
|
||||
}];
|
||||
|
||||
let genAccessors = 1;
|
||||
|
||||
let extraClassDeclaration = [{
|
||||
using KindTy = unsigned;
|
||||
|
||||
// a !fir.boxchar<k> always wraps a !fir.char<k, ?>
|
||||
CharacterType getElementType(mlir::MLIRContext *context) const;
|
||||
|
||||
CharacterType getEleTy() const;
|
||||
}];
|
||||
}
|
||||
|
||||
#endif // FIR_DIALECT_FIR_TYPES
|
||||
|
|
|
@ -58,37 +58,11 @@ TYPE parseTypeSingleton(mlir::DialectAsmParser &parser, mlir::Location) {
|
|||
return TYPE::get(ty);
|
||||
}
|
||||
|
||||
// `boxchar` `<` kind `>`
|
||||
BoxCharType parseBoxChar(mlir::DialectAsmParser &parser) {
|
||||
return parseKindSingleton<BoxCharType>(parser);
|
||||
}
|
||||
|
||||
// `boxproc` `<` return-type `>`
|
||||
BoxProcType parseBoxProc(mlir::DialectAsmParser &parser, mlir::Location loc) {
|
||||
return parseTypeSingleton<BoxProcType>(parser, loc);
|
||||
}
|
||||
|
||||
// `char` `<` kind [`,` `len`] `>`
|
||||
CharacterType parseCharacter(mlir::DialectAsmParser &parser) {
|
||||
int kind = 0;
|
||||
if (parser.parseLess() || parser.parseInteger(kind)) {
|
||||
parser.emitError(parser.getCurrentLocation(), "kind value expected");
|
||||
return {};
|
||||
}
|
||||
CharacterType::LenType len = 1;
|
||||
if (mlir::succeeded(parser.parseOptionalComma())) {
|
||||
if (mlir::succeeded(parser.parseOptionalQuestion())) {
|
||||
len = fir::CharacterType::unknownLen();
|
||||
} else if (!mlir::succeeded(parser.parseInteger(len))) {
|
||||
parser.emitError(parser.getCurrentLocation(), "len value expected");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
if (parser.parseGreater())
|
||||
return {};
|
||||
return CharacterType::get(parser.getBuilder().getContext(), kind, len);
|
||||
}
|
||||
|
||||
// `complex` `<` kind `>`
|
||||
fir::ComplexType parseComplex(mlir::DialectAsmParser &parser) {
|
||||
return parseKindSingleton<fir::ComplexType>(parser);
|
||||
|
@ -325,17 +299,20 @@ mlir::Type fir::parseFirType(FIROpsDialect *dialect,
|
|||
if (mlir::failed(parser.parseKeyword(&typeNameLit)))
|
||||
return {};
|
||||
|
||||
// TODO all TYPE::parse can be move to generatedTypeParser when all types
|
||||
// have been moved
|
||||
|
||||
auto loc = parser.getEncodedSourceLoc(parser.getNameLoc());
|
||||
if (typeNameLit == "array")
|
||||
return parseSequence(parser, loc);
|
||||
if (typeNameLit == "box")
|
||||
return generatedTypeParser(dialect->getContext(), parser, typeNameLit);
|
||||
if (typeNameLit == "boxchar")
|
||||
return parseBoxChar(parser);
|
||||
return generatedTypeParser(dialect->getContext(), parser, typeNameLit);
|
||||
if (typeNameLit == "boxproc")
|
||||
return parseBoxProc(parser, loc);
|
||||
if (typeNameLit == "char")
|
||||
return parseCharacter(parser);
|
||||
return generatedTypeParser(dialect->getContext(), parser, typeNameLit);
|
||||
if (typeNameLit == "complex")
|
||||
return parseComplex(parser);
|
||||
if (typeNameLit == "field")
|
||||
|
@ -378,39 +355,6 @@ namespace detail {
|
|||
|
||||
// Type storage classes
|
||||
|
||||
/// `CHARACTER` storage
|
||||
struct CharacterTypeStorage : public mlir::TypeStorage {
|
||||
using KeyTy = std::tuple<KindTy, CharacterType::LenType>;
|
||||
|
||||
static unsigned hashKey(const KeyTy &key) {
|
||||
auto hashVal = llvm::hash_combine(std::get<0>(key));
|
||||
return llvm::hash_combine(hashVal, llvm::hash_combine(std::get<1>(key)));
|
||||
}
|
||||
|
||||
bool operator==(const KeyTy &key) const {
|
||||
return key == KeyTy{getFKind(), getLen()};
|
||||
}
|
||||
|
||||
static CharacterTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
|
||||
const KeyTy &key) {
|
||||
auto *storage = allocator.allocate<CharacterTypeStorage>();
|
||||
return new (storage)
|
||||
CharacterTypeStorage{std::get<0>(key), std::get<1>(key)};
|
||||
}
|
||||
|
||||
KindTy getFKind() const { return kind; }
|
||||
CharacterType::LenType getLen() const { return len; }
|
||||
|
||||
protected:
|
||||
KindTy kind;
|
||||
CharacterType::LenType len;
|
||||
|
||||
private:
|
||||
CharacterTypeStorage() = delete;
|
||||
explicit CharacterTypeStorage(KindTy kind, CharacterType::LenType len)
|
||||
: kind{kind}, len{len} {}
|
||||
};
|
||||
|
||||
struct SliceTypeStorage : public mlir::TypeStorage {
|
||||
using KeyTy = unsigned;
|
||||
|
||||
|
@ -549,35 +493,6 @@ private:
|
|||
explicit RealTypeStorage(KindTy kind) : kind{kind} {}
|
||||
};
|
||||
|
||||
/// Boxed CHARACTER object type
|
||||
struct BoxCharTypeStorage : public mlir::TypeStorage {
|
||||
using KeyTy = KindTy;
|
||||
|
||||
static unsigned hashKey(const KeyTy &key) { return llvm::hash_combine(key); }
|
||||
|
||||
bool operator==(const KeyTy &key) const { return key == getFKind(); }
|
||||
|
||||
static BoxCharTypeStorage *construct(mlir::TypeStorageAllocator &allocator,
|
||||
KindTy kind) {
|
||||
auto *storage = allocator.allocate<BoxCharTypeStorage>();
|
||||
return new (storage) BoxCharTypeStorage{kind};
|
||||
}
|
||||
|
||||
KindTy getFKind() const { return kind; }
|
||||
|
||||
// a !fir.boxchar<k> always wraps a !fir.char<k, ?>
|
||||
CharacterType getElementType(mlir::MLIRContext *ctxt) const {
|
||||
return CharacterType::getUnknownLen(ctxt, getFKind());
|
||||
}
|
||||
|
||||
protected:
|
||||
KindTy kind;
|
||||
|
||||
private:
|
||||
BoxCharTypeStorage() = delete;
|
||||
explicit BoxCharTypeStorage(KindTy kind) : kind{kind} {}
|
||||
};
|
||||
|
||||
/// Boxed PROCEDURE POINTER object type
|
||||
struct BoxProcTypeStorage : public mlir::TypeStorage {
|
||||
using KeyTy = mlir::Type;
|
||||
|
@ -872,19 +787,6 @@ mlir::Type dyn_cast_ptrEleTy(mlir::Type t) {
|
|||
|
||||
} // namespace fir
|
||||
|
||||
// CHARACTER
|
||||
|
||||
CharacterType fir::CharacterType::get(mlir::MLIRContext *ctxt, KindTy kind,
|
||||
CharacterType::LenType len) {
|
||||
return Base::get(ctxt, kind, len);
|
||||
}
|
||||
|
||||
KindTy fir::CharacterType::getFKind() const { return getImpl()->getFKind(); }
|
||||
|
||||
CharacterType::LenType fir::CharacterType::getLen() const {
|
||||
return getImpl()->getLen();
|
||||
}
|
||||
|
||||
// Len
|
||||
|
||||
LenType fir::LenType::get(mlir::MLIRContext *ctxt) {
|
||||
|
@ -934,16 +836,6 @@ fir::BoxType::verifyConstructionInvariants(mlir::Location, mlir::Type eleTy,
|
|||
return mlir::success();
|
||||
}
|
||||
|
||||
// BoxChar<C>
|
||||
|
||||
BoxCharType fir::BoxCharType::get(mlir::MLIRContext *ctxt, KindTy kind) {
|
||||
return Base::get(ctxt, kind);
|
||||
}
|
||||
|
||||
CharacterType fir::BoxCharType::getEleTy() const {
|
||||
return getImpl()->getElementType(getContext());
|
||||
}
|
||||
|
||||
// BoxProc<T>
|
||||
|
||||
BoxProcType fir::BoxProcType::get(mlir::Type elementType) {
|
||||
|
@ -1240,31 +1132,12 @@ 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<BoxCharType>()) {
|
||||
os << "boxchar<" << type.getEleTy().cast<fir::CharacterType>().getFKind()
|
||||
<< '>';
|
||||
return;
|
||||
}
|
||||
if (auto type = ty.dyn_cast<BoxProcType>()) {
|
||||
os << "boxproc<";
|
||||
p.printType(type.getEleTy());
|
||||
os << '>';
|
||||
return;
|
||||
}
|
||||
if (auto chTy = ty.dyn_cast<CharacterType>()) {
|
||||
// Fortran intrinsic type CHARACTER
|
||||
os << "char<" << chTy.getFKind();
|
||||
auto len = chTy.getLen();
|
||||
if (len != fir::CharacterType::singleton()) {
|
||||
os << ',';
|
||||
if (len == fir::CharacterType::unknownLen())
|
||||
os << '?';
|
||||
else
|
||||
os << len;
|
||||
}
|
||||
os << '>';
|
||||
return;
|
||||
}
|
||||
if (auto type = ty.dyn_cast<fir::ComplexType>()) {
|
||||
// Fortran intrinsic type COMPLEX
|
||||
os << "complex<" << type.getFKind() << '>';
|
||||
|
@ -1387,14 +1260,12 @@ 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::Type fir::BoxType::parse(mlir::MLIRContext *context,
|
||||
mlir::DialectAsmParser &parser) {
|
||||
mlir::Type ofTy;
|
||||
if (parser.parseLess() || parser.parseType(ofTy)) {
|
||||
|
@ -1416,7 +1287,7 @@ mlir::Type BoxType::parse(mlir::MLIRContext *context,
|
|||
return get(ofTy, map);
|
||||
}
|
||||
|
||||
void BoxType::print(::mlir::DialectAsmPrinter &printer) const {
|
||||
void fir::BoxType::print(::mlir::DialectAsmPrinter &printer) const {
|
||||
printer << "box<";
|
||||
printer.printType(getEleTy());
|
||||
if (auto map = getLayoutMap()) {
|
||||
|
@ -1426,4 +1297,65 @@ void BoxType::print(::mlir::DialectAsmPrinter &printer) const {
|
|||
printer << '>';
|
||||
}
|
||||
|
||||
} // namespace fir
|
||||
//===----------------------------------------------------------------------===//
|
||||
// BoxCharType
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
mlir::Type fir::BoxCharType::parse(mlir::MLIRContext *context,
|
||||
mlir::DialectAsmParser &parser) {
|
||||
int kind = 0;
|
||||
if (parser.parseLess() || parser.parseInteger(kind) ||
|
||||
parser.parseGreater()) {
|
||||
parser.emitError(parser.getCurrentLocation(), "kind value expected");
|
||||
return Type();
|
||||
}
|
||||
return get(context, kind);
|
||||
}
|
||||
|
||||
CharacterType
|
||||
fir::BoxCharType::getElementType(mlir::MLIRContext *context) const {
|
||||
return CharacterType::getUnknownLen(context, getKind());
|
||||
}
|
||||
|
||||
CharacterType fir::BoxCharType::getEleTy() const {
|
||||
return getElementType(getContext());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CharacterType
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// `char` `<` kind [`,` `len`] `>`
|
||||
mlir::Type fir::CharacterType::parse(mlir::MLIRContext *context,
|
||||
mlir::DialectAsmParser &parser) {
|
||||
int kind = 0;
|
||||
if (parser.parseLess() || parser.parseInteger(kind)) {
|
||||
parser.emitError(parser.getCurrentLocation(), "kind value expected");
|
||||
return Type();
|
||||
}
|
||||
CharacterType::LenType len = 1;
|
||||
if (mlir::succeeded(parser.parseOptionalComma())) {
|
||||
if (mlir::succeeded(parser.parseOptionalQuestion())) {
|
||||
len = fir::CharacterType::unknownLen();
|
||||
} else if (!mlir::succeeded(parser.parseInteger(len))) {
|
||||
parser.emitError(parser.getCurrentLocation(), "len value expected");
|
||||
return Type();
|
||||
}
|
||||
}
|
||||
if (parser.parseGreater())
|
||||
return Type();
|
||||
return get(context, kind, len);
|
||||
}
|
||||
|
||||
void fir::CharacterType::print(::mlir::DialectAsmPrinter &printer) const {
|
||||
printer << "char<" << getFKind();
|
||||
auto len = getLen();
|
||||
if (len != fir::CharacterType::singleton()) {
|
||||
printer << ',';
|
||||
if (len == fir::CharacterType::unknownLen())
|
||||
printer << '?';
|
||||
else
|
||||
printer << len;
|
||||
}
|
||||
printer << '>';
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue