[flang][NFC] add genType(FunctionRef<T>) entry points in lowering
authorJean Perier <jperier@nvidia.com>
Wed, 30 Nov 2022 13:44:10 +0000 (14:44 +0100)
committerJean Perier <jperier@nvidia.com>
Wed, 30 Nov 2022 13:44:27 +0000 (14:44 +0100)
This will help lowering to HLFIR to not use the AsGenericExpr/AsExpr
patterns that copies sub-expresssions into evaluate::SomeExpr so that
they can be passed to helpers. Sub-expressions like FunctionRef can
be heavy (hundreds of arguments, constant array expression arguments...).

Differential Revision: https://reviews.llvm.org/D138997

flang/include/flang/Lower/ConvertType.h
flang/lib/Lower/ConvertType.cpp

index 524f450..ef01d90 100644 (file)
@@ -22,6 +22,7 @@
 #define FORTRAN_LOWER_CONVERT_TYPE_H
 
 #include "flang/Common/Fortran.h"
+#include "flang/Evaluate/type.h"
 #include "mlir/IR/BuiltinTypes.h"
 
 namespace mlir {
@@ -39,6 +40,8 @@ class Reference;
 namespace evaluate {
 template <typename>
 class Expr;
+template <typename>
+class FunctionRef;
 struct SomeType;
 } // namespace evaluate
 
@@ -83,6 +86,15 @@ mlir::Type translateVariableToFIRType(Fortran::lower::AbstractConverter &,
 /// Translate a REAL of KIND to the mlir::Type.
 mlir::Type convertReal(mlir::MLIRContext *ctxt, int KIND);
 
+template <typename T>
+class TypeBuilder {
+public:
+  static mlir::Type genType(Fortran::lower::AbstractConverter &,
+                            const Fortran::evaluate::FunctionRef<T> &);
+};
+using namespace evaluate;
+FOR_EACH_SPECIFIC_TYPE(extern template class TypeBuilder, )
+
 } // namespace lower
 } // namespace Fortran
 
index 30d9e5e..9861441 100644 (file)
@@ -122,7 +122,7 @@ genFIRType(mlir::MLIRContext *context, Fortran::common::TypeCategory tc,
 // Symbol and expression type translation
 //===--------------------------------------------------------------------===//
 
-/// TypeBuilder translates expression and symbol type taking into account
+/// TypeBuilderImpl translates expression and symbol type taking into account
 /// their shape and length parameters. For symbols, attributes such as
 /// ALLOCATABLE or POINTER are reflected in the fir type.
 /// It uses evaluate::DynamicType and evaluate::Shape when possible to
@@ -130,12 +130,13 @@ genFIRType(mlir::MLIRContext *context, Fortran::common::TypeCategory tc,
 /// Do not use the FirOpBuilder from the AbstractConverter to get fir/mlir types
 /// since it is not guaranteed to exist yet when we lower types.
 namespace {
-struct TypeBuilder {
+struct TypeBuilderImpl {
 
-  TypeBuilder(Fortran::lower::AbstractConverter &converter)
+  TypeBuilderImpl(Fortran::lower::AbstractConverter &converter)
       : converter{converter}, context{&converter.getMLIRContext()} {}
 
-  mlir::Type genExprType(const Fortran::lower::SomeExpr &expr) {
+  template <typename A>
+  mlir::Type genExprType(const A &expr) {
     std::optional<Fortran::evaluate::DynamicType> dynamicType = expr.GetType();
     if (!dynamicType)
       return genTypelessExprType(expr);
@@ -188,6 +189,11 @@ struct TypeBuilder {
         converter.getFoldingContext(), std::move(expr)));
   }
 
+  template <typename A>
+  mlir::Type genTypelessExprType(const A &expr) {
+    fir::emitFatalError(converter.getCurrentLocation(), "not a typeless expr");
+  }
+
   mlir::Type genTypelessExprType(const Fortran::lower::SomeExpr &expr) {
     return std::visit(
         Fortran::common::visitors{
@@ -397,6 +403,11 @@ struct TypeBuilder {
     }
     llvm_unreachable("unknown character kind");
   }
+
+  template <typename A>
+  Fortran::lower::LenParameterTy getCharacterLength(const A &expr) {
+    return fir::SequenceType::getUnknownExtent();
+  }
   Fortran::lower::LenParameterTy
   getCharacterLength(const Fortran::lower::SomeExpr &expr) {
     // Do not use dynamic type length here. We would miss constant
@@ -450,25 +461,36 @@ mlir::Type Fortran::lower::getFIRType(mlir::MLIRContext *context,
 mlir::Type Fortran::lower::translateDerivedTypeToFIRType(
     Fortran::lower::AbstractConverter &converter,
     const Fortran::semantics::DerivedTypeSpec &tySpec) {
-  return TypeBuilder{converter}.genDerivedType(tySpec);
+  return TypeBuilderImpl{converter}.genDerivedType(tySpec);
 }
 
 mlir::Type Fortran::lower::translateSomeExprToFIRType(
     Fortran::lower::AbstractConverter &converter, const SomeExpr &expr) {
-  return TypeBuilder{converter}.genExprType(expr);
+  return TypeBuilderImpl{converter}.genExprType(expr);
 }
 
 mlir::Type Fortran::lower::translateSymbolToFIRType(
     Fortran::lower::AbstractConverter &converter, const SymbolRef symbol) {
-  return TypeBuilder{converter}.genSymbolType(symbol);
+  return TypeBuilderImpl{converter}.genSymbolType(symbol);
 }
 
 mlir::Type Fortran::lower::translateVariableToFIRType(
     Fortran::lower::AbstractConverter &converter,
     const Fortran::lower::pft::Variable &var) {
-  return TypeBuilder{converter}.genVariableType(var);
+  return TypeBuilderImpl{converter}.genVariableType(var);
 }
 
 mlir::Type Fortran::lower::convertReal(mlir::MLIRContext *context, int kind) {
   return genRealType(context, kind);
 }
+
+template <typename T>
+mlir::Type Fortran::lower::TypeBuilder<T>::genType(
+    Fortran::lower::AbstractConverter &converter,
+    const Fortran::evaluate::FunctionRef<T> &funcRef) {
+  return TypeBuilderImpl{converter}.genExprType(funcRef);
+}
+
+using namespace Fortran::evaluate;
+using namespace Fortran::common;
+FOR_EACH_SPECIFIC_TYPE(template class Fortran::lower::TypeBuilder, )