[flang][NFC] add genType(FunctionRef<T>) entry points in lowering

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
This commit is contained in:
Jean Perier 2022-11-30 14:44:10 +01:00
parent 7fea6f2e0e
commit d71c1de0ff
2 changed files with 42 additions and 8 deletions

View 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

View 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, )