diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td index 1d66507a23545..cc6b92f5171e2 100644 --- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td +++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td @@ -15,6 +15,7 @@ include "mlir/IR/AttrTypeBase.td" include "mlir/IR/BuiltinTypeInterfaces.td" +include "mlir/IR/OpAsmInterface.td" include "flang/Optimizer/Dialect/FIRDialect.td" //===----------------------------------------------------------------------===// @@ -316,7 +317,9 @@ def fir_PointerType : FIR_Type<"Pointer", "ptr"> { }]; } -def fir_RecordType : FIR_Type<"Record", "type", [MemRefElementTypeInterface]> { +def fir_RecordType : FIR_Type<"Record", "type", + [DeclareTypeInterfaceMethods, + MemRefElementTypeInterface]> { let summary = "FIR derived type"; let description = [{ diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp index 6eaecc69fe742..178860239e17d 100644 --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringSet.h" #include "llvm/ADT/TypeSwitch.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" #define GET_TYPEDEF_CLASSES @@ -31,6 +32,11 @@ using namespace fir; +static llvm::cl::opt enableFirTypeAliases( + "enable-fir-type-aliases", + llvm::cl::desc("Enable MLIR type aliases for FIR derived types"), + llvm::cl::init(false), llvm::cl::Hidden); + namespace { template @@ -1122,7 +1128,7 @@ void fir::RecordType::print(mlir::AsmPrinter &printer) const { char ch = '('; for (auto p : getLenParamList()) { printer << ch << p.first << ':'; - p.second.print(printer.getStream()); + printer.printType(p.second); ch = ','; } printer << ')'; @@ -1134,7 +1140,7 @@ void fir::RecordType::print(mlir::AsmPrinter &printer) const { char ch = '{'; for (auto p : getTypeList()) { printer << ch << p.first << ':'; - p.second.print(printer.getStream()); + printer.printType(p.second); ch = ','; } printer << '}'; @@ -1147,6 +1153,18 @@ void fir::RecordType::print(mlir::AsmPrinter &printer) const { printer << '>'; } +mlir::OpAsmAliasResult fir::RecordType::getAlias(llvm::raw_ostream &os) const { + if (!enableFirTypeAliases) + return mlir::OpAsmAliasResult::NoAlias; + // Derived type names may contain "." that are forbidden in MLIR type + // alias. Replace them by a capital 'X' that cannot be found in user + // defined derived type and is also used as a replacement before generating + // llvm assembly. + for (char ch : getName()) + os << (ch == '.' ? 'X' : ch); + return mlir::OpAsmAliasResult::OverridableAlias; +} + void fir::RecordType::finalize(llvm::ArrayRef lenPList, llvm::ArrayRef typeList) { getImpl()->finalize(lenPList, typeList); diff --git a/flang/test/Fir/derived-type-aliases.fir b/flang/test/Fir/derived-type-aliases.fir new file mode 100644 index 0000000000000..b2495213e4c56 --- /dev/null +++ b/flang/test/Fir/derived-type-aliases.fir @@ -0,0 +1,24 @@ +// RUN: fir-opt %s | FileCheck %s --check-prefix=DEFAULT +// RUN: fir-opt -enable-fir-type-aliases %s | FileCheck %s --check-prefix=ALIASES + +module { + func.func @use_aliases( + %arg0: !fir.ref>}>}>>, + %arg1: !fir.ref>, + %arg2: !fir.ref>, + %arg3: !fir.ref>>}>>) { + return + } +} + +// DEFAULT-NOT: !outer = +// DEFAULT-NOT: !aXb = +// DEFAULT-NOT: !a_b = +// DEFAULT: func.func @use_aliases(%{{.*}}: !fir.ref>}>}>>, %{{.*}}: !fir.ref>, %{{.*}}: !fir.ref>, %{{.*}}: !fir.ref>>}>>) + +// ALIASES-DAG: !aXb = !fir.type +// ALIASES-DAG: !a_b = !fir.type +// ALIASES-DAG: !inner = !fir.type>}> +// ALIASES-DAG: !outer = !fir.type +// ALIASES-DAG: !recursive = !fir.type>>}> +// ALIASES: func.func @use_aliases(%{{.*}}: !fir.ref, %{{.*}}: !fir.ref, %{{.*}}: !fir.ref, %{{.*}}: !fir.ref)