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
19using 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
26struct 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
42struct 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
58struct 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
75struct 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
93struct 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
109struct 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
125struct 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
142struct 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
162using 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 Intrinsic
172struct 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
187struct 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
202struct 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
218struct 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
234struct 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
250struct 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
267struct 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
285struct 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
303struct 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
321struct 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
337struct 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
353struct 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
371struct 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
389struct 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
405struct 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
422struct 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
438struct 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
454struct 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
470struct 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
487struct 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
505struct 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
523struct 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
539struct 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
555struct 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
571struct 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
591struct 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
611struct 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
631struct 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
651struct 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
673struct 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
695struct 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
717struct 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
739struct 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
759struct 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
779struct 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
799struct 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
819struct 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
841struct 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
864struct 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
886struct 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
909struct 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
930struct 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
951struct 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
973struct 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
995struct 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
1016struct 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
1037struct 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
1059struct 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.
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 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).
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 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).
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 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).
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 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).
1214template <typename FN>
1215static void
1216genReduction5Args(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.
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 is
1262/// 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 is
1270/// 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 specialized
1278/// version when mask is a rank one array or the dim argument is not
1279/// 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 a
1288/// 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 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.
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 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.
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 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.
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 version
1361/// 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 version
1372/// 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 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.
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 the
1408/// 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 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.
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 version
1447/// 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 version
1458/// 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 the
1467/// 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 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.
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 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.
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 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.
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 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.
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 version
1574/// 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 version
1583/// 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 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.
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 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.
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 version
1668/// 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 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.
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 version
1749/// that does not take a dim argument.
1750GEN_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.
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 version
1762/// that does not take a dim argument.
1763GEN_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.
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 version
1775/// that does not take a dim argument.
1776GEN_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.
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 = 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.
1831mlir::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
1874void 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

source code of flang/lib/Optimizer/Builder/Runtime/Reduction.cpp