forked from OSchip/llvm-project
[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:
parent
7fea6f2e0e
commit
d71c1de0ff
|
@ -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
|
||||
|
||||
|
|
|
@ -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, )
|
||||
|
|
Loading…
Reference in New Issue