Skip to content

Commit

Permalink
[flang] Add getTypeAsString function to create symbols
Browse files Browse the repository at this point in the history
This patch adds a common function to get a string representation
of a FIR type. This will be useful to generate couple of
operations like the acc.private.recipe, acc.firstprivate.recipe
and the acc.reduction.recipe

Reviewed By: razvanlupusoru

Differential Revision: https://reviews.llvm.org/D150973
  • Loading branch information
clementval committed May 22, 2023
1 parent f7d92d4 commit a7bbbc5
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 4 deletions.
10 changes: 9 additions & 1 deletion flang/include/flang/Optimizer/Dialect/FIRType.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ bool hasAbstractResult(mlir::FunctionType ty);
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<fir::BoxType, fir::ClassType>();
Expand Down Expand Up @@ -413,6 +413,14 @@ inline bool isBoxAddressOrValue(mlir::Type t) {
return fir::unwrapRefType(t).isa<fir::BaseBoxType>();
}

/// Return a string representation of `ty`. The fir.ref is omitted in the
/// representation.
///
/// fir.array<10x10xf32> -> prefix_10x10xf32
/// fir.ref<i32> -> i32
std::string getTypeAsString(mlir::Type ty, const KindMapping &kindMap,
llvm::StringRef prefix = "");

} // namespace fir

#endif // FORTRAN_OPTIMIZER_DIALECT_FIRTYPE_H
46 changes: 45 additions & 1 deletion flang/lib/Optimizer/Dialect/FIRType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ mlir::Type unwrapSeqOrBoxedSeqType(mlir::Type ty) {
}

/// 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<mlir::IntegerType>()) {
switch (intTy.getWidth()) {
Expand Down Expand Up @@ -473,6 +473,50 @@ int getTypeCode(mlir::Type ty, fir::KindMapping &kindMap) {
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<mlir::FloatType>()) {
name << 'f' << ty.getIntOrFloatBitWidth();
} else if (fir::isa_complex(ty)) {
name << 'z';
if (auto cplxTy = mlir::dyn_cast_or_null<mlir::ComplexType>(ty)) {
auto floatTy = cplxTy.getElementType().cast<mlir::FloatType>();
name << floatTy.getWidth();
} else if (auto cplxTy = mlir::dyn_cast_or_null<fir::ComplexType>(ty)) {
name << kindMap.getRealBitsize(cplxTy.getFKind());
}
} else if (auto logTy = mlir::dyn_cast_or_null<fir::LogicalType>(ty)) {
name << 'l' << kindMap.getLogicalBitsize(logTy.getFKind());
} else {
llvm::report_fatal_error("unsupported type");
}
break;
} else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(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<fir::SequenceType>(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 {
Expand Down
29 changes: 27 additions & 2 deletions flang/unittests/Optimizer/FIRTypesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -253,3 +259,22 @@ TEST_F(FIRTypesTest, updateTypeForUnlimitedPolymorphic) {
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));
}

0 comments on commit a7bbbc5

Please sign in to comment.