Files
clang-p2996/flang/lib/Optimizer/Builder/Runtime/Reduction.cpp
Peter Klausler fc97d2e68b [flang] Add UNSIGNED (#113504)
Implement the UNSIGNED extension type and operations under control of a
language feature flag (-funsigned).

This is nearly identical to the UNSIGNED feature that has been available
in Sun Fortran for years, and now implemented in GNU Fortran for
gfortran 15, and proposed for ISO standardization in J3/24-116.txt.

See the new documentation for details; but in short, this is C's
unsigned type, with guaranteed modular arithmetic for +, -, and *, and
the related transformational intrinsic functions SUM & al.
2024-12-18 07:02:37 -08:00

1921 lines
88 KiB
C++

//===-- Reduction.cpp -- generate reduction intrinsics runtime calls- -----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Builder/Runtime/Reduction.h"
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/Character.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Optimizer/Support/Utils.h"
#include "flang/Runtime/reduce.h"
#include "flang/Runtime/reduction.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
using namespace Fortran::runtime;
#define STRINGIFY(S) #S
#define JOIN2(A, B) A##B
#define JOIN3(A, B, C) A##B##C
/// Placeholder for real*10 version of Maxval Intrinsic
struct ForcedMaxvalReal10 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MaxvalReal10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for real*16 version of Maxval Intrinsic
struct ForcedMaxvalReal16 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MaxvalReal16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for integer*16 version of Maxval Intrinsic
struct ForcedMaxvalInteger16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(MaxvalInteger16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for unsigned*16 version of Maxval Intrinsic
struct ForcedMaxvalUnsigned16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(MaxvalUnsigned16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(
ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for real*10 version of Minval Intrinsic
struct ForcedMinvalReal10 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MinvalReal10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for real*16 version of Minval Intrinsic
struct ForcedMinvalReal16 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MinvalReal16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for integer*16 version of Minval Intrinsic
struct ForcedMinvalInteger16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(MinvalInteger16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for unsigned*16 version of Minval Intrinsic
struct ForcedMinvalUnsigned16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(MinvalUnsigned16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(
ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
// Maxloc/Minloc take descriptor, so these runtime signature are not ifdef
// and the mkRTKey can safely be used here. Define alias so that the
// REAL_INTRINSIC_INSTANCES macro works with them too
using ForcedMaxlocReal10 = mkRTKey(MaxlocReal10);
using ForcedMaxlocReal16 = mkRTKey(MaxlocReal16);
using ForcedMaxlocInteger16 = mkRTKey(MaxlocInteger16);
using ForcedMaxlocUnsigned16 = mkRTKey(MaxlocUnsigned16);
using ForcedMinlocReal10 = mkRTKey(MinlocReal10);
using ForcedMinlocReal16 = mkRTKey(MinlocReal16);
using ForcedMinlocInteger16 = mkRTKey(MinlocInteger16);
using ForcedMinlocUnsigned16 = mkRTKey(MinlocUnsigned16);
/// Placeholder for real*10 version of Norm2 Intrinsic
struct ForcedNorm2Real10 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Norm2_10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy}, {ty});
};
}
};
/// Placeholder for real*16 version of Norm2 Intrinsic
struct ForcedNorm2Real16 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Norm2_16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy}, {ty});
};
}
};
/// Placeholder for real*16 version of Norm2Dim Intrinsic
struct ForcedNorm2DimReal16 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Norm2DimReal16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(
ctx, {fir::ReferenceType::get(boxTy), boxTy, intTy, strTy, intTy},
mlir::NoneType::get(ctx));
};
}
};
/// Placeholder for real*10 version of Product Intrinsic
struct ForcedProductReal10 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ProductReal10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for real*16 version of Product Intrinsic
struct ForcedProductReal16 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ProductReal16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for integer*16 version of Product Intrinsic
struct ForcedProductInteger16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ProductInteger16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for unsigned*16 version of Product Intrinsic
struct ForcedProductUnsigned16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ProductUnsigned16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(
ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for complex(10) version of Product Intrinsic
struct ForcedProductComplex10 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppProductComplex10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto resTy = fir::ReferenceType::get(ty);
return mlir::FunctionType::get(
ctx, {resTy, boxTy, strTy, intTy, intTy, boxTy}, {});
};
}
};
/// Placeholder for complex(16) version of Product Intrinsic
struct ForcedProductComplex16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppProductComplex16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto resTy = fir::ReferenceType::get(ty);
return mlir::FunctionType::get(
ctx, {resTy, boxTy, strTy, intTy, intTy, boxTy}, {});
};
}
};
/// Placeholder for real*10 version of DotProduct Intrinsic
struct ForcedDotProductReal10 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(DotProductReal10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, boxTy, strTy, intTy}, {ty});
};
}
};
/// Placeholder for real*16 version of DotProduct Intrinsic
struct ForcedDotProductReal16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(DotProductReal16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, boxTy, strTy, intTy}, {ty});
};
}
};
/// Placeholder for complex(10) version of DotProduct Intrinsic
struct ForcedDotProductComplex10 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppDotProductComplex10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto resTy = fir::ReferenceType::get(ty);
return mlir::FunctionType::get(ctx, {resTy, boxTy, boxTy, strTy, intTy},
{});
};
}
};
/// Placeholder for complex(16) version of DotProduct Intrinsic
struct ForcedDotProductComplex16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppDotProductComplex16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto resTy = fir::ReferenceType::get(ty);
return mlir::FunctionType::get(ctx, {resTy, boxTy, boxTy, strTy, intTy},
{});
};
}
};
/// Placeholder for integer*16 version of DotProduct Intrinsic
struct ForcedDotProductInteger16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(DotProductInteger16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, boxTy, strTy, intTy}, {ty});
};
}
};
/// Placeholder for unsigned*16 version of DotProduct Intrinsic
struct ForcedDotProductUnsigned16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(DotProductUnsigned16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(
ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, boxTy, strTy, intTy}, {ty});
};
}
};
/// Placeholder for real*10 version of Sum Intrinsic
struct ForcedSumReal10 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SumReal10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for real*16 version of Sum Intrinsic
struct ForcedSumReal16 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SumReal16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for integer*16 version of Sum Intrinsic
struct ForcedSumInteger16 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SumInteger16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for unsigned*16 version of Sum Intrinsic
struct ForcedSumUnsigned16 {
static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SumUnsigned16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(
ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for complex(10) version of Sum Intrinsic
struct ForcedSumComplex10 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppSumComplex10));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto resTy = fir::ReferenceType::get(ty);
return mlir::FunctionType::get(
ctx, {resTy, boxTy, strTy, intTy, intTy, boxTy}, {});
};
}
};
/// Placeholder for complex(16) version of Sum Intrinsic
struct ForcedSumComplex16 {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppSumComplex16));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto resTy = fir::ReferenceType::get(ty);
return mlir::FunctionType::get(
ctx, {resTy, boxTy, strTy, intTy, intTy, boxTy}, {});
};
}
};
/// Placeholder for integer(16) version of IAll Intrinsic
struct ForcedIAll16 {
static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IAll16);
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for integer(16) version of IAny Intrinsic
struct ForcedIAny16 {
static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IAny16);
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for integer(16) version of IParity Intrinsic
struct ForcedIParity16 {
static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IParity16);
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},
{ty});
};
}
};
/// Placeholder for real*10 version of Reduce Intrinsic
struct ForcedReduceReal10Ref {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceReal10Ref));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
};
}
};
/// Placeholder for real*10 version of Reduce Intrinsic
struct ForcedReduceReal10Value {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceReal10Value));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
};
}
};
/// Placeholder for real*16 version of Reduce Intrinsic
struct ForcedReduceReal16Ref {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceReal16Ref));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
};
}
};
/// Placeholder for real*16 version of Reduce Intrinsic
struct ForcedReduceReal16Value {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceReal16Value));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
};
}
};
/// Placeholder for DIM real*10 version of Reduce Intrinsic
struct ForcedReduceReal10DimRef {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceReal10DimRef));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for DIM real*10 with value version of Reduce Intrinsic
struct ForcedReduceReal10DimValue {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceReal10DimValue));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF80(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for DIM real*16 version of Reduce Intrinsic
struct ForcedReduceReal16DimRef {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceReal16DimRef));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for DIM real*16 with value version of Reduce Intrinsic
struct ForcedReduceReal16DimValue {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceReal16DimValue));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::FloatType::getF128(ctx);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for integer*16 version of Reduce Intrinsic
struct ForcedReduceInteger16Ref {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceInteger16Ref));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
};
}
};
/// Placeholder for unsigned*16 version of Reduce Intrinsic
struct ForcedReduceUnsigned16Ref {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceUnsigned16Ref));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
};
}
};
/// Placeholder for integer*16 with value version of Reduce Intrinsic
struct ForcedReduceInteger16Value {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceInteger16Value));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
};
}
};
/// Placeholder for unsigned*16 with value version of Reduce Intrinsic
struct ForcedReduceUnsigned16Value {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceUnsigned16Value));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});
};
}
};
/// Placeholder for DIM integer*16 version of Reduce Intrinsic
struct ForcedReduceInteger16DimRef {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceInteger16DimRef));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for DIM unsigned*16 version of Reduce Intrinsic
struct ForcedReduceUnsigned16DimRef {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceUnsigned16DimRef));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(
ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for DIM integer*16 with value version of Reduce Intrinsic
struct ForcedReduceInteger16DimValue {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceInteger16DimValue));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(ctx, 128);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for DIM unsigned*16 with value version of Reduce Intrinsic
struct ForcedReduceUnsigned16DimValue {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(ReduceUnsigned16DimValue));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::IntegerType::get(
ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for complex(10) version of Reduce Intrinsic
struct ForcedReduceComplex10Ref {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppReduceComplex10Ref));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for complex(10) with value version of Reduce Intrinsic
struct ForcedReduceComplex10Value {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppReduceComplex10Value));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for Dim complex(10) version of Reduce Intrinsic
struct ForcedReduceComplex10DimRef {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppReduceComplex10DimRef));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for Dim complex(10) with value version of Reduce Intrinsic
struct ForcedReduceComplex10DimValue {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppReduceComplex10DimValue));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF80(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for complex(16) version of Reduce Intrinsic
struct ForcedReduceComplex16Ref {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppReduceComplex16Ref));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for complex(16) with value version of Reduce Intrinsic
struct ForcedReduceComplex16Value {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppReduceComplex16Value));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for Dim complex(16) version of Reduce Intrinsic
struct ForcedReduceComplex16DimRef {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppReduceComplex16DimRef));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
/// Placeholder for Dim complex(16) with value version of Reduce Intrinsic
struct ForcedReduceComplex16DimValue {
static constexpr const char *name =
ExpandAndQuoteKey(RTNAME(CppReduceComplex16DimValue));
static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {
return [](mlir::MLIRContext *ctx) {
auto ty = mlir::ComplexType::get(mlir::FloatType::getF128(ctx));
auto boxTy =
fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);
auto refTy = fir::ReferenceType::get(ty);
auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);
auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));
auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));
auto refBoxTy = fir::ReferenceType::get(boxTy);
auto i1Ty = mlir::IntegerType::get(ctx, 1);
return mlir::FunctionType::get(
ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},
{});
};
}
};
#define INTRINSIC_INSTANCE(NAME, CAT, KIND, SUFFIX) \
if (!func && cat == TypeCategory::CAT && kind == KIND) { \
func = fir::runtime::getRuntimeFunc<mkRTKey(NAME##CAT##KIND##SUFFIX)>( \
loc, builder); \
}
#define FORCED_INTRINSIC_INSTANCE(NAME, CAT, KIND, SUFFIX) \
if (!func && cat == TypeCategory::CAT && kind == KIND) { \
func = fir::runtime::getRuntimeFunc<Forced##NAME##CAT##KIND##SUFFIX>( \
loc, builder); \
}
#define INTEGER_INTRINSIC_INSTANCES(NAME, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Integer, 1, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Integer, 2, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Integer, 4, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Integer, 8, SUFFIX) \
FORCED_INTRINSIC_INSTANCE(NAME, Integer, 16, SUFFIX)
#define UNSIGNED_INTRINSIC_INSTANCES(NAME, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Unsigned, 1, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Unsigned, 2, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Unsigned, 4, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Unsigned, 8, SUFFIX) \
FORCED_INTRINSIC_INSTANCE(NAME, Unsigned, 16, SUFFIX)
#define REAL_INTRINSIC_INSTANCES(NAME, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Real, 4, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Real, 8, SUFFIX) \
FORCED_INTRINSIC_INSTANCE(NAME, Real, 10, SUFFIX) \
FORCED_INTRINSIC_INSTANCE(NAME, Real, 16, SUFFIX)
#define COMPLEX_INTRINSIC_INSTANCES(NAME, SUFFIX) \
INTRINSIC_INSTANCE(Cpp##NAME, Complex, 4, SUFFIX) \
INTRINSIC_INSTANCE(Cpp##NAME, Complex, 8, SUFFIX) \
FORCED_INTRINSIC_INSTANCE(NAME, Complex, 10, SUFFIX) \
FORCED_INTRINSIC_INSTANCE(NAME, Complex, 16, SUFFIX)
#define NUMERICAL_INTRINSIC_INSTANCES(NAME) \
INTEGER_INTRINSIC_INSTANCES(NAME, ) \
UNSIGNED_INTRINSIC_INSTANCES(NAME, ) \
REAL_INTRINSIC_INSTANCES(NAME, ) \
COMPLEX_INTRINSIC_INSTANCES(NAME, )
#define LOGICAL_INTRINSIC_INSTANCES(NAME, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Logical, 1, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Logical, 2, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Logical, 4, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Logical, 8, SUFFIX)
#define NUMERICAL_AND_LOGICAL_INSTANCES(NAME, SUFFIX) \
INTEGER_INTRINSIC_INSTANCES(NAME, SUFFIX) \
UNSIGNED_INTRINSIC_INSTANCES(NAME, SUFFIX) \
REAL_INTRINSIC_INSTANCES(NAME, SUFFIX) \
COMPLEX_INTRINSIC_INSTANCES(NAME, SUFFIX) \
LOGICAL_INTRINSIC_INSTANCES(NAME, SUFFIX)
// REAL/COMPLEX 2 and 3 usually have no runtime implementation, so they have
// special macros.
#define REAL_2_3_INTRINSIC_INSTANCES(NAME, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Real, 2, SUFFIX) \
INTRINSIC_INSTANCE(NAME, Real, 3, SUFFIX)
#define COMPLEX_2_3_INTRINSIC_INSTANCES(NAME, SUFFIX) \
INTRINSIC_INSTANCE(Cpp##NAME, Complex, 2, SUFFIX) \
INTRINSIC_INSTANCE(Cpp##NAME, Complex, 3, SUFFIX)
/// Generate call to specialized runtime function that takes a mask and
/// dim argument. The All, Any, and Count intrinsics use this pattern.
template <typename FN>
mlir::Value genSpecial2Args(FN func, fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value maskBox,
mlir::Value dim) {
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));
auto args = fir::runtime::createArguments(builder, loc, fTy, maskBox,
sourceFile, sourceLine, dim);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
/// Generate calls to reduction intrinsics such as All and Any.
/// These are the descriptor based implementations that take two
/// arguments (mask, dim).
template <typename FN>
static void genReduction2Args(FN func, fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value resultBox,
mlir::Value maskBox, mlir::Value dim) {
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultBox, maskBox, dim, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate calls to reduction intrinsics such as Maxval and Minval.
/// These take arguments such as (array, dim, mask).
template <typename FN>
static void genReduction3Args(FN func, fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value resultBox,
mlir::Value arrayBox, mlir::Value dim,
mlir::Value maskBox) {
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto args =
fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox, dim,
sourceFile, sourceLine, maskBox);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate calls to reduction intrinsics such as Maxloc and Minloc.
/// These take arguments such as (array, mask, kind, back).
template <typename FN>
static void genReduction4Args(FN func, fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value resultBox,
mlir::Value arrayBox, mlir::Value maskBox,
mlir::Value kind, mlir::Value back) {
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
arrayBox, kind, sourceFile,
sourceLine, maskBox, back);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate calls to reduction intrinsics such as Maxloc and Minloc.
/// These take arguments such as (array, dim, mask, kind, back).
template <typename FN>
static void
genReduction5Args(FN func, fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox, mlir::Value dim,
mlir::Value maskBox, mlir::Value kind, mlir::Value back) {
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
arrayBox, kind, dim, sourceFile,
sourceLine, maskBox, back);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `AllDim` runtime routine.
/// This calls the descriptor based runtime call implementation of the `all`
/// intrinsic.
void fir::runtime::genAllDescriptor(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value resultBox,
mlir::Value maskBox, mlir::Value dim) {
auto allFunc = fir::runtime::getRuntimeFunc<mkRTKey(AllDim)>(loc, builder);
genReduction2Args(allFunc, builder, loc, resultBox, maskBox, dim);
}
/// Generate call to `AnyDim` runtime routine.
/// This calls the descriptor based runtime call implementation of the `any`
/// intrinsic.
void fir::runtime::genAnyDescriptor(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value resultBox,
mlir::Value maskBox, mlir::Value dim) {
auto anyFunc = fir::runtime::getRuntimeFunc<mkRTKey(AnyDim)>(loc, builder);
genReduction2Args(anyFunc, builder, loc, resultBox, maskBox, dim);
}
/// Generate call to `ParityDim` runtime routine.
/// This calls the descriptor based runtime call implementation of the `parity`
/// intrinsic.
void fir::runtime::genParityDescriptor(fir::FirOpBuilder &builder,
mlir::Location loc,
mlir::Value resultBox,
mlir::Value maskBox, mlir::Value dim) {
auto parityFunc =
fir::runtime::getRuntimeFunc<mkRTKey(ParityDim)>(loc, builder);
genReduction2Args(parityFunc, builder, loc, resultBox, maskBox, dim);
}
/// Generate call to `All` intrinsic runtime routine. This routine is
/// specialized for mask arguments with rank == 1.
mlir::Value fir::runtime::genAll(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value maskBox, mlir::Value dim) {
auto allFunc = fir::runtime::getRuntimeFunc<mkRTKey(All)>(loc, builder);
return genSpecial2Args(allFunc, builder, loc, maskBox, dim);
}
/// Generate call to `Any` intrinsic runtime routine. This routine is
/// specialized for mask arguments with rank == 1.
mlir::Value fir::runtime::genAny(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value maskBox, mlir::Value dim) {
auto anyFunc = fir::runtime::getRuntimeFunc<mkRTKey(Any)>(loc, builder);
return genSpecial2Args(anyFunc, builder, loc, maskBox, dim);
}
/// Generate call to `Count` runtime routine. This routine is a specialized
/// version when mask is a rank one array or the dim argument is not
/// specified by the user.
mlir::Value fir::runtime::genCount(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value maskBox,
mlir::Value dim) {
auto countFunc = fir::runtime::getRuntimeFunc<mkRTKey(Count)>(loc, builder);
return genSpecial2Args(countFunc, builder, loc, maskBox, dim);
}
/// Generate call to general `CountDim` runtime routine. This routine has a
/// descriptor result.
void fir::runtime::genCountDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value maskBox,
mlir::Value dim, mlir::Value kind) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(CountDim)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultBox, maskBox, dim, kind, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `Findloc` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
void fir::runtime::genFindloc(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value valBox, mlir::Value maskBox,
mlir::Value kind, mlir::Value back) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(Findloc)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));
auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,
arrayBox, valBox, kind, sourceFile,
sourceLine, maskBox, back);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `FindlocDim` intrinsic runtime routine. This is the version
/// that takes a dim argument.
void fir::runtime::genFindlocDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value valBox, mlir::Value dim,
mlir::Value maskBox, mlir::Value kind,
mlir::Value back) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(FindlocDim)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(6));
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultBox, arrayBox, valBox, kind, dim, sourceFile,
sourceLine, maskBox, back);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `Maxloc` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
void fir::runtime::genMaxloc(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value maskBox, mlir::Value kindVal,
mlir::Value back) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
fir::factory::CharacterExprHelper charHelper{builder, loc};
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
REAL_INTRINSIC_INSTANCES(Maxloc, )
INTEGER_INTRINSIC_INSTANCES(Maxloc, )
UNSIGNED_INTRINSIC_INSTANCES(Maxloc, )
if (charHelper.isCharacterScalar(eleTy))
func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocCharacter)>(loc, builder);
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXLOC");
genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kindVal,
back);
}
/// Generate call to `MaxlocDim` intrinsic runtime routine. This is the version
/// that takes a dim argument.
void fir::runtime::genMaxlocDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox,
mlir::Value kind, mlir::Value back) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocDim)>(loc, builder);
genReduction5Args(func, builder, loc, resultBox, arrayBox, dim, maskBox, kind,
back);
}
/// Generate call to `Maxval` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
mlir::Value fir::runtime::genMaxval(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value arrayBox,
mlir::Value maskBox) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
REAL_INTRINSIC_INSTANCES(Maxval, )
INTEGER_INTRINSIC_INSTANCES(Maxval, )
UNSIGNED_INTRINSIC_INSTANCES(Maxval, )
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXVAL");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));
auto args = fir::runtime::createArguments(
builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
/// Generate call to `MaxvalDim` intrinsic runtime routine. This is the version
/// that handles any rank array with the dim argument specified.
void fir::runtime::genMaxvalDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalDim)>(loc, builder);
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
}
/// Generate call to `MaxvalCharacter` intrinsic runtime routine. This is the
/// version that handles character arrays of rank 1 and without a DIM argument.
void fir::runtime::genMaxvalChar(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value maskBox) {
auto func =
fir::runtime::getRuntimeFunc<mkRTKey(MaxvalCharacter)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultBox, arrayBox, sourceFile, sourceLine, maskBox);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `Minloc` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
void fir::runtime::genMinloc(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value maskBox, mlir::Value kindVal,
mlir::Value back) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
REAL_INTRINSIC_INSTANCES(Minloc, )
INTEGER_INTRINSIC_INSTANCES(Minloc, )
UNSIGNED_INTRINSIC_INSTANCES(Minloc, )
fir::factory::CharacterExprHelper charHelper{builder, loc};
if (charHelper.isCharacterScalar(eleTy))
func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocCharacter)>(loc, builder);
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "MINLOC");
genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kindVal,
back);
}
/// Generate call to `MinlocDim` intrinsic runtime routine. This is the version
/// that takes a dim argument.
void fir::runtime::genMinlocDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox,
mlir::Value kind, mlir::Value back) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocDim)>(loc, builder);
genReduction5Args(func, builder, loc, resultBox, arrayBox, dim, maskBox, kind,
back);
}
/// Generate call to `MinvalDim` intrinsic runtime routine. This is the version
/// that handles any rank array with the dim argument specified.
void fir::runtime::genMinvalDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalDim)>(loc, builder);
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
}
/// Generate call to `MinvalCharacter` intrinsic runtime routine. This is the
/// version that handles character arrays of rank 1 and without a DIM argument.
void fir::runtime::genMinvalChar(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value maskBox) {
auto func =
fir::runtime::getRuntimeFunc<mkRTKey(MinvalCharacter)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultBox, arrayBox, sourceFile, sourceLine, maskBox);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `Minval` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
mlir::Value fir::runtime::genMinval(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value arrayBox,
mlir::Value maskBox) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
REAL_INTRINSIC_INSTANCES(Minval, )
INTEGER_INTRINSIC_INSTANCES(Minval, )
UNSIGNED_INTRINSIC_INSTANCES(Minval, )
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "MINVAL");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));
auto args = fir::runtime::createArguments(
builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
/// Generate call to `Norm2Dim` intrinsic runtime routine. This is the version
/// that takes a dim argument.
void fir::runtime::genNorm2Dim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim) {
mlir::func::FuncOp func;
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
if (eleTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedNorm2DimReal16>(loc, builder);
else
func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2Dim)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultBox, arrayBox, dim, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `Norm2` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
mlir::Value fir::runtime::genNorm2(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value arrayBox) {
mlir::func::FuncOp func;
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
if (eleTy.isF32())
func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2_4)>(loc, builder);
else if (eleTy.isF64())
func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2_8)>(loc, builder);
else if (eleTy.isF80())
func = fir::runtime::getRuntimeFunc<ForcedNorm2Real10>(loc, builder);
else if (eleTy.isF128())
func = fir::runtime::getRuntimeFunc<ForcedNorm2Real16>(loc, builder);
else
fir::intrinsicTypeTODO(builder, eleTy, loc, "NORM2");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));
auto args = fir::runtime::createArguments(builder, loc, fTy, arrayBox,
sourceFile, sourceLine, dim);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
/// Generate call to `Parity` intrinsic runtime routine. This routine is
/// specialized for mask arguments with rank == 1.
mlir::Value fir::runtime::genParity(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value maskBox,
mlir::Value dim) {
auto parityFunc = fir::runtime::getRuntimeFunc<mkRTKey(Parity)>(loc, builder);
return genSpecial2Args(parityFunc, builder, loc, maskBox, dim);
}
/// Generate call to `ProductDim` intrinsic runtime routine. This is the version
/// that handles any rank array with the dim argument specified.
void fir::runtime::genProductDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(ProductDim)>(loc, builder);
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
}
/// Generate call to `Product` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
mlir::Value fir::runtime::genProduct(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value arrayBox,
mlir::Value maskBox,
mlir::Value resultBox) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
NUMERICAL_INTRINSIC_INSTANCES(Product)
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "PRODUCT");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
if (fir::isa_complex(eleTy)) {
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
auto args =
fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
sourceFile, sourceLine, dim, maskBox);
builder.create<fir::CallOp>(loc, func, args);
return resultBox;
}
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));
auto args = fir::runtime::createArguments(
builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
/// Generate call to `DotProduct` intrinsic runtime routine.
mlir::Value fir::runtime::genDotProduct(fir::FirOpBuilder &builder,
mlir::Location loc,
mlir::Value vectorABox,
mlir::Value vectorBBox,
mlir::Value resultBox) {
// For complex data types, resultBox is !fir.ref<!fir.complex<N>>,
// otherwise it is !fir.box<T>.
auto ty = resultBox.getType();
auto eleTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
NUMERICAL_INTRINSIC_INSTANCES(DotProduct)
if (cat == Fortran::common::TypeCategory::Logical)
func =
fir::runtime::getRuntimeFunc<mkRTKey(DotProductLogical)>(loc, builder);
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "DOTPRODUCT");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
if (fir::isa_complex(eleTy)) {
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto args =
fir::runtime::createArguments(builder, loc, fTy, resultBox, vectorABox,
vectorBBox, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, func, args);
return resultBox;
}
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
auto args = fir::runtime::createArguments(builder, loc, fTy, vectorABox,
vectorBBox, sourceFile, sourceLine);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
/// Generate call to `SumDim` intrinsic runtime routine. This is the version
/// that handles any rank array with the dim argument specified.
void fir::runtime::genSumDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(SumDim)>(loc, builder);
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
}
/// Generate call to `Sum` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
mlir::Value fir::runtime::genSum(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value arrayBox, mlir::Value maskBox,
mlir::Value resultBox) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
NUMERICAL_INTRINSIC_INSTANCES(Sum)
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "SUM");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
if (fir::isa_complex(eleTy)) {
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
auto args =
fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,
sourceFile, sourceLine, dim, maskBox);
builder.create<fir::CallOp>(loc, func, args);
return resultBox;
}
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));
auto args = fir::runtime::createArguments(
builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
// The IAll, IAny and IParity intrinsics have essentially the same
// implementation. This macro will generate the function body given the
// intrinsic name.
#define GEN_IALL_IANY_IPARITY(F) \
mlir::Value fir::runtime::JOIN2(gen, F)( \
fir::FirOpBuilder & builder, mlir::Location loc, mlir::Value arrayBox, \
mlir::Value maskBox, mlir::Value resultBox) { \
mlir::func::FuncOp func; \
auto ty = arrayBox.getType(); \
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty); \
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType(); \
auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0); \
\
if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1))) \
func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 1))>(loc, builder); \
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2))) \
func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 2))>(loc, builder); \
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4))) \
func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 4))>(loc, builder); \
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8))) \
func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 8))>(loc, builder); \
else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16))) \
func = fir::runtime::getRuntimeFunc<JOIN3(Forced, F, 16)>(loc, builder); \
else \
fir::emitFatalError(loc, "invalid type in " STRINGIFY(F)); \
\
auto fTy = func.getFunctionType(); \
auto sourceFile = fir::factory::locationToFilename(builder, loc); \
auto sourceLine = \
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2)); \
auto args = fir::runtime::createArguments( \
builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox); \
\
return builder.create<fir::CallOp>(loc, func, args).getResult(0); \
}
/// Generate call to `IAllDim` intrinsic runtime routine. This is the version
/// that handles any rank array with the dim argument specified.
void fir::runtime::genIAllDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(IAllDim)>(loc, builder);
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
}
/// Generate call to `IAll` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
GEN_IALL_IANY_IPARITY(IAll)
/// Generate call to `IAnyDim` intrinsic runtime routine. This is the version
/// that handles any rank array with the dim argument specified.
void fir::runtime::genIAnyDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(IAnyDim)>(loc, builder);
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
}
/// Generate call to `IAny` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
GEN_IALL_IANY_IPARITY(IAny)
/// Generate call to `IParityDim` intrinsic runtime routine. This is the version
/// that handles any rank array with the dim argument specified.
void fir::runtime::genIParityDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value arrayBox,
mlir::Value dim, mlir::Value maskBox) {
auto func = fir::runtime::getRuntimeFunc<mkRTKey(IParityDim)>(loc, builder);
genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);
}
/// Generate call to `IParity` intrinsic runtime routine. This is the version
/// that does not take a dim argument.
GEN_IALL_IANY_IPARITY(IParity)
/// Generate call to `Reduce` intrinsic runtime routine. This is the version
/// that does not take a DIM argument and store result in the passed result
/// value.
void fir::runtime::genReduce(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value arrayBox, mlir::Value operation,
mlir::Value maskBox, mlir::Value identity,
mlir::Value ordered, mlir::Value resultBox,
bool argByRef) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1);
assert(resultBox && "expect non null value for the result");
assert((fir::isa_char(eleTy) || fir::isa_complex(eleTy) ||
fir::isa_derived(eleTy)) &&
"expect character, complex or derived-type");
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
if (argByRef) {
COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, Ref)
COMPLEX_INTRINSIC_INSTANCES(Reduce, Ref)
} else {
COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, Value)
COMPLEX_INTRINSIC_INSTANCES(Reduce, Value)
}
fir::factory::CharacterExprHelper charHelper{builder, loc};
if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar1)>(loc, builder);
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar2)>(loc, builder);
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4)
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar4)>(loc, builder);
else if (fir::isa_derived(eleTy))
func =
fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedType)>(loc, builder);
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(2), operation);
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine,
dim, maskBox, identity, ordered);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `Reduce` intrinsic runtime routine. This is the version
/// that does not take DIM argument and return a scalar result.
mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value arrayBox,
mlir::Value operation, mlir::Value maskBox,
mlir::Value identity, mlir::Value ordered,
bool argByRef) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1);
assert((fir::isa_real(eleTy) || fir::isa_integer(eleTy) ||
mlir::isa<fir::LogicalType>(eleTy)) &&
"expect real, interger or logical");
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
if (argByRef) {
REAL_2_3_INTRINSIC_INSTANCES(Reduce, Ref)
REAL_INTRINSIC_INSTANCES(Reduce, Ref)
INTEGER_INTRINSIC_INSTANCES(Reduce, Ref)
UNSIGNED_INTRINSIC_INSTANCES(Reduce, Ref)
LOGICAL_INTRINSIC_INSTANCES(Reduce, Ref)
} else {
REAL_2_3_INTRINSIC_INSTANCES(Reduce, Value)
REAL_INTRINSIC_INSTANCES(Reduce, Value)
INTEGER_INTRINSIC_INSTANCES(Reduce, Value)
UNSIGNED_INTRINSIC_INSTANCES(Reduce, Value)
LOGICAL_INTRINSIC_INSTANCES(Reduce, Value)
}
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(1), operation);
auto args = fir::runtime::createArguments(builder, loc, fTy, arrayBox, opAddr,
sourceFile, sourceLine, dim,
maskBox, identity, ordered);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
void fir::runtime::genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value arrayBox, mlir::Value operation,
mlir::Value dim, mlir::Value maskBox,
mlir::Value identity, mlir::Value ordered,
mlir::Value resultBox, bool argByRef) {
auto ty = arrayBox.getType();
auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);
auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();
auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);
mlir::func::FuncOp func;
if (argByRef) {
REAL_2_3_INTRINSIC_INSTANCES(Reduce, DimRef)
COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, DimRef)
NUMERICAL_AND_LOGICAL_INSTANCES(Reduce, DimRef)
} else {
REAL_2_3_INTRINSIC_INSTANCES(Reduce, DimValue)
COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, DimValue)
NUMERICAL_AND_LOGICAL_INSTANCES(Reduce, DimValue)
}
fir::factory::CharacterExprHelper charHelper{builder, loc};
if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter1Dim)>(loc,
builder);
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter2Dim)>(loc,
builder);
else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4)
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter4Dim)>(loc,
builder);
else if (fir::isa_derived(eleTy))
func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedTypeDim)>(loc,
builder);
if (!func)
fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(2), operation);
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine,
dim, maskBox, identity, ordered);
builder.create<fir::CallOp>(loc, func, args);
}