brintos

brintos / llvm-project-archived public Read only

0
0
Text · 87.7 KiB · 343d848 Raw
1924 lines · cpp
1//===-- Reduction.cpp -- generate reduction intrinsics runtime calls- -----===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Optimizer/Builder/Runtime/Reduction.h"10#include "flang/Optimizer/Builder/BoxValue.h"11#include "flang/Optimizer/Builder/Character.h"12#include "flang/Optimizer/Builder/FIRBuilder.h"13#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"14#include "flang/Optimizer/Support/Utils.h"15#include "flang/Runtime/reduce.h"16#include "flang/Runtime/reduction.h"17#include "mlir/Dialect/Func/IR/FuncOps.h"18 19using namespace Fortran::runtime;20 21#define STRINGIFY(S) #S22#define JOIN2(A, B) A##B23#define JOIN3(A, B, C) A##B##C24 25/// Placeholder for real*10 version of Maxval Intrinsic26struct ForcedMaxvalReal10 {27  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MaxvalReal10));28  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {29    return [](mlir::MLIRContext *ctx) {30      auto ty = mlir::Float80Type::get(ctx);31      auto boxTy =32          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);33      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));34      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));35      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},36                                     {ty});37    };38  }39};40 41/// Placeholder for real*16 version of Maxval Intrinsic42struct ForcedMaxvalReal16 {43  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MaxvalReal16));44  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {45    return [](mlir::MLIRContext *ctx) {46      auto ty = mlir::Float128Type::get(ctx);47      auto boxTy =48          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);49      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));50      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));51      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},52                                     {ty});53    };54  }55};56 57/// Placeholder for integer*16 version of Maxval Intrinsic58struct ForcedMaxvalInteger16 {59  static constexpr const char *name =60      ExpandAndQuoteKey(RTNAME(MaxvalInteger16));61  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {62    return [](mlir::MLIRContext *ctx) {63      auto ty = mlir::IntegerType::get(ctx, 128);64      auto boxTy =65          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);66      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));67      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));68      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},69                                     {ty});70    };71  }72};73 74/// Placeholder for unsigned*16 version of Maxval Intrinsic75struct ForcedMaxvalUnsigned16 {76  static constexpr const char *name =77      ExpandAndQuoteKey(RTNAME(MaxvalUnsigned16));78  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {79    return [](mlir::MLIRContext *ctx) {80      auto ty = mlir::IntegerType::get(81          ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);82      auto boxTy =83          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);84      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));85      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));86      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},87                                     {ty});88    };89  }90};91 92/// Placeholder for real*10 version of Minval Intrinsic93struct ForcedMinvalReal10 {94  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MinvalReal10));95  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {96    return [](mlir::MLIRContext *ctx) {97      auto ty = mlir::Float80Type::get(ctx);98      auto boxTy =99          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);100      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));101      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));102      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},103                                     {ty});104    };105  }106};107 108/// Placeholder for real*16 version of Minval Intrinsic109struct ForcedMinvalReal16 {110  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(MinvalReal16));111  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {112    return [](mlir::MLIRContext *ctx) {113      auto ty = mlir::Float128Type::get(ctx);114      auto boxTy =115          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);116      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));117      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));118      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},119                                     {ty});120    };121  }122};123 124/// Placeholder for integer*16 version of Minval Intrinsic125struct ForcedMinvalInteger16 {126  static constexpr const char *name =127      ExpandAndQuoteKey(RTNAME(MinvalInteger16));128  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {129    return [](mlir::MLIRContext *ctx) {130      auto ty = mlir::IntegerType::get(ctx, 128);131      auto boxTy =132          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);133      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));134      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));135      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},136                                     {ty});137    };138  }139};140 141/// Placeholder for unsigned*16 version of Minval Intrinsic142struct ForcedMinvalUnsigned16 {143  static constexpr const char *name =144      ExpandAndQuoteKey(RTNAME(MinvalUnsigned16));145  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {146    return [](mlir::MLIRContext *ctx) {147      auto ty = mlir::IntegerType::get(148          ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);149      auto boxTy =150          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);151      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));152      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));153      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},154                                     {ty});155    };156  }157};158 159// Maxloc/Minloc take descriptor, so these runtime signature are not ifdef160// and the mkRTKey can safely be used here. Define alias so that the161// REAL_INTRINSIC_INSTANCES macro works with them too162using ForcedMaxlocReal10 = mkRTKey(MaxlocReal10);163using ForcedMaxlocReal16 = mkRTKey(MaxlocReal16);164using ForcedMaxlocInteger16 = mkRTKey(MaxlocInteger16);165using ForcedMaxlocUnsigned16 = mkRTKey(MaxlocUnsigned16);166using ForcedMinlocReal10 = mkRTKey(MinlocReal10);167using ForcedMinlocReal16 = mkRTKey(MinlocReal16);168using ForcedMinlocInteger16 = mkRTKey(MinlocInteger16);169using ForcedMinlocUnsigned16 = mkRTKey(MinlocUnsigned16);170 171/// Placeholder for real*10 version of Norm2 Intrinsic172struct ForcedNorm2Real10 {173  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Norm2_10));174  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {175    return [](mlir::MLIRContext *ctx) {176      auto ty = mlir::Float80Type::get(ctx);177      auto boxTy =178          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);179      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));180      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));181      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy}, {ty});182    };183  }184};185 186/// Placeholder for real*16 version of Norm2 Intrinsic187struct ForcedNorm2Real16 {188  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Norm2_16));189  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {190    return [](mlir::MLIRContext *ctx) {191      auto ty = mlir::Float128Type::get(ctx);192      auto boxTy =193          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);194      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));195      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));196      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy}, {ty});197    };198  }199};200 201/// Placeholder for real*16 version of Norm2Dim Intrinsic202struct ForcedNorm2DimReal16 {203  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(Norm2DimReal16));204  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {205    return [](mlir::MLIRContext *ctx) {206      auto boxTy =207          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);208      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));209      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));210      return mlir::FunctionType::get(211          ctx, {fir::ReferenceType::get(boxTy), boxTy, intTy, strTy, intTy},212          {});213    };214  }215};216 217/// Placeholder for real*10 version of Product Intrinsic218struct ForcedProductReal10 {219  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ProductReal10));220  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {221    return [](mlir::MLIRContext *ctx) {222      auto ty = mlir::Float80Type::get(ctx);223      auto boxTy =224          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);225      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));226      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));227      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},228                                     {ty});229    };230  }231};232 233/// Placeholder for real*16 version of Product Intrinsic234struct ForcedProductReal16 {235  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(ProductReal16));236  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {237    return [](mlir::MLIRContext *ctx) {238      auto ty = mlir::Float128Type::get(ctx);239      auto boxTy =240          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);241      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));242      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));243      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},244                                     {ty});245    };246  }247};248 249/// Placeholder for integer*16 version of Product Intrinsic250struct ForcedProductInteger16 {251  static constexpr const char *name =252      ExpandAndQuoteKey(RTNAME(ProductInteger16));253  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {254    return [](mlir::MLIRContext *ctx) {255      auto ty = mlir::IntegerType::get(ctx, 128);256      auto boxTy =257          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);258      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));259      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));260      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},261                                     {ty});262    };263  }264};265 266/// Placeholder for unsigned*16 version of Product Intrinsic267struct ForcedProductUnsigned16 {268  static constexpr const char *name =269      ExpandAndQuoteKey(RTNAME(ProductUnsigned16));270  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {271    return [](mlir::MLIRContext *ctx) {272      auto ty = mlir::IntegerType::get(273          ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);274      auto boxTy =275          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);276      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));277      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));278      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},279                                     {ty});280    };281  }282};283 284/// Placeholder for complex(10) version of Product Intrinsic285struct ForcedProductComplex10 {286  static constexpr const char *name =287      ExpandAndQuoteKey(RTNAME(CppProductComplex10));288  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {289    return [](mlir::MLIRContext *ctx) {290      auto ty = mlir::ComplexType::get(mlir::Float80Type::get(ctx));291      auto boxTy =292          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);293      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));294      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));295      auto resTy = fir::ReferenceType::get(ty);296      return mlir::FunctionType::get(297          ctx, {resTy, boxTy, strTy, intTy, intTy, boxTy}, {});298    };299  }300};301 302/// Placeholder for complex(16) version of Product Intrinsic303struct ForcedProductComplex16 {304  static constexpr const char *name =305      ExpandAndQuoteKey(RTNAME(CppProductComplex16));306  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {307    return [](mlir::MLIRContext *ctx) {308      auto ty = mlir::ComplexType::get(mlir::Float128Type::get(ctx));309      auto boxTy =310          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);311      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));312      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));313      auto resTy = fir::ReferenceType::get(ty);314      return mlir::FunctionType::get(315          ctx, {resTy, boxTy, strTy, intTy, intTy, boxTy}, {});316    };317  }318};319 320/// Placeholder for real*10 version of DotProduct Intrinsic321struct ForcedDotProductReal10 {322  static constexpr const char *name =323      ExpandAndQuoteKey(RTNAME(DotProductReal10));324  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {325    return [](mlir::MLIRContext *ctx) {326      auto ty = mlir::Float80Type::get(ctx);327      auto boxTy =328          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);329      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));330      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));331      return mlir::FunctionType::get(ctx, {boxTy, boxTy, strTy, intTy}, {ty});332    };333  }334};335 336/// Placeholder for real*16 version of DotProduct Intrinsic337struct ForcedDotProductReal16 {338  static constexpr const char *name =339      ExpandAndQuoteKey(RTNAME(DotProductReal16));340  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {341    return [](mlir::MLIRContext *ctx) {342      auto ty = mlir::Float128Type::get(ctx);343      auto boxTy =344          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);345      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));346      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));347      return mlir::FunctionType::get(ctx, {boxTy, boxTy, strTy, intTy}, {ty});348    };349  }350};351 352/// Placeholder for complex(10) version of DotProduct Intrinsic353struct ForcedDotProductComplex10 {354  static constexpr const char *name =355      ExpandAndQuoteKey(RTNAME(CppDotProductComplex10));356  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {357    return [](mlir::MLIRContext *ctx) {358      auto ty = mlir::ComplexType::get(mlir::Float80Type::get(ctx));359      auto boxTy =360          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);361      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));362      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));363      auto resTy = fir::ReferenceType::get(ty);364      return mlir::FunctionType::get(ctx, {resTy, boxTy, boxTy, strTy, intTy},365                                     {});366    };367  }368};369 370/// Placeholder for complex(16) version of DotProduct Intrinsic371struct ForcedDotProductComplex16 {372  static constexpr const char *name =373      ExpandAndQuoteKey(RTNAME(CppDotProductComplex16));374  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {375    return [](mlir::MLIRContext *ctx) {376      auto ty = mlir::ComplexType::get(mlir::Float128Type::get(ctx));377      auto boxTy =378          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);379      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));380      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));381      auto resTy = fir::ReferenceType::get(ty);382      return mlir::FunctionType::get(ctx, {resTy, boxTy, boxTy, strTy, intTy},383                                     {});384    };385  }386};387 388/// Placeholder for integer*16 version of DotProduct Intrinsic389struct ForcedDotProductInteger16 {390  static constexpr const char *name =391      ExpandAndQuoteKey(RTNAME(DotProductInteger16));392  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {393    return [](mlir::MLIRContext *ctx) {394      auto ty = mlir::IntegerType::get(ctx, 128);395      auto boxTy =396          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);397      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));398      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));399      return mlir::FunctionType::get(ctx, {boxTy, boxTy, strTy, intTy}, {ty});400    };401  }402};403 404/// Placeholder for unsigned*16 version of DotProduct Intrinsic405struct ForcedDotProductUnsigned16 {406  static constexpr const char *name =407      ExpandAndQuoteKey(RTNAME(DotProductUnsigned16));408  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {409    return [](mlir::MLIRContext *ctx) {410      auto ty = mlir::IntegerType::get(411          ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);412      auto boxTy =413          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);414      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));415      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));416      return mlir::FunctionType::get(ctx, {boxTy, boxTy, strTy, intTy}, {ty});417    };418  }419};420 421/// Placeholder for real*10 version of Sum Intrinsic422struct ForcedSumReal10 {423  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SumReal10));424  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {425    return [](mlir::MLIRContext *ctx) {426      auto ty = mlir::Float80Type::get(ctx);427      auto boxTy =428          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);429      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));430      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));431      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},432                                     {ty});433    };434  }435};436 437/// Placeholder for real*16 version of Sum Intrinsic438struct ForcedSumReal16 {439  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SumReal16));440  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {441    return [](mlir::MLIRContext *ctx) {442      auto ty = mlir::Float128Type::get(ctx);443      auto boxTy =444          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);445      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));446      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));447      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},448                                     {ty});449    };450  }451};452 453/// Placeholder for integer*16 version of Sum Intrinsic454struct ForcedSumInteger16 {455  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SumInteger16));456  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {457    return [](mlir::MLIRContext *ctx) {458      auto ty = mlir::IntegerType::get(ctx, 128);459      auto boxTy =460          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);461      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));462      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));463      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},464                                     {ty});465    };466  }467};468 469/// Placeholder for unsigned*16 version of Sum Intrinsic470struct ForcedSumUnsigned16 {471  static constexpr const char *name = ExpandAndQuoteKey(RTNAME(SumUnsigned16));472  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {473    return [](mlir::MLIRContext *ctx) {474      auto ty = mlir::IntegerType::get(475          ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);476      auto boxTy =477          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);478      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));479      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));480      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},481                                     {ty});482    };483  }484};485 486/// Placeholder for complex(10) version of Sum Intrinsic487struct ForcedSumComplex10 {488  static constexpr const char *name =489      ExpandAndQuoteKey(RTNAME(CppSumComplex10));490  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {491    return [](mlir::MLIRContext *ctx) {492      auto ty = mlir::ComplexType::get(mlir::Float80Type::get(ctx));493      auto boxTy =494          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);495      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));496      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));497      auto resTy = fir::ReferenceType::get(ty);498      return mlir::FunctionType::get(499          ctx, {resTy, boxTy, strTy, intTy, intTy, boxTy}, {});500    };501  }502};503 504/// Placeholder for complex(16) version of Sum Intrinsic505struct ForcedSumComplex16 {506  static constexpr const char *name =507      ExpandAndQuoteKey(RTNAME(CppSumComplex16));508  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {509    return [](mlir::MLIRContext *ctx) {510      auto ty = mlir::ComplexType::get(mlir::Float128Type::get(ctx));511      auto boxTy =512          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);513      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));514      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));515      auto resTy = fir::ReferenceType::get(ty);516      return mlir::FunctionType::get(517          ctx, {resTy, boxTy, strTy, intTy, intTy, boxTy}, {});518    };519  }520};521 522/// Placeholder for integer(16) version of IAll Intrinsic523struct ForcedIAll16 {524  static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IAll16);525  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {526    return [](mlir::MLIRContext *ctx) {527      auto ty = mlir::IntegerType::get(ctx, 128);528      auto boxTy =529          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);530      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));531      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));532      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},533                                     {ty});534    };535  }536};537 538/// Placeholder for integer(16) version of IAny Intrinsic539struct ForcedIAny16 {540  static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IAny16);541  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {542    return [](mlir::MLIRContext *ctx) {543      auto ty = mlir::IntegerType::get(ctx, 128);544      auto boxTy =545          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);546      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));547      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));548      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},549                                     {ty});550    };551  }552};553 554/// Placeholder for integer(16) version of IParity Intrinsic555struct ForcedIParity16 {556  static constexpr const char *name = EXPAND_AND_QUOTE_KEY(IParity16);557  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {558    return [](mlir::MLIRContext *ctx) {559      auto ty = mlir::IntegerType::get(ctx, 128);560      auto boxTy =561          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);562      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));563      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));564      return mlir::FunctionType::get(ctx, {boxTy, strTy, intTy, intTy, boxTy},565                                     {ty});566    };567  }568};569 570/// Placeholder for real*10 version of Reduce Intrinsic571struct ForcedReduceReal10Ref {572  static constexpr const char *name =573      ExpandAndQuoteKey(RTNAME(ReduceReal10Ref));574  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {575    return [](mlir::MLIRContext *ctx) {576      auto ty = mlir::Float80Type::get(ctx);577      auto boxTy =578          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);579      auto refTy = fir::ReferenceType::get(ty);580      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);581      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));582      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));583      auto i1Ty = mlir::IntegerType::get(ctx, 1);584      return mlir::FunctionType::get(585          ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});586    };587  }588};589 590/// Placeholder for real*10 version of Reduce Intrinsic591struct ForcedReduceReal10Value {592  static constexpr const char *name =593      ExpandAndQuoteKey(RTNAME(ReduceReal10Value));594  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {595    return [](mlir::MLIRContext *ctx) {596      auto ty = mlir::Float80Type::get(ctx);597      auto boxTy =598          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);599      auto refTy = fir::ReferenceType::get(ty);600      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);601      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));602      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));603      auto i1Ty = mlir::IntegerType::get(ctx, 1);604      return mlir::FunctionType::get(605          ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});606    };607  }608};609 610/// Placeholder for real*16 version of Reduce Intrinsic611struct ForcedReduceReal16Ref {612  static constexpr const char *name =613      ExpandAndQuoteKey(RTNAME(ReduceReal16Ref));614  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {615    return [](mlir::MLIRContext *ctx) {616      auto ty = mlir::Float128Type::get(ctx);617      auto boxTy =618          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);619      auto refTy = fir::ReferenceType::get(ty);620      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);621      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));622      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));623      auto i1Ty = mlir::IntegerType::get(ctx, 1);624      return mlir::FunctionType::get(625          ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});626    };627  }628};629 630/// Placeholder for real*16 version of Reduce Intrinsic631struct ForcedReduceReal16Value {632  static constexpr const char *name =633      ExpandAndQuoteKey(RTNAME(ReduceReal16Value));634  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {635    return [](mlir::MLIRContext *ctx) {636      auto ty = mlir::Float128Type::get(ctx);637      auto boxTy =638          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);639      auto refTy = fir::ReferenceType::get(ty);640      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);641      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));642      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));643      auto i1Ty = mlir::IntegerType::get(ctx, 1);644      return mlir::FunctionType::get(645          ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});646    };647  }648};649 650/// Placeholder for DIM real*10 version of Reduce Intrinsic651struct ForcedReduceReal10DimRef {652  static constexpr const char *name =653      ExpandAndQuoteKey(RTNAME(ReduceReal10DimRef));654  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {655    return [](mlir::MLIRContext *ctx) {656      auto ty = mlir::Float80Type::get(ctx);657      auto boxTy =658          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);659      auto refTy = fir::ReferenceType::get(ty);660      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);661      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));662      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));663      auto refBoxTy = fir::ReferenceType::get(boxTy);664      auto i1Ty = mlir::IntegerType::get(ctx, 1);665      return mlir::FunctionType::get(666          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},667          {});668    };669  }670};671 672/// Placeholder for DIM real*10 with value version of Reduce Intrinsic673struct ForcedReduceReal10DimValue {674  static constexpr const char *name =675      ExpandAndQuoteKey(RTNAME(ReduceReal10DimValue));676  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {677    return [](mlir::MLIRContext *ctx) {678      auto ty = mlir::Float80Type::get(ctx);679      auto boxTy =680          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);681      auto refTy = fir::ReferenceType::get(ty);682      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);683      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));684      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));685      auto refBoxTy = fir::ReferenceType::get(boxTy);686      auto i1Ty = mlir::IntegerType::get(ctx, 1);687      return mlir::FunctionType::get(688          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},689          {});690    };691  }692};693 694/// Placeholder for DIM real*16 version of Reduce Intrinsic695struct ForcedReduceReal16DimRef {696  static constexpr const char *name =697      ExpandAndQuoteKey(RTNAME(ReduceReal16DimRef));698  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {699    return [](mlir::MLIRContext *ctx) {700      auto ty = mlir::Float128Type::get(ctx);701      auto boxTy =702          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);703      auto refTy = fir::ReferenceType::get(ty);704      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);705      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));706      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));707      auto refBoxTy = fir::ReferenceType::get(boxTy);708      auto i1Ty = mlir::IntegerType::get(ctx, 1);709      return mlir::FunctionType::get(710          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},711          {});712    };713  }714};715 716/// Placeholder for DIM real*16 with value version of Reduce Intrinsic717struct ForcedReduceReal16DimValue {718  static constexpr const char *name =719      ExpandAndQuoteKey(RTNAME(ReduceReal16DimValue));720  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {721    return [](mlir::MLIRContext *ctx) {722      auto ty = mlir::Float128Type::get(ctx);723      auto boxTy =724          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);725      auto refTy = fir::ReferenceType::get(ty);726      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);727      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));728      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));729      auto refBoxTy = fir::ReferenceType::get(boxTy);730      auto i1Ty = mlir::IntegerType::get(ctx, 1);731      return mlir::FunctionType::get(732          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},733          {});734    };735  }736};737 738/// Placeholder for integer*16 version of Reduce Intrinsic739struct ForcedReduceInteger16Ref {740  static constexpr const char *name =741      ExpandAndQuoteKey(RTNAME(ReduceInteger16Ref));742  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {743    return [](mlir::MLIRContext *ctx) {744      auto ty = mlir::IntegerType::get(ctx, 128);745      auto boxTy =746          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);747      auto refTy = fir::ReferenceType::get(ty);748      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);749      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));750      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));751      auto i1Ty = mlir::IntegerType::get(ctx, 1);752      return mlir::FunctionType::get(753          ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});754    };755  }756};757 758/// Placeholder for unsigned*16 version of Reduce Intrinsic759struct ForcedReduceUnsigned16Ref {760  static constexpr const char *name =761      ExpandAndQuoteKey(RTNAME(ReduceUnsigned16Ref));762  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {763    return [](mlir::MLIRContext *ctx) {764      auto ty = mlir::IntegerType::get(ctx, 128);765      auto boxTy =766          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);767      auto refTy = fir::ReferenceType::get(ty);768      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);769      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));770      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));771      auto i1Ty = mlir::IntegerType::get(ctx, 1);772      return mlir::FunctionType::get(773          ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});774    };775  }776};777 778/// Placeholder for integer*16 with value version of Reduce Intrinsic779struct ForcedReduceInteger16Value {780  static constexpr const char *name =781      ExpandAndQuoteKey(RTNAME(ReduceInteger16Value));782  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {783    return [](mlir::MLIRContext *ctx) {784      auto ty = mlir::IntegerType::get(ctx, 128);785      auto boxTy =786          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);787      auto refTy = fir::ReferenceType::get(ty);788      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);789      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));790      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));791      auto i1Ty = mlir::IntegerType::get(ctx, 1);792      return mlir::FunctionType::get(793          ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});794    };795  }796};797 798/// Placeholder for unsigned*16 with value version of Reduce Intrinsic799struct ForcedReduceUnsigned16Value {800  static constexpr const char *name =801      ExpandAndQuoteKey(RTNAME(ReduceUnsigned16Value));802  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {803    return [](mlir::MLIRContext *ctx) {804      auto ty = mlir::IntegerType::get(ctx, 128);805      auto boxTy =806          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);807      auto refTy = fir::ReferenceType::get(ty);808      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);809      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));810      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));811      auto i1Ty = mlir::IntegerType::get(ctx, 1);812      return mlir::FunctionType::get(813          ctx, {boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty}, {ty});814    };815  }816};817 818/// Placeholder for DIM integer*16 version of Reduce Intrinsic819struct ForcedReduceInteger16DimRef {820  static constexpr const char *name =821      ExpandAndQuoteKey(RTNAME(ReduceInteger16DimRef));822  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {823    return [](mlir::MLIRContext *ctx) {824      auto ty = mlir::IntegerType::get(ctx, 128);825      auto boxTy =826          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);827      auto refTy = fir::ReferenceType::get(ty);828      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);829      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));830      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));831      auto refBoxTy = fir::ReferenceType::get(boxTy);832      auto i1Ty = mlir::IntegerType::get(ctx, 1);833      return mlir::FunctionType::get(834          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},835          {});836    };837  }838};839 840/// Placeholder for DIM unsigned*16 version of Reduce Intrinsic841struct ForcedReduceUnsigned16DimRef {842  static constexpr const char *name =843      ExpandAndQuoteKey(RTNAME(ReduceUnsigned16DimRef));844  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {845    return [](mlir::MLIRContext *ctx) {846      auto ty = mlir::IntegerType::get(847          ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);848      auto boxTy =849          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);850      auto refTy = fir::ReferenceType::get(ty);851      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);852      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));853      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));854      auto refBoxTy = fir::ReferenceType::get(boxTy);855      auto i1Ty = mlir::IntegerType::get(ctx, 1);856      return mlir::FunctionType::get(857          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},858          {});859    };860  }861};862 863/// Placeholder for DIM integer*16 with value version of Reduce Intrinsic864struct ForcedReduceInteger16DimValue {865  static constexpr const char *name =866      ExpandAndQuoteKey(RTNAME(ReduceInteger16DimValue));867  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {868    return [](mlir::MLIRContext *ctx) {869      auto ty = mlir::IntegerType::get(ctx, 128);870      auto boxTy =871          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);872      auto refTy = fir::ReferenceType::get(ty);873      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);874      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));875      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));876      auto refBoxTy = fir::ReferenceType::get(boxTy);877      auto i1Ty = mlir::IntegerType::get(ctx, 1);878      return mlir::FunctionType::get(879          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},880          {});881    };882  }883};884 885/// Placeholder for DIM unsigned*16 with value version of Reduce Intrinsic886struct ForcedReduceUnsigned16DimValue {887  static constexpr const char *name =888      ExpandAndQuoteKey(RTNAME(ReduceUnsigned16DimValue));889  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {890    return [](mlir::MLIRContext *ctx) {891      auto ty = mlir::IntegerType::get(892          ctx, 128, mlir::IntegerType::SignednessSemantics::Unsigned);893      auto boxTy =894          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);895      auto refTy = fir::ReferenceType::get(ty);896      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);897      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));898      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));899      auto refBoxTy = fir::ReferenceType::get(boxTy);900      auto i1Ty = mlir::IntegerType::get(ctx, 1);901      return mlir::FunctionType::get(902          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},903          {});904    };905  }906};907 908/// Placeholder for complex(10) version of Reduce Intrinsic909struct ForcedReduceComplex10Ref {910  static constexpr const char *name =911      ExpandAndQuoteKey(RTNAME(CppReduceComplex10Ref));912  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {913    return [](mlir::MLIRContext *ctx) {914      auto ty = mlir::ComplexType::get(mlir::Float80Type::get(ctx));915      auto boxTy =916          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);917      auto refTy = fir::ReferenceType::get(ty);918      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);919      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));920      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));921      auto i1Ty = mlir::IntegerType::get(ctx, 1);922      return mlir::FunctionType::get(923          ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},924          {});925    };926  }927};928 929/// Placeholder for complex(10) with value version of Reduce Intrinsic930struct ForcedReduceComplex10Value {931  static constexpr const char *name =932      ExpandAndQuoteKey(RTNAME(CppReduceComplex10Value));933  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {934    return [](mlir::MLIRContext *ctx) {935      auto ty = mlir::ComplexType::get(mlir::Float80Type::get(ctx));936      auto boxTy =937          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);938      auto refTy = fir::ReferenceType::get(ty);939      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);940      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));941      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));942      auto i1Ty = mlir::IntegerType::get(ctx, 1);943      return mlir::FunctionType::get(944          ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},945          {});946    };947  }948};949 950/// Placeholder for Dim complex(10) version of Reduce Intrinsic951struct ForcedReduceComplex10DimRef {952  static constexpr const char *name =953      ExpandAndQuoteKey(RTNAME(CppReduceComplex10DimRef));954  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {955    return [](mlir::MLIRContext *ctx) {956      auto ty = mlir::ComplexType::get(mlir::Float80Type::get(ctx));957      auto boxTy =958          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);959      auto refTy = fir::ReferenceType::get(ty);960      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);961      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));962      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));963      auto refBoxTy = fir::ReferenceType::get(boxTy);964      auto i1Ty = mlir::IntegerType::get(ctx, 1);965      return mlir::FunctionType::get(966          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},967          {});968    };969  }970};971 972/// Placeholder for Dim complex(10) with value version of Reduce Intrinsic973struct ForcedReduceComplex10DimValue {974  static constexpr const char *name =975      ExpandAndQuoteKey(RTNAME(CppReduceComplex10DimValue));976  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {977    return [](mlir::MLIRContext *ctx) {978      auto ty = mlir::ComplexType::get(mlir::Float80Type::get(ctx));979      auto boxTy =980          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);981      auto refTy = fir::ReferenceType::get(ty);982      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);983      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));984      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));985      auto refBoxTy = fir::ReferenceType::get(boxTy);986      auto i1Ty = mlir::IntegerType::get(ctx, 1);987      return mlir::FunctionType::get(988          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},989          {});990    };991  }992};993 994/// Placeholder for complex(16) version of Reduce Intrinsic995struct ForcedReduceComplex16Ref {996  static constexpr const char *name =997      ExpandAndQuoteKey(RTNAME(CppReduceComplex16Ref));998  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {999    return [](mlir::MLIRContext *ctx) {1000      auto ty = mlir::ComplexType::get(mlir::Float128Type::get(ctx));1001      auto boxTy =1002          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);1003      auto refTy = fir::ReferenceType::get(ty);1004      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);1005      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));1006      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));1007      auto i1Ty = mlir::IntegerType::get(ctx, 1);1008      return mlir::FunctionType::get(1009          ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},1010          {});1011    };1012  }1013};1014 1015/// Placeholder for complex(16) with value version of Reduce Intrinsic1016struct ForcedReduceComplex16Value {1017  static constexpr const char *name =1018      ExpandAndQuoteKey(RTNAME(CppReduceComplex16Value));1019  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {1020    return [](mlir::MLIRContext *ctx) {1021      auto ty = mlir::ComplexType::get(mlir::Float128Type::get(ctx));1022      auto boxTy =1023          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);1024      auto refTy = fir::ReferenceType::get(ty);1025      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);1026      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));1027      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));1028      auto i1Ty = mlir::IntegerType::get(ctx, 1);1029      return mlir::FunctionType::get(1030          ctx, {refTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},1031          {});1032    };1033  }1034};1035 1036/// Placeholder for Dim complex(16) version of Reduce Intrinsic1037struct ForcedReduceComplex16DimRef {1038  static constexpr const char *name =1039      ExpandAndQuoteKey(RTNAME(CppReduceComplex16DimRef));1040  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {1041    return [](mlir::MLIRContext *ctx) {1042      auto ty = mlir::ComplexType::get(mlir::Float128Type::get(ctx));1043      auto boxTy =1044          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);1045      auto refTy = fir::ReferenceType::get(ty);1046      auto opTy = mlir::FunctionType::get(ctx, {refTy, refTy}, refTy);1047      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));1048      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));1049      auto refBoxTy = fir::ReferenceType::get(boxTy);1050      auto i1Ty = mlir::IntegerType::get(ctx, 1);1051      return mlir::FunctionType::get(1052          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},1053          {});1054    };1055  }1056};1057 1058/// Placeholder for Dim complex(16) with value version of Reduce Intrinsic1059struct ForcedReduceComplex16DimValue {1060  static constexpr const char *name =1061      ExpandAndQuoteKey(RTNAME(CppReduceComplex16DimValue));1062  static constexpr fir::runtime::FuncTypeBuilderFunc getTypeModel() {1063    return [](mlir::MLIRContext *ctx) {1064      auto ty = mlir::ComplexType::get(mlir::Float128Type::get(ctx));1065      auto boxTy =1066          fir::runtime::getModel<const Fortran::runtime::Descriptor &>()(ctx);1067      auto refTy = fir::ReferenceType::get(ty);1068      auto opTy = mlir::FunctionType::get(ctx, {ty, ty}, refTy);1069      auto strTy = fir::ReferenceType::get(mlir::IntegerType::get(ctx, 8));1070      auto intTy = mlir::IntegerType::get(ctx, 8 * sizeof(int));1071      auto refBoxTy = fir::ReferenceType::get(boxTy);1072      auto i1Ty = mlir::IntegerType::get(ctx, 1);1073      return mlir::FunctionType::get(1074          ctx, {refBoxTy, boxTy, opTy, strTy, intTy, intTy, boxTy, refTy, i1Ty},1075          {});1076    };1077  }1078};1079 1080#define INTRINSIC_INSTANCE(NAME, CAT, KIND, SUFFIX)                            \1081  if (!func && cat == TypeCategory::CAT && kind == KIND) {                     \1082    func = fir::runtime::getRuntimeFunc<mkRTKey(NAME##CAT##KIND##SUFFIX)>(     \1083        loc, builder);                                                         \1084  }1085#define FORCED_INTRINSIC_INSTANCE(NAME, CAT, KIND, SUFFIX)                     \1086  if (!func && cat == TypeCategory::CAT && kind == KIND) {                     \1087    func = fir::runtime::getRuntimeFunc<Forced##NAME##CAT##KIND##SUFFIX>(      \1088        loc, builder);                                                         \1089  }1090 1091#define INTEGER_INTRINSIC_INSTANCES(NAME, SUFFIX)                              \1092  INTRINSIC_INSTANCE(NAME, Integer, 1, SUFFIX)                                 \1093  INTRINSIC_INSTANCE(NAME, Integer, 2, SUFFIX)                                 \1094  INTRINSIC_INSTANCE(NAME, Integer, 4, SUFFIX)                                 \1095  INTRINSIC_INSTANCE(NAME, Integer, 8, SUFFIX)                                 \1096  FORCED_INTRINSIC_INSTANCE(NAME, Integer, 16, SUFFIX)1097 1098#define UNSIGNED_INTRINSIC_INSTANCES(NAME, SUFFIX)                             \1099  INTRINSIC_INSTANCE(NAME, Unsigned, 1, SUFFIX)                                \1100  INTRINSIC_INSTANCE(NAME, Unsigned, 2, SUFFIX)                                \1101  INTRINSIC_INSTANCE(NAME, Unsigned, 4, SUFFIX)                                \1102  INTRINSIC_INSTANCE(NAME, Unsigned, 8, SUFFIX)                                \1103  FORCED_INTRINSIC_INSTANCE(NAME, Unsigned, 16, SUFFIX)1104 1105#define REAL_INTRINSIC_INSTANCES(NAME, SUFFIX)                                 \1106  INTRINSIC_INSTANCE(NAME, Real, 4, SUFFIX)                                    \1107  INTRINSIC_INSTANCE(NAME, Real, 8, SUFFIX)                                    \1108  FORCED_INTRINSIC_INSTANCE(NAME, Real, 10, SUFFIX)                            \1109  FORCED_INTRINSIC_INSTANCE(NAME, Real, 16, SUFFIX)1110 1111#define COMPLEX_INTRINSIC_INSTANCES(NAME, SUFFIX)                              \1112  INTRINSIC_INSTANCE(Cpp##NAME, Complex, 4, SUFFIX)                            \1113  INTRINSIC_INSTANCE(Cpp##NAME, Complex, 8, SUFFIX)                            \1114  FORCED_INTRINSIC_INSTANCE(NAME, Complex, 10, SUFFIX)                         \1115  FORCED_INTRINSIC_INSTANCE(NAME, Complex, 16, SUFFIX)1116 1117#define NUMERICAL_INTRINSIC_INSTANCES(NAME)                                    \1118  INTEGER_INTRINSIC_INSTANCES(NAME, )                                          \1119  UNSIGNED_INTRINSIC_INSTANCES(NAME, )                                         \1120  REAL_INTRINSIC_INSTANCES(NAME, )                                             \1121  COMPLEX_INTRINSIC_INSTANCES(NAME, )1122 1123#define LOGICAL_INTRINSIC_INSTANCES(NAME, SUFFIX)                              \1124  INTRINSIC_INSTANCE(NAME, Logical, 1, SUFFIX)                                 \1125  INTRINSIC_INSTANCE(NAME, Logical, 2, SUFFIX)                                 \1126  INTRINSIC_INSTANCE(NAME, Logical, 4, SUFFIX)                                 \1127  INTRINSIC_INSTANCE(NAME, Logical, 8, SUFFIX)1128 1129#define NUMERICAL_AND_LOGICAL_INSTANCES(NAME, SUFFIX)                          \1130  INTEGER_INTRINSIC_INSTANCES(NAME, SUFFIX)                                    \1131  UNSIGNED_INTRINSIC_INSTANCES(NAME, SUFFIX)                                   \1132  REAL_INTRINSIC_INSTANCES(NAME, SUFFIX)                                       \1133  COMPLEX_INTRINSIC_INSTANCES(NAME, SUFFIX)                                    \1134  LOGICAL_INTRINSIC_INSTANCES(NAME, SUFFIX)1135 1136// REAL/COMPLEX 2 and 3 usually have no runtime implementation, so they have1137// special macros.1138#define REAL_2_3_INTRINSIC_INSTANCES(NAME, SUFFIX)                             \1139  INTRINSIC_INSTANCE(NAME, Real, 2, SUFFIX)                                    \1140  INTRINSIC_INSTANCE(NAME, Real, 3, SUFFIX)1141 1142#define COMPLEX_2_3_INTRINSIC_INSTANCES(NAME, SUFFIX)                          \1143  INTRINSIC_INSTANCE(Cpp##NAME, Complex, 2, SUFFIX)                            \1144  INTRINSIC_INSTANCE(Cpp##NAME, Complex, 3, SUFFIX)1145 1146/// Generate call to specialized runtime function that takes a mask and1147/// dim argument. The All, Any, and Count intrinsics use this pattern.1148template <typename FN>1149mlir::Value genSpecial2Args(FN func, fir::FirOpBuilder &builder,1150                            mlir::Location loc, mlir::Value maskBox,1151                            mlir::Value dim) {1152  auto fTy = func.getFunctionType();1153  auto sourceFile = fir::factory::locationToFilename(builder, loc);1154  auto sourceLine =1155      fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));1156  auto args = fir::runtime::createArguments(builder, loc, fTy, maskBox,1157                                            sourceFile, sourceLine, dim);1158  return fir::CallOp::create(builder, loc, func, args).getResult(0);1159}1160 1161/// Generate calls to reduction intrinsics such as All and Any.1162/// These are the descriptor based implementations that take two1163/// arguments (mask, dim).1164template <typename FN>1165static void genReduction2Args(FN func, fir::FirOpBuilder &builder,1166                              mlir::Location loc, mlir::Value resultBox,1167                              mlir::Value maskBox, mlir::Value dim) {1168  auto fTy = func.getFunctionType();1169  auto sourceFile = fir::factory::locationToFilename(builder, loc);1170  auto sourceLine =1171      fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));1172  auto args = fir::runtime::createArguments(1173      builder, loc, fTy, resultBox, maskBox, dim, sourceFile, sourceLine);1174  fir::CallOp::create(builder, loc, func, args);1175}1176 1177/// Generate calls to reduction intrinsics such as Maxval and Minval.1178/// These take arguments such as (array, dim, mask).1179template <typename FN>1180static void genReduction3Args(FN func, fir::FirOpBuilder &builder,1181                              mlir::Location loc, mlir::Value resultBox,1182                              mlir::Value arrayBox, mlir::Value dim,1183                              mlir::Value maskBox) {1184 1185  auto fTy = func.getFunctionType();1186  auto sourceFile = fir::factory::locationToFilename(builder, loc);1187  auto sourceLine =1188      fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));1189  auto args =1190      fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox, dim,1191                                    sourceFile, sourceLine, maskBox);1192  fir::CallOp::create(builder, loc, func, args);1193}1194 1195/// Generate calls to reduction intrinsics such as Maxloc and Minloc.1196/// These take arguments such as (array, mask, kind, back).1197template <typename FN>1198static void genReduction4Args(FN func, fir::FirOpBuilder &builder,1199                              mlir::Location loc, mlir::Value resultBox,1200                              mlir::Value arrayBox, mlir::Value maskBox,1201                              mlir::Value kind, mlir::Value back) {1202  auto fTy = func.getFunctionType();1203  auto sourceFile = fir::factory::locationToFilename(builder, loc);1204  auto sourceLine =1205      fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));1206  auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,1207                                            arrayBox, kind, sourceFile,1208                                            sourceLine, maskBox, back);1209  fir::CallOp::create(builder, loc, func, args);1210}1211 1212/// Generate calls to reduction intrinsics such as Maxloc and Minloc.1213/// These take arguments such as (array, dim, mask, kind, back).1214template <typename FN>1215static void1216genReduction5Args(FN func, fir::FirOpBuilder &builder, mlir::Location loc,1217                  mlir::Value resultBox, mlir::Value arrayBox, mlir::Value dim,1218                  mlir::Value maskBox, mlir::Value kind, mlir::Value back) {1219  auto fTy = func.getFunctionType();1220  auto sourceFile = fir::factory::locationToFilename(builder, loc);1221  auto sourceLine =1222      fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));1223  auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,1224                                            arrayBox, kind, dim, sourceFile,1225                                            sourceLine, maskBox, back);1226  fir::CallOp::create(builder, loc, func, args);1227}1228 1229/// Generate call to `AllDim` runtime routine.1230/// This calls the descriptor based runtime call implementation of the `all`1231/// intrinsic.1232void fir::runtime::genAllDescriptor(fir::FirOpBuilder &builder,1233                                    mlir::Location loc, mlir::Value resultBox,1234                                    mlir::Value maskBox, mlir::Value dim) {1235  auto allFunc = fir::runtime::getRuntimeFunc<mkRTKey(AllDim)>(loc, builder);1236  genReduction2Args(allFunc, builder, loc, resultBox, maskBox, dim);1237}1238 1239/// Generate call to `AnyDim` runtime routine.1240/// This calls the descriptor based runtime call implementation of the `any`1241/// intrinsic.1242void fir::runtime::genAnyDescriptor(fir::FirOpBuilder &builder,1243                                    mlir::Location loc, mlir::Value resultBox,1244                                    mlir::Value maskBox, mlir::Value dim) {1245  auto anyFunc = fir::runtime::getRuntimeFunc<mkRTKey(AnyDim)>(loc, builder);1246  genReduction2Args(anyFunc, builder, loc, resultBox, maskBox, dim);1247}1248 1249/// Generate call to `ParityDim` runtime routine.1250/// This calls the descriptor based runtime call implementation of the `parity`1251/// intrinsic.1252void fir::runtime::genParityDescriptor(fir::FirOpBuilder &builder,1253                                       mlir::Location loc,1254                                       mlir::Value resultBox,1255                                       mlir::Value maskBox, mlir::Value dim) {1256  auto parityFunc =1257      fir::runtime::getRuntimeFunc<mkRTKey(ParityDim)>(loc, builder);1258  genReduction2Args(parityFunc, builder, loc, resultBox, maskBox, dim);1259}1260 1261/// Generate call to `All` intrinsic runtime routine. This routine is1262/// specialized for mask arguments with rank == 1.1263mlir::Value fir::runtime::genAll(fir::FirOpBuilder &builder, mlir::Location loc,1264                                 mlir::Value maskBox, mlir::Value dim) {1265  auto allFunc = fir::runtime::getRuntimeFunc<mkRTKey(All)>(loc, builder);1266  return genSpecial2Args(allFunc, builder, loc, maskBox, dim);1267}1268 1269/// Generate call to `Any` intrinsic runtime routine. This routine is1270/// specialized for mask arguments with rank == 1.1271mlir::Value fir::runtime::genAny(fir::FirOpBuilder &builder, mlir::Location loc,1272                                 mlir::Value maskBox, mlir::Value dim) {1273  auto anyFunc = fir::runtime::getRuntimeFunc<mkRTKey(Any)>(loc, builder);1274  return genSpecial2Args(anyFunc, builder, loc, maskBox, dim);1275}1276 1277/// Generate call to `Count` runtime routine. This routine is a specialized1278/// version when mask is a rank one array or the dim argument is not1279/// specified by the user.1280mlir::Value fir::runtime::genCount(fir::FirOpBuilder &builder,1281                                   mlir::Location loc, mlir::Value maskBox,1282                                   mlir::Value dim) {1283  auto countFunc = fir::runtime::getRuntimeFunc<mkRTKey(Count)>(loc, builder);1284  return genSpecial2Args(countFunc, builder, loc, maskBox, dim);1285}1286 1287/// Generate call to general `CountDim` runtime routine. This routine has a1288/// descriptor result.1289void fir::runtime::genCountDim(fir::FirOpBuilder &builder, mlir::Location loc,1290                               mlir::Value resultBox, mlir::Value maskBox,1291                               mlir::Value dim, mlir::Value kind) {1292  auto func = fir::runtime::getRuntimeFunc<mkRTKey(CountDim)>(loc, builder);1293  auto fTy = func.getFunctionType();1294  auto sourceFile = fir::factory::locationToFilename(builder, loc);1295  auto sourceLine =1296      fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));1297  auto args = fir::runtime::createArguments(1298      builder, loc, fTy, resultBox, maskBox, dim, kind, sourceFile, sourceLine);1299  fir::CallOp::create(builder, loc, func, args);1300}1301 1302/// Generate call to `Findloc` intrinsic runtime routine. This is the version1303/// that does not take a dim argument.1304void fir::runtime::genFindloc(fir::FirOpBuilder &builder, mlir::Location loc,1305                              mlir::Value resultBox, mlir::Value arrayBox,1306                              mlir::Value valBox, mlir::Value maskBox,1307                              mlir::Value kind, mlir::Value back) {1308  auto func = fir::runtime::getRuntimeFunc<mkRTKey(Findloc)>(loc, builder);1309  auto fTy = func.getFunctionType();1310  auto sourceFile = fir::factory::locationToFilename(builder, loc);1311  auto sourceLine =1312      fir::factory::locationToLineNo(builder, loc, fTy.getInput(5));1313  auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox,1314                                            arrayBox, valBox, kind, sourceFile,1315                                            sourceLine, maskBox, back);1316  fir::CallOp::create(builder, loc, func, args);1317}1318 1319/// Generate call to `FindlocDim` intrinsic runtime routine. This is the version1320/// that takes a dim argument.1321void fir::runtime::genFindlocDim(fir::FirOpBuilder &builder, mlir::Location loc,1322                                 mlir::Value resultBox, mlir::Value arrayBox,1323                                 mlir::Value valBox, mlir::Value dim,1324                                 mlir::Value maskBox, mlir::Value kind,1325                                 mlir::Value back) {1326  auto func = fir::runtime::getRuntimeFunc<mkRTKey(FindlocDim)>(loc, builder);1327  auto fTy = func.getFunctionType();1328  auto sourceFile = fir::factory::locationToFilename(builder, loc);1329  auto sourceLine =1330      fir::factory::locationToLineNo(builder, loc, fTy.getInput(6));1331  auto args = fir::runtime::createArguments(1332      builder, loc, fTy, resultBox, arrayBox, valBox, kind, dim, sourceFile,1333      sourceLine, maskBox, back);1334  fir::CallOp::create(builder, loc, func, args);1335}1336 1337/// Generate call to `Maxloc` intrinsic runtime routine. This is the version1338/// that does not take a dim argument.1339void fir::runtime::genMaxloc(fir::FirOpBuilder &builder, mlir::Location loc,1340                             mlir::Value resultBox, mlir::Value arrayBox,1341                             mlir::Value maskBox, mlir::Value kindVal,1342                             mlir::Value back) {1343  auto ty = arrayBox.getType();1344  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1345  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1346  fir::factory::CharacterExprHelper charHelper{builder, loc};1347  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1348  mlir::func::FuncOp func;1349  REAL_INTRINSIC_INSTANCES(Maxloc, )1350  INTEGER_INTRINSIC_INSTANCES(Maxloc, )1351  UNSIGNED_INTRINSIC_INSTANCES(Maxloc, )1352  if (charHelper.isCharacterScalar(eleTy))1353    func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocCharacter)>(loc, builder);1354  if (!func)1355    fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXLOC");1356  genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kindVal,1357                    back);1358}1359 1360/// Generate call to `MaxlocDim` intrinsic runtime routine. This is the version1361/// that takes a dim argument.1362void fir::runtime::genMaxlocDim(fir::FirOpBuilder &builder, mlir::Location loc,1363                                mlir::Value resultBox, mlir::Value arrayBox,1364                                mlir::Value dim, mlir::Value maskBox,1365                                mlir::Value kind, mlir::Value back) {1366  auto func = fir::runtime::getRuntimeFunc<mkRTKey(MaxlocDim)>(loc, builder);1367  genReduction5Args(func, builder, loc, resultBox, arrayBox, dim, maskBox, kind,1368                    back);1369}1370 1371/// Generate call to `Maxval` intrinsic runtime routine. This is the version1372/// that does not take a dim argument.1373mlir::Value fir::runtime::genMaxval(fir::FirOpBuilder &builder,1374                                    mlir::Location loc, mlir::Value arrayBox,1375                                    mlir::Value maskBox) {1376  auto ty = arrayBox.getType();1377  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1378  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1379  auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);1380  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1381  mlir::func::FuncOp func;1382  REAL_INTRINSIC_INSTANCES(Maxval, )1383  INTEGER_INTRINSIC_INSTANCES(Maxval, )1384  UNSIGNED_INTRINSIC_INSTANCES(Maxval, )1385  if (!func)1386    fir::intrinsicTypeTODO(builder, eleTy, loc, "MAXVAL");1387 1388  auto fTy = func.getFunctionType();1389  auto sourceFile = fir::factory::locationToFilename(builder, loc);1390  auto sourceLine =1391      fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));1392  auto args = fir::runtime::createArguments(1393      builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);1394 1395  return fir::CallOp::create(builder, loc, func, args).getResult(0);1396}1397 1398/// Generate call to `MaxvalDim` intrinsic runtime routine. This is the version1399/// that handles any rank array with the dim argument specified.1400void fir::runtime::genMaxvalDim(fir::FirOpBuilder &builder, mlir::Location loc,1401                                mlir::Value resultBox, mlir::Value arrayBox,1402                                mlir::Value dim, mlir::Value maskBox) {1403  auto func = fir::runtime::getRuntimeFunc<mkRTKey(MaxvalDim)>(loc, builder);1404  genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);1405}1406 1407/// Generate call to `MaxvalCharacter` intrinsic runtime routine. This is the1408/// version that handles character arrays of rank 1 and without a DIM argument.1409void fir::runtime::genMaxvalChar(fir::FirOpBuilder &builder, mlir::Location loc,1410                                 mlir::Value resultBox, mlir::Value arrayBox,1411                                 mlir::Value maskBox) {1412  auto func =1413      fir::runtime::getRuntimeFunc<mkRTKey(MaxvalCharacter)>(loc, builder);1414  auto fTy = func.getFunctionType();1415  auto sourceFile = fir::factory::locationToFilename(builder, loc);1416  auto sourceLine =1417      fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));1418  auto args = fir::runtime::createArguments(1419      builder, loc, fTy, resultBox, arrayBox, sourceFile, sourceLine, maskBox);1420  fir::CallOp::create(builder, loc, func, args);1421}1422 1423/// Generate call to `Minloc` intrinsic runtime routine. This is the version1424/// that does not take a dim argument.1425void fir::runtime::genMinloc(fir::FirOpBuilder &builder, mlir::Location loc,1426                             mlir::Value resultBox, mlir::Value arrayBox,1427                             mlir::Value maskBox, mlir::Value kindVal,1428                             mlir::Value back) {1429  auto ty = arrayBox.getType();1430  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1431  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1432  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1433  mlir::func::FuncOp func;1434  REAL_INTRINSIC_INSTANCES(Minloc, )1435  INTEGER_INTRINSIC_INSTANCES(Minloc, )1436  UNSIGNED_INTRINSIC_INSTANCES(Minloc, )1437  fir::factory::CharacterExprHelper charHelper{builder, loc};1438  if (charHelper.isCharacterScalar(eleTy))1439    func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocCharacter)>(loc, builder);1440  if (!func)1441    fir::intrinsicTypeTODO(builder, eleTy, loc, "MINLOC");1442  genReduction4Args(func, builder, loc, resultBox, arrayBox, maskBox, kindVal,1443                    back);1444}1445 1446/// Generate call to `MinlocDim` intrinsic runtime routine. This is the version1447/// that takes a dim argument.1448void fir::runtime::genMinlocDim(fir::FirOpBuilder &builder, mlir::Location loc,1449                                mlir::Value resultBox, mlir::Value arrayBox,1450                                mlir::Value dim, mlir::Value maskBox,1451                                mlir::Value kind, mlir::Value back) {1452  auto func = fir::runtime::getRuntimeFunc<mkRTKey(MinlocDim)>(loc, builder);1453  genReduction5Args(func, builder, loc, resultBox, arrayBox, dim, maskBox, kind,1454                    back);1455}1456 1457/// Generate call to `MinvalDim` intrinsic runtime routine. This is the version1458/// that handles any rank array with the dim argument specified.1459void fir::runtime::genMinvalDim(fir::FirOpBuilder &builder, mlir::Location loc,1460                                mlir::Value resultBox, mlir::Value arrayBox,1461                                mlir::Value dim, mlir::Value maskBox) {1462  auto func = fir::runtime::getRuntimeFunc<mkRTKey(MinvalDim)>(loc, builder);1463  genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);1464}1465 1466/// Generate call to `MinvalCharacter` intrinsic runtime routine. This is the1467/// version that handles character arrays of rank 1 and without a DIM argument.1468void fir::runtime::genMinvalChar(fir::FirOpBuilder &builder, mlir::Location loc,1469                                 mlir::Value resultBox, mlir::Value arrayBox,1470                                 mlir::Value maskBox) {1471  auto func =1472      fir::runtime::getRuntimeFunc<mkRTKey(MinvalCharacter)>(loc, builder);1473  auto fTy = func.getFunctionType();1474  auto sourceFile = fir::factory::locationToFilename(builder, loc);1475  auto sourceLine =1476      fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));1477  auto args = fir::runtime::createArguments(1478      builder, loc, fTy, resultBox, arrayBox, sourceFile, sourceLine, maskBox);1479  fir::CallOp::create(builder, loc, func, args);1480}1481 1482/// Generate call to `Minval` intrinsic runtime routine. This is the version1483/// that does not take a dim argument.1484mlir::Value fir::runtime::genMinval(fir::FirOpBuilder &builder,1485                                    mlir::Location loc, mlir::Value arrayBox,1486                                    mlir::Value maskBox) {1487  auto ty = arrayBox.getType();1488  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1489  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1490  auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);1491  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1492 1493  mlir::func::FuncOp func;1494  REAL_INTRINSIC_INSTANCES(Minval, )1495  INTEGER_INTRINSIC_INSTANCES(Minval, )1496  UNSIGNED_INTRINSIC_INSTANCES(Minval, )1497  if (!func)1498    fir::intrinsicTypeTODO(builder, eleTy, loc, "MINVAL");1499 1500  auto fTy = func.getFunctionType();1501  auto sourceFile = fir::factory::locationToFilename(builder, loc);1502  auto sourceLine =1503      fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));1504  auto args = fir::runtime::createArguments(1505      builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);1506 1507  return fir::CallOp::create(builder, loc, func, args).getResult(0);1508}1509 1510/// Generate call to `Norm2Dim` intrinsic runtime routine. This is the version1511/// that takes a dim argument.1512void fir::runtime::genNorm2Dim(fir::FirOpBuilder &builder, mlir::Location loc,1513                               mlir::Value resultBox, mlir::Value arrayBox,1514                               mlir::Value dim) {1515  mlir::func::FuncOp func;1516  auto ty = arrayBox.getType();1517  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1518  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1519  if (eleTy.isF128())1520    func = fir::runtime::getRuntimeFunc<ForcedNorm2DimReal16>(loc, builder);1521  else1522    func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2Dim)>(loc, builder);1523  auto fTy = func.getFunctionType();1524  auto sourceFile = fir::factory::locationToFilename(builder, loc);1525  auto sourceLine =1526      fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));1527  auto args = fir::runtime::createArguments(1528      builder, loc, fTy, resultBox, arrayBox, dim, sourceFile, sourceLine);1529 1530  fir::CallOp::create(builder, loc, func, args);1531}1532 1533/// Generate call to `Norm2` intrinsic runtime routine. This is the version1534/// that does not take a dim argument.1535mlir::Value fir::runtime::genNorm2(fir::FirOpBuilder &builder,1536                                   mlir::Location loc, mlir::Value arrayBox) {1537  mlir::func::FuncOp func;1538  auto ty = arrayBox.getType();1539  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1540  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1541  auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);1542 1543  if (eleTy.isF32())1544    func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2_4)>(loc, builder);1545  else if (eleTy.isF64())1546    func = fir::runtime::getRuntimeFunc<mkRTKey(Norm2_8)>(loc, builder);1547  else if (eleTy.isF80())1548    func = fir::runtime::getRuntimeFunc<ForcedNorm2Real10>(loc, builder);1549  else if (eleTy.isF128())1550    func = fir::runtime::getRuntimeFunc<ForcedNorm2Real16>(loc, builder);1551  else1552    fir::intrinsicTypeTODO(builder, eleTy, loc, "NORM2");1553 1554  auto fTy = func.getFunctionType();1555  auto sourceFile = fir::factory::locationToFilename(builder, loc);1556  auto sourceLine =1557      fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));1558  auto args = fir::runtime::createArguments(builder, loc, fTy, arrayBox,1559                                            sourceFile, sourceLine, dim);1560 1561  return fir::CallOp::create(builder, loc, func, args).getResult(0);1562}1563 1564/// Generate call to `Parity` intrinsic runtime routine. This routine is1565/// specialized for mask arguments with rank == 1.1566mlir::Value fir::runtime::genParity(fir::FirOpBuilder &builder,1567                                    mlir::Location loc, mlir::Value maskBox,1568                                    mlir::Value dim) {1569  auto parityFunc = fir::runtime::getRuntimeFunc<mkRTKey(Parity)>(loc, builder);1570  return genSpecial2Args(parityFunc, builder, loc, maskBox, dim);1571}1572 1573/// Generate call to `ProductDim` intrinsic runtime routine. This is the version1574/// that handles any rank array with the dim argument specified.1575void fir::runtime::genProductDim(fir::FirOpBuilder &builder, mlir::Location loc,1576                                 mlir::Value resultBox, mlir::Value arrayBox,1577                                 mlir::Value dim, mlir::Value maskBox) {1578  auto func = fir::runtime::getRuntimeFunc<mkRTKey(ProductDim)>(loc, builder);1579  genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);1580}1581 1582/// Generate call to `Product` intrinsic runtime routine. This is the version1583/// that does not take a dim argument.1584mlir::Value fir::runtime::genProduct(fir::FirOpBuilder &builder,1585                                     mlir::Location loc, mlir::Value arrayBox,1586                                     mlir::Value maskBox,1587                                     mlir::Value resultBox) {1588  auto ty = arrayBox.getType();1589  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1590  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1591  auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);1592 1593  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1594  mlir::func::FuncOp func;1595  NUMERICAL_INTRINSIC_INSTANCES(Product)1596  if (!func)1597    fir::intrinsicTypeTODO(builder, eleTy, loc, "PRODUCT");1598 1599  auto fTy = func.getFunctionType();1600  auto sourceFile = fir::factory::locationToFilename(builder, loc);1601  if (fir::isa_complex(eleTy)) {1602    auto sourceLine =1603        fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));1604    auto args =1605        fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,1606                                      sourceFile, sourceLine, dim, maskBox);1607    fir::CallOp::create(builder, loc, func, args);1608    return resultBox;1609  }1610 1611  auto sourceLine =1612      fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));1613  auto args = fir::runtime::createArguments(1614      builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);1615 1616  return fir::CallOp::create(builder, loc, func, args).getResult(0);1617}1618 1619/// Generate call to `DotProduct` intrinsic runtime routine.1620mlir::Value fir::runtime::genDotProduct(fir::FirOpBuilder &builder,1621                                        mlir::Location loc,1622                                        mlir::Value vectorABox,1623                                        mlir::Value vectorBBox,1624                                        mlir::Value resultBox) {1625  // For complex data types, resultBox is !fir.ref<!fir.complex<N>>,1626  // otherwise it is !fir.box<T>.1627  auto ty = resultBox.getType();1628  auto eleTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1629 1630  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1631  mlir::func::FuncOp func;1632  NUMERICAL_INTRINSIC_INSTANCES(DotProduct)1633  if (cat == Fortran::common::TypeCategory::Logical)1634    func =1635        fir::runtime::getRuntimeFunc<mkRTKey(DotProductLogical)>(loc, builder);1636  if (!func)1637    fir::intrinsicTypeTODO(builder, eleTy, loc, "DOTPRODUCT");1638 1639  auto fTy = func.getFunctionType();1640  auto sourceFile = fir::factory::locationToFilename(builder, loc);1641 1642  if (fir::isa_complex(eleTy)) {1643    auto sourceLine =1644        fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));1645    auto args =1646        fir::runtime::createArguments(builder, loc, fTy, resultBox, vectorABox,1647                                      vectorBBox, sourceFile, sourceLine);1648    fir::CallOp::create(builder, loc, func, args);1649    return resultBox;1650  }1651 1652  auto sourceLine =1653      fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));1654  auto args = fir::runtime::createArguments(builder, loc, fTy, vectorABox,1655                                            vectorBBox, sourceFile, sourceLine);1656  return fir::CallOp::create(builder, loc, func, args).getResult(0);1657}1658/// Generate call to `SumDim` intrinsic runtime routine. This is the version1659/// that handles any rank array with the dim argument specified.1660void fir::runtime::genSumDim(fir::FirOpBuilder &builder, mlir::Location loc,1661                             mlir::Value resultBox, mlir::Value arrayBox,1662                             mlir::Value dim, mlir::Value maskBox) {1663  auto func = fir::runtime::getRuntimeFunc<mkRTKey(SumDim)>(loc, builder);1664  genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);1665}1666 1667/// Generate call to `Sum` intrinsic runtime routine. This is the version1668/// that does not take a dim argument.1669mlir::Value fir::runtime::genSum(fir::FirOpBuilder &builder, mlir::Location loc,1670                                 mlir::Value arrayBox, mlir::Value maskBox,1671                                 mlir::Value resultBox) {1672  auto ty = arrayBox.getType();1673  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1674  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1675  auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);1676 1677  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1678  mlir::func::FuncOp func;1679  NUMERICAL_INTRINSIC_INSTANCES(Sum)1680  if (!func)1681    fir::intrinsicTypeTODO(builder, eleTy, loc, "SUM");1682 1683  auto fTy = func.getFunctionType();1684  auto sourceFile = fir::factory::locationToFilename(builder, loc);1685  if (fir::isa_complex(eleTy)) {1686    auto sourceLine =1687        fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));1688    auto args =1689        fir::runtime::createArguments(builder, loc, fTy, resultBox, arrayBox,1690                                      sourceFile, sourceLine, dim, maskBox);1691    fir::CallOp::create(builder, loc, func, args);1692    return resultBox;1693  }1694 1695  auto sourceLine =1696      fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));1697  auto args = fir::runtime::createArguments(1698      builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);1699 1700  return fir::CallOp::create(builder, loc, func, args).getResult(0);1701}1702 1703// The IAll, IAny and IParity intrinsics have essentially the same1704// implementation. This macro will generate the function body given the1705// intrinsic name.1706#define GEN_IALL_IANY_IPARITY(F)                                               \1707  mlir::Value fir::runtime::JOIN2(gen, F)(                                     \1708      fir::FirOpBuilder & builder, mlir::Location loc, mlir::Value arrayBox,   \1709      mlir::Value maskBox, mlir::Value resultBox) {                            \1710    mlir::func::FuncOp func;                                                   \1711    auto ty = arrayBox.getType();                                              \1712    auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);                              \1713    auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();        \1714    auto dim = builder.createIntegerConstant(loc, builder.getIndexType(), 0);  \1715                                                                               \1716    if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(1)))            \1717      func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 1))>(loc, builder); \1718    else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(2)))       \1719      func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 2))>(loc, builder); \1720    else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(4)))       \1721      func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 4))>(loc, builder); \1722    else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(8)))       \1723      func = fir::runtime::getRuntimeFunc<mkRTKey(JOIN2(F, 8))>(loc, builder); \1724    else if (eleTy.isInteger(builder.getKindMap().getIntegerBitsize(16)))      \1725      func = fir::runtime::getRuntimeFunc<JOIN3(Forced, F, 16)>(loc, builder); \1726    else                                                                       \1727      fir::emitFatalError(loc, "invalid type in " STRINGIFY(F));               \1728                                                                               \1729    auto fTy = func.getFunctionType();                                         \1730    auto sourceFile = fir::factory::locationToFilename(builder, loc);          \1731    auto sourceLine =                                                          \1732        fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));         \1733    auto args = fir::runtime::createArguments(                                 \1734        builder, loc, fTy, arrayBox, sourceFile, sourceLine, dim, maskBox);    \1735                                                                               \1736    return fir::CallOp::create(builder, loc, func, args).getResult(0);         \1737  }1738 1739/// Generate call to `IAllDim` intrinsic runtime routine. This is the version1740/// that handles any rank array with the dim argument specified.1741void fir::runtime::genIAllDim(fir::FirOpBuilder &builder, mlir::Location loc,1742                              mlir::Value resultBox, mlir::Value arrayBox,1743                              mlir::Value dim, mlir::Value maskBox) {1744  auto func = fir::runtime::getRuntimeFunc<mkRTKey(IAllDim)>(loc, builder);1745  genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);1746}1747 1748/// Generate call to `IAll` intrinsic runtime routine. This is the version1749/// that does not take a dim argument.1750GEN_IALL_IANY_IPARITY(IAll)1751 1752/// Generate call to `IAnyDim` intrinsic runtime routine. This is the version1753/// that handles any rank array with the dim argument specified.1754void fir::runtime::genIAnyDim(fir::FirOpBuilder &builder, mlir::Location loc,1755                              mlir::Value resultBox, mlir::Value arrayBox,1756                              mlir::Value dim, mlir::Value maskBox) {1757  auto func = fir::runtime::getRuntimeFunc<mkRTKey(IAnyDim)>(loc, builder);1758  genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);1759}1760 1761/// Generate call to `IAny` intrinsic runtime routine. This is the version1762/// that does not take a dim argument.1763GEN_IALL_IANY_IPARITY(IAny)1764 1765/// Generate call to `IParityDim` intrinsic runtime routine. This is the version1766/// that handles any rank array with the dim argument specified.1767void fir::runtime::genIParityDim(fir::FirOpBuilder &builder, mlir::Location loc,1768                                 mlir::Value resultBox, mlir::Value arrayBox,1769                                 mlir::Value dim, mlir::Value maskBox) {1770  auto func = fir::runtime::getRuntimeFunc<mkRTKey(IParityDim)>(loc, builder);1771  genReduction3Args(func, builder, loc, resultBox, arrayBox, dim, maskBox);1772}1773 1774/// Generate call to `IParity` intrinsic runtime routine. This is the version1775/// that does not take a dim argument.1776GEN_IALL_IANY_IPARITY(IParity)1777 1778/// Generate call to `Reduce` intrinsic runtime routine. This is the version1779/// that does not take a DIM argument and store result in the passed result1780/// value.1781void fir::runtime::genReduce(fir::FirOpBuilder &builder, mlir::Location loc,1782                             mlir::Value arrayBox, mlir::Value operation,1783                             mlir::Value maskBox, mlir::Value identity,1784                             mlir::Value ordered, mlir::Value resultBox,1785                             bool argByRef) {1786  auto ty = arrayBox.getType();1787  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1788  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1789  auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1);1790 1791  assert(resultBox && "expect non null value for the result");1792  assert((fir::isa_char(eleTy) || fir::isa_complex(eleTy) ||1793          fir::isa_derived(eleTy)) &&1794         "expect character, complex or derived-type");1795 1796  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1797  mlir::func::FuncOp func;1798  if (argByRef) {1799    COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, Ref)1800    COMPLEX_INTRINSIC_INSTANCES(Reduce, Ref)1801  } else {1802    COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, Value)1803    COMPLEX_INTRINSIC_INSTANCES(Reduce, Value)1804  }1805  fir::factory::CharacterExprHelper charHelper{builder, loc};1806  if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)1807    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar1)>(loc, builder);1808  else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)1809    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar2)>(loc, builder);1810  else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4)1811    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceChar4)>(loc, builder);1812  else if (fir::isa_derived(eleTy))1813    func =1814        fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedType)>(loc, builder);1815  if (!func)1816    fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");1817 1818  auto fTy = func.getFunctionType();1819  auto sourceFile = fir::factory::locationToFilename(builder, loc);1820  auto sourceLine =1821      fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));1822  auto opAddr =1823      fir::BoxAddrOp::create(builder, loc, fTy.getInput(2), operation);1824  auto args = fir::runtime::createArguments(1825      builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine,1826      dim, maskBox, identity, ordered);1827  fir::CallOp::create(builder, loc, func, args);1828}1829 1830/// Generate call to `Reduce` intrinsic runtime routine. This is the version1831/// that does not take DIM argument and return a scalar result.1832mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder,1833                                    mlir::Location loc, mlir::Value arrayBox,1834                                    mlir::Value operation, mlir::Value maskBox,1835                                    mlir::Value identity, mlir::Value ordered,1836                                    bool argByRef) {1837  auto ty = arrayBox.getType();1838  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1839  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1840  auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1);1841 1842  assert((fir::isa_real(eleTy) || fir::isa_integer(eleTy) ||1843          mlir::isa<fir::LogicalType>(eleTy)) &&1844         "expect real, integer or logical");1845 1846  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1847  mlir::func::FuncOp func;1848  if (argByRef) {1849    REAL_2_3_INTRINSIC_INSTANCES(Reduce, Ref)1850    REAL_INTRINSIC_INSTANCES(Reduce, Ref)1851    INTEGER_INTRINSIC_INSTANCES(Reduce, Ref)1852    UNSIGNED_INTRINSIC_INSTANCES(Reduce, Ref)1853    LOGICAL_INTRINSIC_INSTANCES(Reduce, Ref)1854  } else {1855    REAL_2_3_INTRINSIC_INSTANCES(Reduce, Value)1856    REAL_INTRINSIC_INSTANCES(Reduce, Value)1857    INTEGER_INTRINSIC_INSTANCES(Reduce, Value)1858    UNSIGNED_INTRINSIC_INSTANCES(Reduce, Value)1859    LOGICAL_INTRINSIC_INSTANCES(Reduce, Value)1860  }1861  if (!func)1862    fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");1863 1864  auto fTy = func.getFunctionType();1865  auto sourceFile = fir::factory::locationToFilename(builder, loc);1866  auto sourceLine =1867      fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));1868  auto opAddr =1869      fir::BoxAddrOp::create(builder, loc, fTy.getInput(1), operation);1870  auto args = fir::runtime::createArguments(builder, loc, fTy, arrayBox, opAddr,1871                                            sourceFile, sourceLine, dim,1872                                            maskBox, identity, ordered);1873  return fir::CallOp::create(builder, loc, func, args).getResult(0);1874}1875 1876void fir::runtime::genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc,1877                                mlir::Value arrayBox, mlir::Value operation,1878                                mlir::Value dim, mlir::Value maskBox,1879                                mlir::Value identity, mlir::Value ordered,1880                                mlir::Value resultBox, bool argByRef) {1881  auto ty = arrayBox.getType();1882  auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty);1883  auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType();1884  auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy);1885 1886  mlir::func::FuncOp func;1887  if (argByRef) {1888    REAL_2_3_INTRINSIC_INSTANCES(Reduce, DimRef)1889    COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, DimRef)1890    NUMERICAL_AND_LOGICAL_INSTANCES(Reduce, DimRef)1891  } else {1892    REAL_2_3_INTRINSIC_INSTANCES(Reduce, DimValue)1893    COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, DimValue)1894    NUMERICAL_AND_LOGICAL_INSTANCES(Reduce, DimValue)1895  }1896  fir::factory::CharacterExprHelper charHelper{builder, loc};1897  if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1)1898    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter1Dim)>(loc,1899                                                                      builder);1900  else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2)1901    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter2Dim)>(loc,1902                                                                      builder);1903  else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4)1904    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter4Dim)>(loc,1905                                                                      builder);1906  else if (fir::isa_derived(eleTy))1907    func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedTypeDim)>(loc,1908                                                                       builder);1909  if (!func)1910    fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE");1911 1912  auto fTy = func.getFunctionType();1913  auto sourceFile = fir::factory::locationToFilename(builder, loc);1914 1915  auto sourceLine =1916      fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));1917  auto opAddr =1918      fir::BoxAddrOp::create(builder, loc, fTy.getInput(2), operation);1919  auto args = fir::runtime::createArguments(1920      builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine,1921      dim, maskBox, identity, ordered);1922  fir::CallOp::create(builder, loc, func, args);1923}1924