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 @@ -16,6 +16,13 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/BuiltinTypes.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Type.h" + +namespace fir { +class FIROpsDialect; +class KindMapping; +using KindTy = unsigned; +} // namespace fir #define GET_TYPEDEF_CLASSES #include "flang/Optimizer/Dialect/FIROpsTypes.h.inc" @@ -37,11 +44,6 @@ } // namespace mlir namespace fir { - -class FIROpsDialect; - -using KindTy = unsigned; - namespace detail { struct RecordTypeStorage; } // namespace detail @@ -257,6 +259,14 @@ /// Returns null on error. mlir::Type applyPathToType(mlir::Type rootTy, mlir::ValueRange path); +/// Does this function type has a result that require binding the result value +/// with a storage in a fir.save_result operation in order to use the result? +bool hasAbstractResult(mlir::FunctionType ty); + +/// Convert llvm::Type::TypeID to mlir::Type +mlir::Type fromRealTypeID(mlir::MLIRContext *context, llvm::Type::TypeID typeID, + fir::KindTy kind); + } // namespace fir #endif // FORTRAN_OPTIMIZER_DIALECT_FIRTYPE_H 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 @@ -153,6 +153,7 @@ using KindTy = unsigned; mlir::Type getElementType() const; + mlir::Type getEleType(const fir::KindMapping &kindMap) const; }]; } diff --git a/flang/lib/Optimizer/CodeGen/TypeConverter.h b/flang/lib/Optimizer/CodeGen/TypeConverter.h --- a/flang/lib/Optimizer/CodeGen/TypeConverter.h +++ b/flang/lib/Optimizer/CodeGen/TypeConverter.h @@ -338,7 +338,8 @@ // convert a front-end kind value to either a std or LLVM IR dialect type // fir.real --> llvm.anyfloat where anyfloat is a kind mapping mlir::Type convertRealType(fir::KindTy kind) { - return fromRealTypeID(kindMapping.getRealTypeID(kind), kind); + return fir::fromRealTypeID(&getContext(), kindMapping.getRealTypeID(kind), + kind); } // fir.array --> llvm<"[...[c x any]]"> @@ -369,28 +370,6 @@ mlir::IntegerType::get(&getContext(), 8)); } - /// Convert llvm::Type::TypeID to mlir::Type - mlir::Type fromRealTypeID(llvm::Type::TypeID typeID, fir::KindTy kind) { - switch (typeID) { - case llvm::Type::TypeID::HalfTyID: - return mlir::FloatType::getF16(&getContext()); - case llvm::Type::TypeID::BFloatTyID: - return mlir::FloatType::getBF16(&getContext()); - case llvm::Type::TypeID::FloatTyID: - return mlir::FloatType::getF32(&getContext()); - case llvm::Type::TypeID::DoubleTyID: - return mlir::FloatType::getF64(&getContext()); - case llvm::Type::TypeID::X86_FP80TyID: - return mlir::FloatType::getF80(&getContext()); - case llvm::Type::TypeID::FP128TyID: - return mlir::FloatType::getF128(&getContext()); - default: - mlir::emitError(mlir::UnknownLoc::get(&getContext())) - << "unsupported type: !fir.real<" << kind << ">"; - return {}; - } - } - KindMapping &getKindMap() { return kindMapping; } private: diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -14,6 +14,8 @@ #include "flang/Optimizer/Dialect/FIRAttr.h" #include "flang/Optimizer/Dialect/FIROpsSupport.h" #include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Optimizer/Support/FIRContext.h" +#include "flang/Optimizer/Support/KindMapping.h" #include "flang/Optimizer/Support/Utils.h" #include "mlir/Dialect/CommonFolders.h" #include "mlir/Dialect/Func/IR/FuncOps.h" @@ -3437,8 +3439,11 @@ return mlir::Type{}; }) .Case([&](fir::ComplexType ty) { - if (fir::isa_integer((*i++).getType())) - return ty.getElementType(); + auto x = *i; + if (auto *op = (*i++).getDefiningOp()) + if (fir::isa_integer(x.getType())) + return ty.getEleType(fir::getKindMapping( + op->getParentOfType())); return mlir::Type{}; }) .Case([&](mlir::ComplexType ty) { 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 @@ -12,6 +12,7 @@ #include "flang/Optimizer/Dialect/FIRType.h" #include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Support/KindMapping.h" #include "flang/Tools/PointerModels.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinDialect.h" @@ -483,6 +484,13 @@ return fir::RealType::get(getContext(), getFKind()); } +// Return the MLIR float type of the complex element type. +mlir::Type fir::ComplexType::getEleType(const fir::KindMapping &kindMap) const { + auto fkind = getFKind(); + auto realTypeID = kindMap.getRealTypeID(fkind); + return fir::fromRealTypeID(getContext(), realTypeID, fkind); +} + //===----------------------------------------------------------------------===// // HeapType //===----------------------------------------------------------------------===// @@ -925,6 +933,37 @@ fir::isa_integer(tuple.getType(1)); } +bool fir::hasAbstractResult(mlir::FunctionType ty) { + if (ty.getNumResults() == 0) + return false; + auto resultType = ty.getResult(0); + return resultType.isa(); +} + +/// Convert llvm::Type::TypeID to mlir::Type. \p kind is provided for error +/// messages only. +mlir::Type fir::fromRealTypeID(mlir::MLIRContext *context, + llvm::Type::TypeID typeID, fir::KindTy kind) { + switch (typeID) { + case llvm::Type::TypeID::HalfTyID: + return mlir::FloatType::getF16(context); + case llvm::Type::TypeID::BFloatTyID: + return mlir::FloatType::getBF16(context); + case llvm::Type::TypeID::FloatTyID: + return mlir::FloatType::getF32(context); + case llvm::Type::TypeID::DoubleTyID: + return mlir::FloatType::getF64(context); + case llvm::Type::TypeID::X86_FP80TyID: + return mlir::FloatType::getF80(context); + case llvm::Type::TypeID::FP128TyID: + return mlir::FloatType::getF128(context); + default: + mlir::emitError(mlir::UnknownLoc::get(context)) + << "unsupported type: !fir.real<" << kind << ">"; + return {}; + } +} + //===----------------------------------------------------------------------===// // FIROpsDialect //===----------------------------------------------------------------------===//