2222#include " flang/Optimizer/Builder/FIRBuilder.h"
2323#include " flang/Optimizer/Dialect/FIRDialect.h"
2424#include " flang/Optimizer/Dialect/FIRType.h"
25+ #include " flang/Runtime/reduce.h"
2526#include " mlir/IR/BuiltinTypes.h"
2627#include " mlir/IR/MLIRContext.h"
2728#include " llvm/ADT/SmallVector.h"
@@ -52,6 +53,34 @@ namespace fir::runtime {
5253using TypeBuilderFunc = mlir::Type (*)(mlir::MLIRContext *);
5354using FuncTypeBuilderFunc = mlir::FunctionType (*)(mlir::MLIRContext *);
5455
56+ #define REDUCTION_OPERATION_MODEL (T ) \
57+ template <> \
58+ constexpr TypeBuilderFunc \
59+ getModel<Fortran::runtime::ReductionOperation<T>>() { \
60+ return [](mlir::MLIRContext *context) -> mlir::Type { \
61+ TypeBuilderFunc f{getModel<T>()}; \
62+ auto refTy = fir::ReferenceType::get (f (context)); \
63+ return mlir::FunctionType::get (context, {refTy, refTy}, refTy); \
64+ }; \
65+ }
66+
67+ #define REDUCTION_CHAR_OPERATION_MODEL (T ) \
68+ template <> \
69+ constexpr TypeBuilderFunc \
70+ getModel<Fortran::runtime::ReductionCharOperation<T>>() { \
71+ return [](mlir::MLIRContext *context) -> mlir::Type { \
72+ TypeBuilderFunc f{getModel<T>()}; \
73+ auto voidTy = fir::LLVMPointerType::get ( \
74+ context, mlir::IntegerType::get (context, 8 )); \
75+ auto size_tTy = \
76+ mlir::IntegerType::get (context, 8 * sizeof (std::size_t )); \
77+ auto refTy = fir::ReferenceType::get (f (context)); \
78+ return mlir::FunctionType::get ( \
79+ context, {refTy, size_tTy, refTy, refTy, size_tTy, size_tTy}, \
80+ voidTy); \
81+ }; \
82+ }
83+
5584// ===----------------------------------------------------------------------===//
5685// Type builder models
5786// ===----------------------------------------------------------------------===//
@@ -75,14 +104,24 @@ constexpr TypeBuilderFunc getModel<unsigned int>() {
75104 return mlir::IntegerType::get (context, 8 * sizeof (unsigned int ));
76105 };
77106}
78-
79107template <>
80108constexpr TypeBuilderFunc getModel<short int >() {
81109 return [](mlir::MLIRContext *context) -> mlir::Type {
82110 return mlir::IntegerType::get (context, 8 * sizeof (short int ));
83111 };
84112}
85113template <>
114+ constexpr TypeBuilderFunc getModel<short int *>() {
115+ return [](mlir::MLIRContext *context) -> mlir::Type {
116+ TypeBuilderFunc f{getModel<short int >()};
117+ return fir::ReferenceType::get (f (context));
118+ };
119+ }
120+ template <>
121+ constexpr TypeBuilderFunc getModel<const short int *>() {
122+ return getModel<short int *>();
123+ }
124+ template <>
86125constexpr TypeBuilderFunc getModel<int >() {
87126 return [](mlir::MLIRContext *context) -> mlir::Type {
88127 return mlir::IntegerType::get (context, 8 * sizeof (int ));
@@ -96,6 +135,17 @@ constexpr TypeBuilderFunc getModel<int &>() {
96135 };
97136}
98137template <>
138+ constexpr TypeBuilderFunc getModel<int *>() {
139+ return getModel<int &>();
140+ }
141+ template <>
142+ constexpr TypeBuilderFunc getModel<const int *>() {
143+ return [](mlir::MLIRContext *context) -> mlir::Type {
144+ TypeBuilderFunc f{getModel<int >()};
145+ return fir::ReferenceType::get (f (context));
146+ };
147+ }
148+ template <>
99149constexpr TypeBuilderFunc getModel<char *>() {
100150 return [](mlir::MLIRContext *context) -> mlir::Type {
101151 return fir::ReferenceType::get (mlir::IntegerType::get (context, 8 ));
@@ -130,6 +180,43 @@ constexpr TypeBuilderFunc getModel<signed char>() {
130180 };
131181}
132182template <>
183+ constexpr TypeBuilderFunc getModel<signed char *>() {
184+ return [](mlir::MLIRContext *context) -> mlir::Type {
185+ TypeBuilderFunc f{getModel<signed char >()};
186+ return fir::ReferenceType::get (f (context));
187+ };
188+ }
189+ template <>
190+ constexpr TypeBuilderFunc getModel<const signed char *>() {
191+ return getModel<signed char *>();
192+ }
193+ template <>
194+ constexpr TypeBuilderFunc getModel<char16_t >() {
195+ return [](mlir::MLIRContext *context) -> mlir::Type {
196+ return mlir::IntegerType::get (context, 8 * sizeof (char16_t ));
197+ };
198+ }
199+ template <>
200+ constexpr TypeBuilderFunc getModel<char16_t *>() {
201+ return [](mlir::MLIRContext *context) -> mlir::Type {
202+ TypeBuilderFunc f{getModel<char16_t >()};
203+ return fir::ReferenceType::get (f (context));
204+ };
205+ }
206+ template <>
207+ constexpr TypeBuilderFunc getModel<char32_t >() {
208+ return [](mlir::MLIRContext *context) -> mlir::Type {
209+ return mlir::IntegerType::get (context, 8 * sizeof (char32_t ));
210+ };
211+ }
212+ template <>
213+ constexpr TypeBuilderFunc getModel<char32_t *>() {
214+ return [](mlir::MLIRContext *context) -> mlir::Type {
215+ TypeBuilderFunc f{getModel<char32_t >()};
216+ return fir::ReferenceType::get (f (context));
217+ };
218+ }
219+ template <>
133220constexpr TypeBuilderFunc getModel<unsigned char >() {
134221 return [](mlir::MLIRContext *context) -> mlir::Type {
135222 return mlir::IntegerType::get (context, 8 * sizeof (unsigned char ));
@@ -175,6 +262,10 @@ constexpr TypeBuilderFunc getModel<long *>() {
175262 return getModel<long &>();
176263}
177264template <>
265+ constexpr TypeBuilderFunc getModel<const long *>() {
266+ return getModel<long *>();
267+ }
268+ template <>
178269constexpr TypeBuilderFunc getModel<long long >() {
179270 return [](mlir::MLIRContext *context) -> mlir::Type {
180271 return mlir::IntegerType::get (context, 8 * sizeof (long long ));
@@ -199,6 +290,10 @@ constexpr TypeBuilderFunc getModel<long long *>() {
199290 return getModel<long long &>();
200291}
201292template <>
293+ constexpr TypeBuilderFunc getModel<const long long *>() {
294+ return getModel<long long *>();
295+ }
296+ template <>
202297constexpr TypeBuilderFunc getModel<unsigned long >() {
203298 return [](mlir::MLIRContext *context) -> mlir::Type {
204299 return mlir::IntegerType::get (context, 8 * sizeof (unsigned long ));
@@ -228,6 +323,27 @@ constexpr TypeBuilderFunc getModel<double *>() {
228323 return getModel<double &>();
229324}
230325template <>
326+ constexpr TypeBuilderFunc getModel<const double *>() {
327+ return getModel<double *>();
328+ }
329+ template <>
330+ constexpr TypeBuilderFunc getModel<long double >() {
331+ return [](mlir::MLIRContext *context) -> mlir::Type {
332+ return mlir::FloatType::getF80 (context);
333+ };
334+ }
335+ template <>
336+ constexpr TypeBuilderFunc getModel<long double *>() {
337+ return [](mlir::MLIRContext *context) -> mlir::Type {
338+ TypeBuilderFunc f{getModel<long double >()};
339+ return fir::ReferenceType::get (f (context));
340+ };
341+ }
342+ template <>
343+ constexpr TypeBuilderFunc getModel<const long double *>() {
344+ return getModel<long double *>();
345+ }
346+ template <>
231347constexpr TypeBuilderFunc getModel<float >() {
232348 return [](mlir::MLIRContext *context) -> mlir::Type {
233349 return mlir::FloatType::getF32 (context);
@@ -245,6 +361,10 @@ constexpr TypeBuilderFunc getModel<float *>() {
245361 return getModel<float &>();
246362}
247363template <>
364+ constexpr TypeBuilderFunc getModel<const float *>() {
365+ return getModel<float *>();
366+ }
367+ template <>
248368constexpr TypeBuilderFunc getModel<bool >() {
249369 return [](mlir::MLIRContext *context) -> mlir::Type {
250370 return mlir::IntegerType::get (context, 1 );
@@ -258,20 +378,48 @@ constexpr TypeBuilderFunc getModel<bool &>() {
258378 };
259379}
260380template <>
381+ constexpr TypeBuilderFunc getModel<std::complex <float >>() {
382+ return [](mlir::MLIRContext *context) -> mlir::Type {
383+ return mlir::ComplexType::get (mlir::FloatType::getF32 (context));
384+ };
385+ }
386+ template <>
261387constexpr TypeBuilderFunc getModel<std::complex <float > &>() {
262388 return [](mlir::MLIRContext *context) -> mlir::Type {
263- auto ty = mlir::ComplexType::get (mlir::FloatType::getF32 (context));
264- return fir::ReferenceType::get (ty);
389+ TypeBuilderFunc f{getModel<std::complex <float >>()};
390+ return fir::ReferenceType::get (f (context));
391+ };
392+ }
393+ template <>
394+ constexpr TypeBuilderFunc getModel<std::complex <float > *>() {
395+ return getModel<std::complex <float > &>();
396+ }
397+ template <>
398+ constexpr TypeBuilderFunc getModel<const std::complex <float > *>() {
399+ return getModel<std::complex <float > *>();
400+ }
401+ template <>
402+ constexpr TypeBuilderFunc getModel<std::complex <double >>() {
403+ return [](mlir::MLIRContext *context) -> mlir::Type {
404+ return mlir::ComplexType::get (mlir::FloatType::getF64 (context));
265405 };
266406}
267407template <>
268408constexpr TypeBuilderFunc getModel<std::complex <double > &>() {
269409 return [](mlir::MLIRContext *context) -> mlir::Type {
270- auto ty = mlir::ComplexType::get ( mlir::FloatType::getF64 (context)) ;
271- return fir::ReferenceType::get (ty );
410+ TypeBuilderFunc f{getModel<std:: complex < double >>()} ;
411+ return fir::ReferenceType::get (f (context) );
272412 };
273413}
274414template <>
415+ constexpr TypeBuilderFunc getModel<std::complex <double > *>() {
416+ return getModel<std::complex <double > &>();
417+ }
418+ template <>
419+ constexpr TypeBuilderFunc getModel<const std::complex <double > *>() {
420+ return getModel<std::complex <double > *>();
421+ }
422+ template <>
275423constexpr TypeBuilderFunc getModel<c_float_complex_t >() {
276424 return [](mlir::MLIRContext *context) -> mlir::Type {
277425 return fir::ComplexType::get (context, sizeof (float ));
@@ -332,6 +480,33 @@ constexpr TypeBuilderFunc getModel<void>() {
332480 };
333481}
334482
483+ REDUCTION_OPERATION_MODEL (std::int8_t )
484+ REDUCTION_OPERATION_MODEL (std::int16_t )
485+ REDUCTION_OPERATION_MODEL (std::int32_t )
486+ REDUCTION_OPERATION_MODEL (std::int64_t )
487+ REDUCTION_OPERATION_MODEL (Fortran::common::int128_t )
488+
489+ REDUCTION_OPERATION_MODEL (float )
490+ REDUCTION_OPERATION_MODEL (double )
491+ REDUCTION_OPERATION_MODEL (long double )
492+
493+ REDUCTION_OPERATION_MODEL (std::complex <float >)
494+ REDUCTION_OPERATION_MODEL (std::complex <double >)
495+
496+ REDUCTION_CHAR_OPERATION_MODEL (char )
497+ REDUCTION_CHAR_OPERATION_MODEL (char16_t )
498+ REDUCTION_CHAR_OPERATION_MODEL (char32_t )
499+
500+ template <>
501+ constexpr TypeBuilderFunc
502+ getModel<Fortran::runtime::ReductionDerivedTypeOperation>() {
503+ return [](mlir::MLIRContext *context) -> mlir::Type {
504+ auto voidTy =
505+ fir::LLVMPointerType::get (context, mlir::IntegerType::get (context, 8 ));
506+ return mlir::FunctionType::get (context, {voidTy, voidTy, voidTy}, voidTy);
507+ };
508+ }
509+
335510template <typename ...>
336511struct RuntimeTableKey ;
337512template <typename RT, typename ... ATs>
0 commit comments