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 | |