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