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 @@ -359,7 +359,7 @@ mlir::Type fromRealTypeID(mlir::MLIRContext *context, llvm::Type::TypeID typeID, fir::KindTy kind); -int getTypeCode(mlir::Type ty, KindMapping &kindMap); +int getTypeCode(mlir::Type ty, const KindMapping &kindMap); inline bool BaseBoxType::classof(mlir::Type type) { return type.isa(); @@ -413,6 +413,14 @@ return fir::unwrapRefType(t).isa(); } +/// Return a string representation of `ty`. The fir.ref is omitted in the +/// representation. +/// +/// fir.array<10x10xf32> -> prefix_10x10xf32 +/// fir.ref -> i32 +std::string getTypeAsString(mlir::Type ty, const KindMapping &kindMap, + llvm::StringRef prefix = ""); + } // namespace fir #endif // FORTRAN_OPTIMIZER_DIALECT_FIRTYPE_H 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 @@ -383,7 +383,7 @@ } /// Return the ISO_C_BINDING intrinsic module value of type \p ty. -int getTypeCode(mlir::Type ty, fir::KindMapping &kindMap) { +int getTypeCode(mlir::Type ty, const fir::KindMapping &kindMap) { unsigned width = 0; if (mlir::IntegerType intTy = ty.dyn_cast()) { switch (intTy.getWidth()) { @@ -473,6 +473,50 @@ llvm_unreachable("unsupported type"); } +std::string getTypeAsString(mlir::Type ty, const fir::KindMapping &kindMap, + llvm::StringRef prefix) { + std::stringstream name; + name << prefix.str(); + if (!prefix.empty()) + name << "_"; + ty = fir::unwrapRefType(ty); + while (ty) { + if (fir::isa_trivial(ty)) { + if (ty.isIntOrIndex()) { + name << 'i' << ty.getIntOrFloatBitWidth(); + } else if (ty.isa()) { + name << 'f' << ty.getIntOrFloatBitWidth(); + } else if (fir::isa_complex(ty)) { + name << 'z'; + if (auto cplxTy = mlir::dyn_cast_or_null(ty)) { + auto floatTy = cplxTy.getElementType().cast(); + name << floatTy.getWidth(); + } else if (auto cplxTy = mlir::dyn_cast_or_null(ty)) { + name << kindMap.getRealBitsize(cplxTy.getFKind()); + } + } else if (auto logTy = mlir::dyn_cast_or_null(ty)) { + name << 'l' << kindMap.getLogicalBitsize(logTy.getFKind()); + } else { + llvm::report_fatal_error("unsupported type"); + } + break; + } else if (auto charTy = mlir::dyn_cast_or_null(ty)) { + name << 'c' << kindMap.getCharacterBitsize(charTy.getFKind()); + if (charTy.getLen() != fir::CharacterType::singleton()) + name << "x" << charTy.getLen(); + break; + } else if (auto seqTy = mlir::dyn_cast_or_null(ty)) { + for (auto extent : seqTy.getShape()) + name << extent << 'x'; + ty = seqTy.getEleTy(); + } else { + // TODO: add support for RecordType/BaseBoxType + llvm::report_fatal_error("unsupported type"); + } + } + return name.str(); +} + } // namespace fir namespace { diff --git a/flang/unittests/Optimizer/FIRTypesTest.cpp b/flang/unittests/Optimizer/FIRTypesTest.cpp --- a/flang/unittests/Optimizer/FIRTypesTest.cpp +++ b/flang/unittests/Optimizer/FIRTypesTest.cpp @@ -8,13 +8,19 @@ #include "gtest/gtest.h" #include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Optimizer/Dialect/Support/KindMapping.h" #include "flang/Optimizer/Support/InitFIR.h" struct FIRTypesTest : public testing::Test { public: - void SetUp() { fir::support::loadDialects(context); } - + void SetUp() { + fir::support::loadDialects(context); + kindMap = new fir::KindMapping(&context, kindMapInit, "r42a10c14d28i40l41"); + } mlir::MLIRContext context; + fir::KindMapping *kindMap{}; + std::string kindMapInit = + "i10:80,l3:24,a1:8,r54:Double,r62:X86_FP80,r11:PPC_FP128"; }; // Test fir::isPolymorphicType from flang/Optimizer/Dialect/FIRType.h. @@ -253,3 +259,22 @@ EXPECT_EQ(ptrArrNone, fir::updateTypeForUnlimitedPolymorphic(ptrArrTy)); } } + +TEST_F(FIRTypesTest, getTypeAsString) { + EXPECT_EQ("i32", + fir::getTypeAsString(mlir::IntegerType::get(&context, 32), *kindMap)); + EXPECT_EQ( + "f64", fir::getTypeAsString(mlir::FloatType::getF64(&context), *kindMap)); + EXPECT_EQ( + "l8", fir::getTypeAsString(fir::LogicalType::get(&context, 1), *kindMap)); + EXPECT_EQ("z32", + fir::getTypeAsString( + mlir::ComplexType::get(mlir::FloatType::getF32(&context)), *kindMap)); + EXPECT_EQ("c8", + fir::getTypeAsString(fir::CharacterType::get(&context, 1, 1), *kindMap)); + EXPECT_EQ("c8x10", + fir::getTypeAsString(fir::CharacterType::get(&context, 1, 10), *kindMap)); + mlir::Type ty = mlir::IntegerType::get(&context, 64); + mlir::Type arrTy = fir::SequenceType::get({10, 20}, ty); + EXPECT_EQ("10x20xi64", fir::getTypeAsString(arrTy, *kindMap)); +}