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-exception 6 // 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 19 using namespace Fortran::runtime; 20 21 #define STRINGIFY(S) #S 22 #define JOIN2(A, B) A##B 23 #define JOIN3(A, B, C) A##B##C 24 25 /// Placeholder for real*10 version of Maxval Intrinsic 26 struct 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 Intrinsic 42 struct 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 Intrinsic 58 struct 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 Intrinsic 75 struct 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 Intrinsic 93 struct 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 Intrinsic 109 struct 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 Intrinsic 125 struct 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 Intrinsic 142 struct 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 ifdef 160 // and the mkRTKey can safely be used here. Define alias so that the 161 // REAL_INTRINSIC_INSTANCES macro works with them too 162 using ForcedMaxlocReal10 = mkRTKey(MaxlocReal10); 163 using ForcedMaxlocReal16 = mkRTKey(MaxlocReal16); 164 using ForcedMaxlocInteger16 = mkRTKey(MaxlocInteger16); 165 using ForcedMaxlocUnsigned16 = mkRTKey(MaxlocUnsigned16); 166 using ForcedMinlocReal10 = mkRTKey(MinlocReal10); 167 using ForcedMinlocReal16 = mkRTKey(MinlocReal16); 168 using ForcedMinlocInteger16 = mkRTKey(MinlocInteger16); 169 using ForcedMinlocUnsigned16 = mkRTKey(MinlocUnsigned16); 170 171 /// Placeholder for real*10 version of Norm2 Intrinsic 172 struct 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 Intrinsic 187 struct 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 Intrinsic 202 struct 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 Intrinsic 218 struct 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 Intrinsic 234 struct 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 Intrinsic 250 struct 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 Intrinsic 267 struct 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 Intrinsic 285 struct 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 Intrinsic 303 struct 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 Intrinsic 321 struct 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 Intrinsic 337 struct 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 Intrinsic 353 struct 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 Intrinsic 371 struct 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 Intrinsic 389 struct 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 Intrinsic 405 struct 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 Intrinsic 422 struct 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 Intrinsic 438 struct 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 Intrinsic 454 struct 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 Intrinsic 470 struct 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 Intrinsic 487 struct 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 Intrinsic 505 struct 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 Intrinsic 523 struct 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 Intrinsic 539 struct 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 Intrinsic 555 struct 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 Intrinsic 571 struct 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 Intrinsic 591 struct 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 Intrinsic 611 struct 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 Intrinsic 631 struct 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 Intrinsic 651 struct 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 Intrinsic 673 struct 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 Intrinsic 695 struct 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 Intrinsic 717 struct 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 Intrinsic 739 struct 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 Intrinsic 759 struct 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 Intrinsic 779 struct 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 Intrinsic 799 struct 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 Intrinsic 819 struct 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 Intrinsic 841 struct 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 Intrinsic 864 struct 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 Intrinsic 886 struct 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 Intrinsic 909 struct 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 Intrinsic 930 struct 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 Intrinsic 951 struct 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 Intrinsic 973 struct 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 Intrinsic 995 struct 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 Intrinsic 1016 struct 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 Intrinsic 1037 struct 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 Intrinsic 1059 struct 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 have 1137 // 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 and 1147 /// dim argument. The All, Any, and Count intrinsics use this pattern. 1148 template <typename FN> 1149 mlir::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 builder.create<fir::CallOp>(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 two 1163 /// arguments (mask, dim). 1164 template <typename FN> 1165 static 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 builder.create<fir::CallOp>(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). 1179 template <typename FN> 1180 static 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 builder.create<fir::CallOp>(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). 1197 template <typename FN> 1198 static 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 builder.create<fir::CallOp>(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). 1214 template <typename FN> 1215 static void 1216 genReduction5Args(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 builder.create<fir::CallOp>(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. 1232 void 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. 1242 void 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. 1252 void 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 is 1262 /// specialized for mask arguments with rank == 1. 1263 mlir::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 is 1270 /// specialized for mask arguments with rank == 1. 1271 mlir::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 specialized 1278 /// version when mask is a rank one array or the dim argument is not 1279 /// specified by the user. 1280 mlir::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 a 1288 /// descriptor result. 1289 void 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 builder.create<fir::CallOp>(loc, func, args); 1300 } 1301 1302 /// Generate call to `Findloc` intrinsic runtime routine. This is the version 1303 /// that does not take a dim argument. 1304 void 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 builder.create<fir::CallOp>(loc, func, args); 1317 } 1318 1319 /// Generate call to `FindlocDim` intrinsic runtime routine. This is the version 1320 /// that takes a dim argument. 1321 void 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 builder.create<fir::CallOp>(loc, func, args); 1335 } 1336 1337 /// Generate call to `Maxloc` intrinsic runtime routine. This is the version 1338 /// that does not take a dim argument. 1339 void 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 version 1361 /// that takes a dim argument. 1362 void 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 version 1372 /// that does not take a dim argument. 1373 mlir::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 builder.create<fir::CallOp>(loc, func, args).getResult(0); 1396 } 1397 1398 /// Generate call to `MaxvalDim` intrinsic runtime routine. This is the version 1399 /// that handles any rank array with the dim argument specified. 1400 void 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 the 1408 /// version that handles character arrays of rank 1 and without a DIM argument. 1409 void 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 builder.create<fir::CallOp>(loc, func, args); 1421 } 1422 1423 /// Generate call to `Minloc` intrinsic runtime routine. This is the version 1424 /// that does not take a dim argument. 1425 void 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 version 1447 /// that takes a dim argument. 1448 void 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 version 1458 /// that handles any rank array with the dim argument specified. 1459 void 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 the 1467 /// version that handles character arrays of rank 1 and without a DIM argument. 1468 void 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 builder.create<fir::CallOp>(loc, func, args); 1480 } 1481 1482 /// Generate call to `Minval` intrinsic runtime routine. This is the version 1483 /// that does not take a dim argument. 1484 mlir::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 builder.create<fir::CallOp>(loc, func, args).getResult(0); 1508 } 1509 1510 /// Generate call to `Norm2Dim` intrinsic runtime routine. This is the version 1511 /// that takes a dim argument. 1512 void 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 else 1522 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 builder.create<fir::CallOp>(loc, func, args); 1531 } 1532 1533 /// Generate call to `Norm2` intrinsic runtime routine. This is the version 1534 /// that does not take a dim argument. 1535 mlir::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 else 1552 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 builder.create<fir::CallOp>(loc, func, args).getResult(0); 1562 } 1563 1564 /// Generate call to `Parity` intrinsic runtime routine. This routine is 1565 /// specialized for mask arguments with rank == 1. 1566 mlir::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 version 1574 /// that handles any rank array with the dim argument specified. 1575 void 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 version 1583 /// that does not take a dim argument. 1584 mlir::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 builder.create<fir::CallOp>(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 builder.create<fir::CallOp>(loc, func, args).getResult(0); 1617 } 1618 1619 /// Generate call to `DotProduct` intrinsic runtime routine. 1620 mlir::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 builder.create<fir::CallOp>(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 builder.create<fir::CallOp>(loc, func, args).getResult(0); 1657 } 1658 /// Generate call to `SumDim` intrinsic runtime routine. This is the version 1659 /// that handles any rank array with the dim argument specified. 1660 void 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 version 1668 /// that does not take a dim argument. 1669 mlir::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 builder.create<fir::CallOp>(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 builder.create<fir::CallOp>(loc, func, args).getResult(0); 1701 } 1702 1703 // The IAll, IAny and IParity intrinsics have essentially the same 1704 // implementation. This macro will generate the function body given the 1705 // 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 builder.create<fir::CallOp>(loc, func, args).getResult(0); \ 1737 } 1738 1739 /// Generate call to `IAllDim` intrinsic runtime routine. This is the version 1740 /// that handles any rank array with the dim argument specified. 1741 void 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 version 1749 /// that does not take a dim argument. 1750 GEN_IALL_IANY_IPARITY(IAll) 1751 1752 /// Generate call to `IAnyDim` intrinsic runtime routine. This is the version 1753 /// that handles any rank array with the dim argument specified. 1754 void 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 version 1762 /// that does not take a dim argument. 1763 GEN_IALL_IANY_IPARITY(IAny) 1764 1765 /// Generate call to `IParityDim` intrinsic runtime routine. This is the version 1766 /// that handles any rank array with the dim argument specified. 1767 void 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 version 1775 /// that does not take a dim argument. 1776 GEN_IALL_IANY_IPARITY(IParity) 1777 1778 /// Generate call to `Reduce` intrinsic runtime routine. This is the version 1779 /// that does not take a DIM argument and store result in the passed result 1780 /// value. 1781 void 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 = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(2), operation); 1823 auto args = fir::runtime::createArguments( 1824 builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine, 1825 dim, maskBox, identity, ordered); 1826 builder.create<fir::CallOp>(loc, func, args); 1827 } 1828 1829 /// Generate call to `Reduce` intrinsic runtime routine. This is the version 1830 /// that does not take DIM argument and return a scalar result. 1831 mlir::Value fir::runtime::genReduce(fir::FirOpBuilder &builder, 1832 mlir::Location loc, mlir::Value arrayBox, 1833 mlir::Value operation, mlir::Value maskBox, 1834 mlir::Value identity, mlir::Value ordered, 1835 bool argByRef) { 1836 auto ty = arrayBox.getType(); 1837 auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty); 1838 auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType(); 1839 auto dim = builder.createIntegerConstant(loc, builder.getI32Type(), 1); 1840 1841 assert((fir::isa_real(eleTy) || fir::isa_integer(eleTy) || 1842 mlir::isa<fir::LogicalType>(eleTy)) && 1843 "expect real, interger or logical"); 1844 1845 auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy); 1846 mlir::func::FuncOp func; 1847 if (argByRef) { 1848 REAL_2_3_INTRINSIC_INSTANCES(Reduce, Ref) 1849 REAL_INTRINSIC_INSTANCES(Reduce, Ref) 1850 INTEGER_INTRINSIC_INSTANCES(Reduce, Ref) 1851 UNSIGNED_INTRINSIC_INSTANCES(Reduce, Ref) 1852 LOGICAL_INTRINSIC_INSTANCES(Reduce, Ref) 1853 } else { 1854 REAL_2_3_INTRINSIC_INSTANCES(Reduce, Value) 1855 REAL_INTRINSIC_INSTANCES(Reduce, Value) 1856 INTEGER_INTRINSIC_INSTANCES(Reduce, Value) 1857 UNSIGNED_INTRINSIC_INSTANCES(Reduce, Value) 1858 LOGICAL_INTRINSIC_INSTANCES(Reduce, Value) 1859 } 1860 if (!func) 1861 fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE"); 1862 1863 auto fTy = func.getFunctionType(); 1864 auto sourceFile = fir::factory::locationToFilename(builder, loc); 1865 auto sourceLine = 1866 fir::factory::locationToLineNo(builder, loc, fTy.getInput(3)); 1867 auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(1), operation); 1868 auto args = fir::runtime::createArguments(builder, loc, fTy, arrayBox, opAddr, 1869 sourceFile, sourceLine, dim, 1870 maskBox, identity, ordered); 1871 return builder.create<fir::CallOp>(loc, func, args).getResult(0); 1872 } 1873 1874 void fir::runtime::genReduceDim(fir::FirOpBuilder &builder, mlir::Location loc, 1875 mlir::Value arrayBox, mlir::Value operation, 1876 mlir::Value dim, mlir::Value maskBox, 1877 mlir::Value identity, mlir::Value ordered, 1878 mlir::Value resultBox, bool argByRef) { 1879 auto ty = arrayBox.getType(); 1880 auto arrTy = fir::dyn_cast_ptrOrBoxEleTy(ty); 1881 auto eleTy = mlir::cast<fir::SequenceType>(arrTy).getElementType(); 1882 auto [cat, kind] = fir::mlirTypeToCategoryKind(loc, eleTy); 1883 1884 mlir::func::FuncOp func; 1885 if (argByRef) { 1886 REAL_2_3_INTRINSIC_INSTANCES(Reduce, DimRef) 1887 COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, DimRef) 1888 NUMERICAL_AND_LOGICAL_INSTANCES(Reduce, DimRef) 1889 } else { 1890 REAL_2_3_INTRINSIC_INSTANCES(Reduce, DimValue) 1891 COMPLEX_2_3_INTRINSIC_INSTANCES(Reduce, DimValue) 1892 NUMERICAL_AND_LOGICAL_INSTANCES(Reduce, DimValue) 1893 } 1894 fir::factory::CharacterExprHelper charHelper{builder, loc}; 1895 if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 1) 1896 func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter1Dim)>(loc, 1897 builder); 1898 else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 2) 1899 func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter2Dim)>(loc, 1900 builder); 1901 else if (fir::isa_char(eleTy) && charHelper.getCharacterKind(eleTy) == 4) 1902 func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceCharacter4Dim)>(loc, 1903 builder); 1904 else if (fir::isa_derived(eleTy)) 1905 func = fir::runtime::getRuntimeFunc<mkRTKey(ReduceDerivedTypeDim)>(loc, 1906 builder); 1907 if (!func) 1908 fir::intrinsicTypeTODO(builder, eleTy, loc, "REDUCE"); 1909 1910 auto fTy = func.getFunctionType(); 1911 auto sourceFile = fir::factory::locationToFilename(builder, loc); 1912 1913 auto sourceLine = 1914 fir::factory::locationToLineNo(builder, loc, fTy.getInput(4)); 1915 auto opAddr = builder.create<fir::BoxAddrOp>(loc, fTy.getInput(2), operation); 1916 auto args = fir::runtime::createArguments( 1917 builder, loc, fTy, resultBox, arrayBox, opAddr, sourceFile, sourceLine, 1918 dim, maskBox, identity, ordered); 1919 builder.create<fir::CallOp>(loc, func, args); 1920 } 1921