diff --git a/flang/include/flang/Lower/IntrinsicCall.h b/flang/include/flang/Lower/IntrinsicCall.h --- a/flang/include/flang/Lower/IntrinsicCall.h +++ b/flang/include/flang/Lower/IntrinsicCall.h @@ -19,15 +19,6 @@ // TODO: Error handling interface ? // TODO: Implementation is incomplete. Many intrinsics to tbd. -/// Generate the FIR+MLIR operations for the generic intrinsic \p name -/// with arguments \p args and expected result type \p resultType. -/// Returned mlir::Value is the returned Fortran intrinsic value. -fir::ExtendedValue genIntrinsicCall(fir::FirOpBuilder &, mlir::Location, - llvm::StringRef name, - std::optional resultType, - llvm::ArrayRef args, - StatementContext &); - /// Same as the other genIntrinsicCall version above, except that the result /// deallocation, if required, is not added to a StatementContext. Instead, an /// extra boolean result indicates if the result must be freed after use. diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp --- a/flang/lib/Lower/ConvertExpr.cpp +++ b/flang/lib/Lower/ConvertExpr.cpp @@ -655,6 +655,27 @@ expr.u); } +/// Generate the FIR+MLIR operations for the generic intrinsic \p name +/// with arguments \p args and the expected result type \p resultType. +/// Returned fir::ExtendedValue is the returned Fortran intrinsic value. +static fir::ExtendedValue +genIntrinsicCall(fir::FirOpBuilder &builder, mlir::Location loc, + llvm::StringRef name, std::optional resultType, + llvm::ArrayRef args, + Fortran::lower::StatementContext &stmtCtx) { + auto [result, mustBeFreed] = + Fortran::lower::genIntrinsicCall(builder, loc, name, resultType, args); + if (mustBeFreed) { + mlir::Value addr = fir::getBase(result); + if (auto *box = result.getBoxOf()) + addr = + builder.create(loc, box->getMemTy(), box->getAddr()); + fir::FirOpBuilder *bldr = &builder; + stmtCtx.attachCleanup([=]() { bldr->create(loc, addr); }); + } + return result; +} + namespace { /// Lowering of Fortran::evaluate::Expr expressions @@ -1938,8 +1959,8 @@ llvm_unreachable("bad switch"); } // Let the intrinsic library lower the intrinsic procedure call - return Fortran::lower::genIntrinsicCall(builder, getLoc(), name, resultType, - operands, stmtCtx); + return genIntrinsicCall(builder, getLoc(), name, resultType, operands, + stmtCtx); } /// helper to detect statement functions @@ -4577,8 +4598,7 @@ llvm::SmallVector args; for (const auto &cc : operands) args.push_back(cc(iters)); - return Fortran::lower::genIntrinsicCall(builder, loc, name, retTy, args, - getElementCtx()); + return genIntrinsicCall(builder, loc, name, retTy, args, getElementCtx()); }; } diff --git a/flang/lib/Lower/CustomIntrinsicCall.cpp b/flang/lib/Lower/CustomIntrinsicCall.cpp --- a/flang/lib/Lower/CustomIntrinsicCall.cpp +++ b/flang/lib/Lower/CustomIntrinsicCall.cpp @@ -15,6 +15,7 @@ #include "flang/Evaluate/fold.h" #include "flang/Evaluate/tools.h" #include "flang/Lower/IntrinsicCall.h" +#include "flang/Lower/StatementContext.h" #include "flang/Optimizer/Builder/Todo.h" #include @@ -63,6 +64,27 @@ isIshftcWithDynamicallyOptionalArg(name, procRef, fldCtx); } +/// Generate the FIR+MLIR operations for the generic intrinsic \p name +/// with arguments \p args and the expected result type \p resultType. +/// Returned fir::ExtendedValue is the returned Fortran intrinsic value. +static fir::ExtendedValue +genIntrinsicCall(fir::FirOpBuilder &builder, mlir::Location loc, + llvm::StringRef name, std::optional resultType, + llvm::ArrayRef args, + Fortran::lower::StatementContext &stmtCtx) { + auto [result, mustBeFreed] = + Fortran::lower::genIntrinsicCall(builder, loc, name, resultType, args); + if (mustBeFreed) { + mlir::Value addr = fir::getBase(result); + if (auto *box = result.getBoxOf()) + addr = + builder.create(loc, box->getMemTy(), box->getAddr()); + fir::FirOpBuilder *bldr = &builder; + stmtCtx.attachCleanup([=]() { bldr->create(loc, addr); }); + } + return result; +} + static void prepareMinOrMaxArguments( const Fortran::evaluate::ProcedureRef &procRef, const Fortran::evaluate::SpecificIntrinsic &intrinsic, @@ -108,8 +130,8 @@ llvm::SmallVector args; args.push_back(getOperand(0)); args.push_back(getOperand(1)); - mlir::Value extremum = fir::getBase(Fortran::lower::genIntrinsicCall( - builder, loc, name, resultType, args, stmtCtx)); + mlir::Value extremum = fir::getBase( + genIntrinsicCall(builder, loc, name, resultType, args, stmtCtx)); for (std::size_t opIndex = 2; opIndex < numOperands; ++opIndex) { if (std::optional isPresentRuntimeCheck = @@ -123,9 +145,8 @@ llvm::SmallVector args; args.emplace_back(extremum); args.emplace_back(getOperand(opIndex)); - fir::ExtendedValue newExtremum = - Fortran::lower::genIntrinsicCall(builder, loc, name, - resultType, args, stmtCtx); + fir::ExtendedValue newExtremum = genIntrinsicCall( + builder, loc, name, resultType, args, stmtCtx); builder.create(loc, fir::getBase(newExtremum)); }) .genElse([&]() { builder.create(loc, extremum); }) @@ -135,8 +156,8 @@ llvm::SmallVector args; args.emplace_back(extremum); args.emplace_back(getOperand(opIndex)); - extremum = fir::getBase(Fortran::lower::genIntrinsicCall( - builder, loc, name, resultType, args, stmtCtx)); + extremum = fir::getBase( + genIntrinsicCall(builder, loc, name, resultType, args, stmtCtx)); } } return extremum; @@ -198,8 +219,7 @@ builder.create(loc, bitSize); }) .getResults()[0]); - return Fortran::lower::genIntrinsicCall(builder, loc, name, resultType, args, - stmtCtx); + return genIntrinsicCall(builder, loc, name, resultType, args, stmtCtx); } void Fortran::lower::prepareCustomIntrinsicArgument( diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp --- a/flang/lib/Lower/IntrinsicCall.cpp +++ b/flang/lib/Lower/IntrinsicCall.cpp @@ -17,7 +17,6 @@ #include "flang/Common/static-multimap-view.h" #include "flang/Lower/Mangler.h" #include "flang/Lower/Runtime.h" -#include "flang/Lower/StatementContext.h" #include "flang/Lower/Support/Utils.h" #include "flang/Lower/SymbolMap.h" #include "flang/Optimizer/Builder/BoxValue.h" @@ -5307,24 +5306,6 @@ // Public intrinsic call helpers //===----------------------------------------------------------------------===// -fir::ExtendedValue -Fortran::lower::genIntrinsicCall(fir::FirOpBuilder &builder, mlir::Location loc, - llvm::StringRef name, - std::optional resultType, - llvm::ArrayRef args, - Fortran::lower::StatementContext &stmtCtx) { - auto [result, mustBeFreed] = - IntrinsicLibrary{builder, loc}.genIntrinsicCall(name, resultType, args); - if (mustBeFreed) { - mlir::Value addr = fir::getBase(result); - if (auto *box = result.getBoxOf()) - addr = - builder.create(loc, box->getMemTy(), box->getAddr()); - fir::FirOpBuilder *bldr = &builder; - stmtCtx.attachCleanup([=]() { bldr->create(loc, addr); }); - } - return result; -} std::pair Fortran::lower::genIntrinsicCall(fir::FirOpBuilder &builder, mlir::Location loc, llvm::StringRef name,