//===-- ConvertType.cpp ---------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "flang/Lower/ConvertType.h" #include "flang/Lower/PFTBuilder.h" #include "flang/Lower/Utils.h" #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Semantics/tools.h" #include "flang/Semantics/type.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinTypes.h" #undef QUOTE #undef TODO #define QUOTE(X) #X #define TODO(S) \ { \ emitError(__FILE__ ":" QUOTE(__LINE__) ": type lowering of " S \ " not implemented"); \ exit(1); \ } template bool isConstant(const Fortran::evaluate::Expr &e) { return Fortran::evaluate::IsConstantExpr(Fortran::lower::SomeExpr{e}); } template int64_t toConstant(const Fortran::evaluate::Expr &e) { auto opt = Fortran::evaluate::ToInt64(e); assert(opt.has_value() && "expression didn't resolve to a constant"); return opt.value(); } // one argument template, must be specialized template mlir::Type genFIRType(mlir::MLIRContext *, int) { return {}; } // two argument template template mlir::Type genFIRType(mlir::MLIRContext *context) { if constexpr (TC == Fortran::common::TypeCategory::Integer) { auto bits{Fortran::evaluate::Type::Scalar::bits}; return mlir::IntegerType::get(context, bits); } else if constexpr (TC == Fortran::common::TypeCategory::Logical || TC == Fortran::common::TypeCategory::Character || TC == Fortran::common::TypeCategory::Complex) { return genFIRType(context, KIND); } else { return {}; } } template <> mlir::Type genFIRType(mlir::MLIRContext *context) { return mlir::FloatType::getF16(context); } template <> mlir::Type genFIRType(mlir::MLIRContext *context) { return mlir::FloatType::getBF16(context); } template <> mlir::Type genFIRType(mlir::MLIRContext *context) { return mlir::FloatType::getF32(context); } template <> mlir::Type genFIRType(mlir::MLIRContext *context) { return mlir::FloatType::getF64(context); } template <> mlir::Type genFIRType( mlir::MLIRContext *context) { return fir::RealType::get(context, 10); } template <> mlir::Type genFIRType( mlir::MLIRContext *context) { return fir::RealType::get(context, 16); } template <> mlir::Type genFIRType(mlir::MLIRContext *context, int kind) { if (Fortran::evaluate::IsValidKindOfIntrinsicType( Fortran::common::TypeCategory::Real, kind)) { switch (kind) { case 2: return genFIRType(context); case 3: return genFIRType(context); case 4: return genFIRType(context); case 8: return genFIRType(context); case 10: return genFIRType(context); case 16: return genFIRType(context); } } llvm_unreachable("REAL type translation not implemented"); } template <> mlir::Type genFIRType(mlir::MLIRContext *context, int kind) { if (Fortran::evaluate::IsValidKindOfIntrinsicType( Fortran::common::TypeCategory::Integer, kind)) { switch (kind) { case 1: return genFIRType(context); case 2: return genFIRType(context); case 4: return genFIRType(context); case 8: return genFIRType(context); case 16: return genFIRType(context); } } llvm_unreachable("INTEGER type translation not implemented"); } template <> mlir::Type genFIRType(mlir::MLIRContext *context, int KIND) { if (Fortran::evaluate::IsValidKindOfIntrinsicType( Fortran::common::TypeCategory::Logical, KIND)) return fir::LogicalType::get(context, KIND); return {}; } template <> mlir::Type genFIRType(mlir::MLIRContext *context, int KIND) { if (Fortran::evaluate::IsValidKindOfIntrinsicType( Fortran::common::TypeCategory::Character, KIND)) return fir::CharacterType::get(context, KIND, 1); return {}; } template <> mlir::Type genFIRType(mlir::MLIRContext *context, int KIND) { if (Fortran::evaluate::IsValidKindOfIntrinsicType( Fortran::common::TypeCategory::Complex, KIND)) return fir::ComplexType::get(context, KIND); return {}; } namespace { /// Discover the type of an Fortran::evaluate::Expr and convert it to an /// mlir::Type. The type returned may be an MLIR standard or FIR type. class TypeBuilder { public: /// Constructor. explicit TypeBuilder( mlir::MLIRContext *context, const Fortran::common::IntrinsicTypeDefaultKinds &defaults) : context{context}, defaults{defaults} {} //===--------------------------------------------------------------------===// // Generate type entry points //===--------------------------------------------------------------------===// template