17#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_RTBUILDER_H
18#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_RTBUILDER_H
20#include "flang/Common/uint128.h"
21#include "flang/Optimizer/Builder/FIRBuilder.h"
22#include "flang/Optimizer/Dialect/FIRDialect.h"
23#include "flang/Optimizer/Dialect/FIRType.h"
24#include "flang/Runtime/io-api.h"
25#include "flang/Runtime/reduce.h"
26#include "flang/Support/Fortran.h"
27#include "mlir/IR/BuiltinTypes.h"
28#include "mlir/IR/MLIRContext.h"
29#include "llvm/ADT/STLExtras.h"
30#include "llvm/ADT/SmallVector.h"
36typedef std::uint32_t pid_t;
43struct c_float_complex_t;
44struct c_double_complex_t;
46namespace Fortran::runtime {
53namespace fir::runtime {
55using TypeBuilderFunc = mlir::Type (*)(mlir::MLIRContext *);
56using FuncTypeBuilderFunc = mlir::FunctionType (*)(mlir::MLIRContext *);
58#define REDUCTION_REF_OPERATION_MODEL(T) \
60 constexpr TypeBuilderFunc \
61 getModel<Fortran::runtime::ReferenceReductionOperation<T>>() { \
62 return [](mlir::MLIRContext *context) -> mlir::Type { \
63 TypeBuilderFunc f{getModel<T>()}; \
64 auto refTy = fir::ReferenceType::get(f(context)); \
65 return mlir::FunctionType::get(context, {refTy, refTy}, refTy); \
69#define REDUCTION_VALUE_OPERATION_MODEL(T) \
71 constexpr TypeBuilderFunc \
72 getModel<Fortran::runtime::ValueReductionOperation<T>>() { \
73 return [](mlir::MLIRContext *context) -> mlir::Type { \
74 TypeBuilderFunc f{getModel<T>()}; \
75 auto refTy = fir::ReferenceType::get(f(context)); \
76 return mlir::FunctionType::get(context, {f(context), f(context)}, \
81#define REDUCTION_CHAR_OPERATION_MODEL(T) \
83 constexpr TypeBuilderFunc \
84 getModel<Fortran::runtime::ReductionCharOperation<T>>() { \
85 return [](mlir::MLIRContext *context) -> mlir::Type { \
86 TypeBuilderFunc f{getModel<T>()}; \
87 auto voidTy = fir::LLVMPointerType::get( \
88 context, mlir::IntegerType::get(context, 8)); \
90 mlir::IntegerType::get(context, 8 * sizeof(std::size_t)); \
91 auto refTy = fir::ReferenceType::get(f(context)); \
92 return mlir::FunctionType::get( \
93 context, {refTy, size_tTy, refTy, refTy, size_tTy, size_tTy}, \
113static constexpr TypeBuilderFunc getModel();
116constexpr TypeBuilderFunc getModel<unsigned int>() {
117 return [](mlir::MLIRContext *context) -> mlir::Type {
118 return mlir::IntegerType::get(context, 8 *
sizeof(
unsigned int));
122constexpr TypeBuilderFunc getModel<short int>() {
123 return [](mlir::MLIRContext *context) -> mlir::Type {
124 return mlir::IntegerType::get(context, 8 *
sizeof(
short int));
128constexpr TypeBuilderFunc getModel<short int *>() {
129 return [](mlir::MLIRContext *context) -> mlir::Type {
130 TypeBuilderFunc f{getModel<short int>()};
131 return fir::ReferenceType::get(f(context));
135constexpr TypeBuilderFunc getModel<const short int *>() {
136 return getModel<short int *>();
139constexpr TypeBuilderFunc getModel<int>() {
140 return [](mlir::MLIRContext *context) -> mlir::Type {
141 return mlir::IntegerType::get(context, 8 *
sizeof(
int));
145constexpr TypeBuilderFunc getModel<int &>() {
146 return [](mlir::MLIRContext *context) -> mlir::Type {
147 TypeBuilderFunc f{getModel<int>()};
148 return fir::ReferenceType::get(f(context));
152constexpr TypeBuilderFunc getModel<int *>() {
153 return getModel<int &>();
156constexpr TypeBuilderFunc getModel<const int *>() {
157 return [](mlir::MLIRContext *context) -> mlir::Type {
158 TypeBuilderFunc f{getModel<int>()};
159 return fir::ReferenceType::get(f(context));
163constexpr TypeBuilderFunc getModel<char *>() {
164 return [](mlir::MLIRContext *context) -> mlir::Type {
165 return fir::ReferenceType::get(mlir::IntegerType::get(context, 8));
169constexpr TypeBuilderFunc getModel<const char *>() {
170 return getModel<char *>();
173constexpr TypeBuilderFunc getModel<const char16_t *>() {
174 return [](mlir::MLIRContext *context) -> mlir::Type {
175 return fir::ReferenceType::get(mlir::IntegerType::get(context, 16));
179constexpr TypeBuilderFunc getModel<const char32_t *>() {
180 return [](mlir::MLIRContext *context) -> mlir::Type {
181 return fir::ReferenceType::get(mlir::IntegerType::get(context, 32));
185constexpr TypeBuilderFunc getModel<char>() {
186 return [](mlir::MLIRContext *context) -> mlir::Type {
187 return mlir::IntegerType::get(context, 8 *
sizeof(
char));
191constexpr TypeBuilderFunc getModel<signed char>() {
192 return [](mlir::MLIRContext *context) -> mlir::Type {
193 return mlir::IntegerType::get(context, 8 *
sizeof(
signed char));
197constexpr TypeBuilderFunc getModel<signed char *>() {
198 return [](mlir::MLIRContext *context) -> mlir::Type {
199 TypeBuilderFunc f{getModel<signed char>()};
200 return fir::ReferenceType::get(f(context));
204constexpr TypeBuilderFunc getModel<const signed char *>() {
205 return getModel<signed char *>();
208constexpr TypeBuilderFunc getModel<char16_t>() {
209 return [](mlir::MLIRContext *context) -> mlir::Type {
210 return mlir::IntegerType::get(context, 8 *
sizeof(
char16_t));
214constexpr TypeBuilderFunc getModel<char16_t *>() {
215 return [](mlir::MLIRContext *context) -> mlir::Type {
216 TypeBuilderFunc f{getModel<char16_t>()};
217 return fir::ReferenceType::get(f(context));
221constexpr TypeBuilderFunc getModel<char32_t>() {
222 return [](mlir::MLIRContext *context) -> mlir::Type {
223 return mlir::IntegerType::get(context, 8 *
sizeof(
char32_t));
227constexpr TypeBuilderFunc getModel<char32_t *>() {
228 return [](mlir::MLIRContext *context) -> mlir::Type {
229 TypeBuilderFunc f{getModel<char32_t>()};
230 return fir::ReferenceType::get(f(context));
234constexpr TypeBuilderFunc getModel<unsigned char>() {
235 return [](mlir::MLIRContext *context) -> mlir::Type {
236 return mlir::IntegerType::get(context, 8 *
sizeof(
unsigned char));
240constexpr TypeBuilderFunc getModel<void *>() {
241 return [](mlir::MLIRContext *context) -> mlir::Type {
242 return fir::LLVMPointerType::get(context,
243 mlir::IntegerType::get(context, 8));
247constexpr TypeBuilderFunc getModel<const void *>() {
248 return getModel<void *>();
251constexpr TypeBuilderFunc getModel<void (*)(int)>() {
252 return [](mlir::MLIRContext *context) -> mlir::Type {
253 return fir::LLVMPointerType::get(
255 mlir::FunctionType::get(context, {}, {}));
259constexpr TypeBuilderFunc
260getModel<void *(*)(void *, const void *, unsigned long)>() {
261 return [](mlir::MLIRContext *context) -> mlir::Type {
263 fir::LLVMPointerType::get(context, mlir::IntegerType::get(context, 8));
264 auto unsignedLongTy =
265 mlir::IntegerType::get(context, 8 *
sizeof(
unsigned long));
266 auto funcTy = mlir::FunctionType::get(
267 context, {voidPtrTy, voidPtrTy, unsignedLongTy}, {voidPtrTy});
268 return fir::LLVMPointerType::get(context, funcTy);
273constexpr TypeBuilderFunc
274getModel<void *(*)(void *, const void *, unsigned __int64)>() {
275 return [](mlir::MLIRContext *context) -> mlir::Type {
277 fir::LLVMPointerType::get(context, mlir::IntegerType::get(context, 8));
278 auto uint64Ty = mlir::IntegerType::get(context, 64);
279 auto funcTy = mlir::FunctionType::get(
280 context, {voidPtrTy, voidPtrTy, uint64Ty}, {voidPtrTy});
281 return fir::LLVMPointerType::get(context, funcTy);
286constexpr TypeBuilderFunc getModel<void (*)(void)>() {
287 return [](mlir::MLIRContext *context) -> mlir::Type {
288 return fir::LLVMPointerType::get(
290 mlir::FunctionType::get(context, {}, {}));
294constexpr TypeBuilderFunc getModel<void **>() {
295 return [](mlir::MLIRContext *context) -> mlir::Type {
296 return fir::ReferenceType::get(
297 fir::LLVMPointerType::get(context, mlir::IntegerType::get(context, 8)));
301constexpr TypeBuilderFunc getModel<long>() {
302 return [](mlir::MLIRContext *context) -> mlir::Type {
303 return mlir::IntegerType::get(context, 8 *
sizeof(
long));
307constexpr TypeBuilderFunc getModel<long &>() {
308 return [](mlir::MLIRContext *context) -> mlir::Type {
309 TypeBuilderFunc f{getModel<long>()};
310 return fir::ReferenceType::get(f(context));
314constexpr TypeBuilderFunc getModel<long *>() {
315 return getModel<long &>();
318constexpr TypeBuilderFunc getModel<const long *>() {
319 return getModel<long *>();
322constexpr TypeBuilderFunc getModel<long long>() {
323 return [](mlir::MLIRContext *context) -> mlir::Type {
324 return mlir::IntegerType::get(context, 8 *
sizeof(
long long));
328constexpr TypeBuilderFunc getModel<Fortran::common::int128_t>() {
329 return [](mlir::MLIRContext *context) -> mlir::Type {
330 return mlir::IntegerType::get(context,
331 8 *
sizeof(Fortran::common::int128_t));
335constexpr TypeBuilderFunc getModel<long long &>() {
336 return [](mlir::MLIRContext *context) -> mlir::Type {
337 TypeBuilderFunc f{getModel<long long>()};
338 return fir::ReferenceType::get(f(context));
342constexpr TypeBuilderFunc getModel<long long *>() {
343 return getModel<long long &>();
346constexpr TypeBuilderFunc getModel<const long long *>() {
347 return getModel<long long *>();
350constexpr TypeBuilderFunc getModel<unsigned long>() {
351 return [](mlir::MLIRContext *context) -> mlir::Type {
352 return mlir::IntegerType::get(context, 8 *
sizeof(
unsigned long));
356constexpr TypeBuilderFunc getModel<unsigned long long>() {
357 return [](mlir::MLIRContext *context) -> mlir::Type {
358 return mlir::IntegerType::get(context, 8 *
sizeof(
unsigned long long));
362constexpr TypeBuilderFunc getModel<double>() {
363 return [](mlir::MLIRContext *context) -> mlir::Type {
364 return mlir::Float64Type::get(context);
368constexpr TypeBuilderFunc getModel<double &>() {
369 return [](mlir::MLIRContext *context) -> mlir::Type {
370 TypeBuilderFunc f{getModel<double>()};
371 return fir::ReferenceType::get(f(context));
375constexpr TypeBuilderFunc getModel<double *>() {
376 return getModel<double &>();
379constexpr TypeBuilderFunc getModel<const double *>() {
380 return getModel<double *>();
383constexpr TypeBuilderFunc getModel<long double>() {
384 return [](mlir::MLIRContext *context) -> mlir::Type {
387 constexpr size_t size =
sizeof(
long double);
388 static_assert(size == 16 || size == 10 || size == 8,
389 "unsupported long double size");
390 if constexpr (size == 16)
391 return mlir::Float128Type::get(context);
392 if constexpr (size == 10)
393 return mlir::Float80Type::get(context);
394 if constexpr (size == 8)
395 return mlir::Float64Type::get(context);
396 llvm_unreachable(
"failed static assert");
400constexpr TypeBuilderFunc getModel<long double *>() {
401 return [](mlir::MLIRContext *context) -> mlir::Type {
402 TypeBuilderFunc f{getModel<long double>()};
403 return fir::ReferenceType::get(f(context));
407constexpr TypeBuilderFunc getModel<const long double *>() {
408 return getModel<long double *>();
411constexpr TypeBuilderFunc getModel<float>() {
412 return [](mlir::MLIRContext *context) -> mlir::Type {
413 return mlir::Float32Type::get(context);
417constexpr TypeBuilderFunc getModel<float &>() {
418 return [](mlir::MLIRContext *context) -> mlir::Type {
419 TypeBuilderFunc f{getModel<float>()};
420 return fir::ReferenceType::get(f(context));
424constexpr TypeBuilderFunc getModel<float *>() {
425 return getModel<float &>();
428constexpr TypeBuilderFunc getModel<const float *>() {
429 return getModel<float *>();
432constexpr TypeBuilderFunc getModel<bool>() {
433 return [](mlir::MLIRContext *context) -> mlir::Type {
434 return mlir::IntegerType::get(context, 1);
438constexpr TypeBuilderFunc getModel<bool &>() {
439 return [](mlir::MLIRContext *context) -> mlir::Type {
440 TypeBuilderFunc f{getModel<bool>()};
441 return fir::ReferenceType::get(f(context));
445constexpr TypeBuilderFunc getModel<bool *>() {
446 return [](mlir::MLIRContext *context) -> mlir::Type {
447 TypeBuilderFunc f{getModel<bool>()};
448 return fir::ReferenceType::get(f(context));
452constexpr TypeBuilderFunc getModel<unsigned short>() {
453 return [](mlir::MLIRContext *context) -> mlir::Type {
454 return mlir::IntegerType::get(
455 context, 8 *
sizeof(
unsigned short),
456 mlir::IntegerType::SignednessSemantics::Unsigned);
460constexpr TypeBuilderFunc getModel<unsigned char *>() {
461 return [](mlir::MLIRContext *context) -> mlir::Type {
462 return fir::ReferenceType::get(mlir::IntegerType::get(context, 8));
466constexpr TypeBuilderFunc getModel<const unsigned char *>() {
467 return getModel<unsigned char *>();
470constexpr TypeBuilderFunc getModel<unsigned short *>() {
471 return [](mlir::MLIRContext *context) -> mlir::Type {
472 return fir::ReferenceType::get(
473 mlir::IntegerType::get(context, 8 *
sizeof(
unsigned short)));
477constexpr TypeBuilderFunc getModel<const unsigned short *>() {
478 return getModel<unsigned short *>();
481constexpr TypeBuilderFunc getModel<unsigned *>() {
482 return getModel<int *>();
485constexpr TypeBuilderFunc getModel<const unsigned *>() {
486 return getModel<unsigned *>();
489constexpr TypeBuilderFunc getModel<unsigned long *>() {
490 return [](mlir::MLIRContext *context) -> mlir::Type {
491 return fir::ReferenceType::get(
492 mlir::IntegerType::get(context, 8 *
sizeof(
unsigned long)));
496constexpr TypeBuilderFunc getModel<const unsigned long *>() {
497 return getModel<unsigned long *>();
500constexpr TypeBuilderFunc getModel<unsigned long long *>() {
501 return [](mlir::MLIRContext *context) -> mlir::Type {
502 return fir::ReferenceType::get(
503 mlir::IntegerType::get(context, 8 *
sizeof(
unsigned long long)));
507constexpr TypeBuilderFunc getModel<const unsigned long long *>() {
508 return getModel<unsigned long long *>();
511constexpr TypeBuilderFunc getModel<Fortran::common::uint128_t>() {
512 return getModel<Fortran::common::int128_t>();
515constexpr TypeBuilderFunc getModel<Fortran::common::int128_t *>() {
516 return [](mlir::MLIRContext *context) -> mlir::Type {
517 TypeBuilderFunc f{getModel<Fortran::common::int128_t>()};
518 return fir::ReferenceType::get(f(context));
522constexpr TypeBuilderFunc getModel<Fortran::common::uint128_t *>() {
523 return getModel<Fortran::common::int128_t *>();
526constexpr TypeBuilderFunc getModel<const Fortran::common::uint128_t *>() {
527 return getModel<Fortran::common::uint128_t *>();
538constexpr TypeBuilderFunc getModel<std::complex<float> &>() {
539 return [](mlir::MLIRContext *context) -> mlir::Type {
540 mlir::Type floatTy = getModel<float>()(context);
541 return fir::ReferenceType::get(mlir::ComplexType::get(floatTy));
545constexpr TypeBuilderFunc getModel<std::complex<float> *>() {
546 return getModel<std::complex<float> &>();
549constexpr TypeBuilderFunc getModel<const std::complex<float> *>() {
550 return getModel<std::complex<float> *>();
553constexpr TypeBuilderFunc getModel<std::complex<double> &>() {
554 return [](mlir::MLIRContext *context) -> mlir::Type {
555 mlir::Type floatTy = getModel<double>()(context);
556 return fir::ReferenceType::get(mlir::ComplexType::get(floatTy));
560constexpr TypeBuilderFunc getModel<std::complex<double> *>() {
561 return getModel<std::complex<double> &>();
564constexpr TypeBuilderFunc getModel<const std::complex<double> *>() {
565 return getModel<std::complex<double> *>();
568constexpr TypeBuilderFunc getModel<c_float_complex_t>() {
569 return [](mlir::MLIRContext *context) -> mlir::Type {
570 mlir::Type floatTy = getModel<float>()(context);
571 return mlir::ComplexType::get(floatTy);
575constexpr TypeBuilderFunc getModel<c_double_complex_t>() {
576 return [](mlir::MLIRContext *context) -> mlir::Type {
577 mlir::Type floatTy = getModel<double>()(context);
578 return mlir::ComplexType::get(floatTy);
582constexpr TypeBuilderFunc getModel<const Fortran::runtime::Descriptor &>() {
583 return [](mlir::MLIRContext *context) -> mlir::Type {
584 return fir::BoxType::get(mlir::NoneType::get(context));
588constexpr TypeBuilderFunc getModel<Fortran::runtime::Descriptor &>() {
589 return [](mlir::MLIRContext *context) -> mlir::Type {
590 return fir::ReferenceType::get(
591 fir::BoxType::get(mlir::NoneType::get(context)));
595constexpr TypeBuilderFunc getModel<const Fortran::runtime::Descriptor *>() {
596 return getModel<const Fortran::runtime::Descriptor &>();
599constexpr TypeBuilderFunc getModel<Fortran::runtime::Descriptor *>() {
600 return getModel<Fortran::runtime::Descriptor &>();
603constexpr TypeBuilderFunc getModel<Fortran::common::TypeCategory>() {
604 return [](mlir::MLIRContext *context) -> mlir::Type {
605 return mlir::IntegerType::get(context,
606 sizeof(Fortran::common::TypeCategory) * 8);
610constexpr TypeBuilderFunc
611getModel<const Fortran::runtime::typeInfo::DerivedType &>() {
612 return [](mlir::MLIRContext *context) -> mlir::Type {
613 return fir::ReferenceType::get(mlir::NoneType::get(context));
617constexpr TypeBuilderFunc
618getModel<const Fortran::runtime::typeInfo::DerivedType *>() {
619 return [](mlir::MLIRContext *context) -> mlir::Type {
620 return fir::ReferenceType::get(mlir::NoneType::get(context));
624constexpr TypeBuilderFunc getModel<void>() {
625 return [](mlir::MLIRContext *context) -> mlir::Type {
626 return mlir::NoneType::get(context);
632constexpr TypeBuilderFunc getModel<Fortran::runtime::io::IoStatementState *>() {
633 return getModel<char *>();
636constexpr TypeBuilderFunc getModel<Fortran::runtime::io::Iostat>() {
637 return [](mlir::MLIRContext *context) -> mlir::Type {
638 return mlir::IntegerType::get(context,
639 8 *
sizeof(Fortran::runtime::io::Iostat));
643constexpr TypeBuilderFunc
644getModel<const Fortran::runtime::io::NamelistGroup &>() {
645 return [](mlir::MLIRContext *context) -> mlir::Type {
646 return fir::ReferenceType::get(mlir::TupleType::get(context));
650constexpr TypeBuilderFunc
651getModel<const Fortran::runtime::io::NonTbpDefinedIoTable *>() {
652 return [](mlir::MLIRContext *context) -> mlir::Type {
653 return fir::ReferenceType::get(mlir::TupleType::get(context));
657REDUCTION_REF_OPERATION_MODEL(std::int8_t)
658REDUCTION_VALUE_OPERATION_MODEL(std::int8_t)
659REDUCTION_REF_OPERATION_MODEL(std::int16_t)
660REDUCTION_VALUE_OPERATION_MODEL(std::int16_t)
661REDUCTION_REF_OPERATION_MODEL(std::int32_t)
662REDUCTION_VALUE_OPERATION_MODEL(std::int32_t)
663REDUCTION_REF_OPERATION_MODEL(std::int64_t)
664REDUCTION_VALUE_OPERATION_MODEL(std::int64_t)
665REDUCTION_REF_OPERATION_MODEL(Fortran::common::int128_t)
666REDUCTION_VALUE_OPERATION_MODEL(Fortran::common::int128_t)
668REDUCTION_REF_OPERATION_MODEL(std::uint8_t)
669REDUCTION_VALUE_OPERATION_MODEL(std::uint8_t)
670REDUCTION_REF_OPERATION_MODEL(std::uint16_t)
671REDUCTION_VALUE_OPERATION_MODEL(std::uint16_t)
672REDUCTION_REF_OPERATION_MODEL(std::uint32_t)
673REDUCTION_VALUE_OPERATION_MODEL(std::uint32_t)
674REDUCTION_REF_OPERATION_MODEL(std::uint64_t)
675REDUCTION_VALUE_OPERATION_MODEL(std::uint64_t)
676REDUCTION_REF_OPERATION_MODEL(Fortran::common::uint128_t)
677REDUCTION_VALUE_OPERATION_MODEL(Fortran::common::uint128_t)
679REDUCTION_REF_OPERATION_MODEL(
float)
680REDUCTION_VALUE_OPERATION_MODEL(
float)
681REDUCTION_REF_OPERATION_MODEL(
double)
682REDUCTION_VALUE_OPERATION_MODEL(
double)
683REDUCTION_REF_OPERATION_MODEL(
long double)
684REDUCTION_VALUE_OPERATION_MODEL(
long double)
690constexpr TypeBuilderFunc
691getModel<Fortran::runtime::ValueReductionOperation<std::complex<float>>>() {
692 return [](mlir::MLIRContext *context) -> mlir::Type {
693 mlir::Type cplx = mlir::ComplexType::get(getModel<float>()(context));
694 auto refTy = fir::ReferenceType::get(cplx);
695 return mlir::FunctionType::get(context, {cplx, cplx}, refTy);
699constexpr TypeBuilderFunc
700getModel<Fortran::runtime::ValueReductionOperation<std::complex<double>>>() {
701 return [](mlir::MLIRContext *context) -> mlir::Type {
702 mlir::Type cplx = mlir::ComplexType::get(getModel<double>()(context));
703 auto refTy = fir::ReferenceType::get(cplx);
704 return mlir::FunctionType::get(context, {cplx, cplx}, refTy);
708constexpr TypeBuilderFunc
709getModel<Fortran::runtime::ReferenceReductionOperation<std::complex<float>>>() {
710 return [](mlir::MLIRContext *context) -> mlir::Type {
711 mlir::Type cplx = mlir::ComplexType::get(getModel<float>()(context));
712 auto refTy = fir::ReferenceType::get(cplx);
713 return mlir::FunctionType::get(context, {refTy, refTy}, refTy);
717constexpr TypeBuilderFunc getModel<
718 Fortran::runtime::ReferenceReductionOperation<std::complex<double>>>() {
719 return [](mlir::MLIRContext *context) -> mlir::Type {
720 mlir::Type cplx = mlir::ComplexType::get(getModel<double>()(context));
721 auto refTy = fir::ReferenceType::get(cplx);
722 return mlir::FunctionType::get(context, {refTy, refTy}, refTy);
726REDUCTION_CHAR_OPERATION_MODEL(
char)
727REDUCTION_CHAR_OPERATION_MODEL(
char16_t)
728REDUCTION_CHAR_OPERATION_MODEL(
char32_t)
731constexpr TypeBuilderFunc
732getModel<Fortran::runtime::ReductionDerivedTypeOperation>() {
733 return [](mlir::MLIRContext *context) -> mlir::Type {
735 fir::LLVMPointerType::get(context, mlir::IntegerType::get(context, 8));
736 return mlir::FunctionType::get(context, {voidTy, voidTy, voidTy}, voidTy);
740template <
typename...>
742template <
typename RT,
typename... ATs>
744 static constexpr FuncTypeBuilderFunc getTypeModel() {
745 return [](mlir::MLIRContext *ctxt) {
746 TypeBuilderFunc ret = getModel<RT>();
747 std::array<TypeBuilderFunc,
sizeof...(ATs)> args = {getModel<ATs>()...};
748 mlir::Type retTy = ret(ctxt);
751 argTys.push_back(f(ctxt));
752 if (mlir::isa<mlir::NoneType>(retTy))
753 return mlir::FunctionType::get(ctxt, argTys, {});
754 return mlir::FunctionType::get(ctxt, argTys, {retTy});
764using RuntimeIdentifier = std::integer_sequence<char, Cs...>;
767template <
typename T, T... As, T... Bs>
768static constexpr std::integer_sequence<T, As..., Bs...>
769concat(std::integer_sequence<T, As...>, std::integer_sequence<T, Bs...>) {
772template <
typename T, T... As, T... Bs,
typename... Cs>
773static constexpr auto concat(std::integer_sequence<T, As...>,
774 std::integer_sequence<T, Bs...>, Cs...) {
775 return concat(std::integer_sequence<T, As..., Bs...>{}, Cs{}...);
778static constexpr std::integer_sequence<T> concat(std::integer_sequence<T>) {
781template <
typename T, T a>
782static constexpr auto filterZero(std::integer_sequence<T, a>) {
783 if constexpr (a != 0) {
784 return std::integer_sequence<T, a>{};
786 return std::integer_sequence<T>{};
789template <
typename T, T... b>
790static constexpr auto filter(std::integer_sequence<T, b...>) {
791 if constexpr (
sizeof...(b) > 0) {
792 return details::concat(filterZero(std::integer_sequence<T, b>{})...);
794 return std::integer_sequence<T>{};
799template <
typename...>
801template <
typename KT,
char... Cs>
803 static constexpr FuncTypeBuilderFunc getTypeModel() {
806 static constexpr const char name[
sizeof...(Cs) + 1] = {Cs...,
'\0'};
821#define FirE(L, I) (I < sizeof(L) / sizeof(*L) ? L[I] : 0)
822#define FirQuoteKey(X) #X
823#define ExpandAndQuoteKey(X) FirQuoteKey(X)
824#define FirMacroExpandKey(X) \
825 FirE(X, 0), FirE(X, 1), FirE(X, 2), FirE(X, 3), FirE(X, 4), FirE(X, 5), \
826 FirE(X, 6), FirE(X, 7), FirE(X, 8), FirE(X, 9), FirE(X, 10), \
827 FirE(X, 11), FirE(X, 12), FirE(X, 13), FirE(X, 14), FirE(X, 15), \
828 FirE(X, 16), FirE(X, 17), FirE(X, 18), FirE(X, 19), FirE(X, 20), \
829 FirE(X, 21), FirE(X, 22), FirE(X, 23), FirE(X, 24), FirE(X, 25), \
830 FirE(X, 26), FirE(X, 27), FirE(X, 28), FirE(X, 29), FirE(X, 30), \
831 FirE(X, 31), FirE(X, 32), FirE(X, 33), FirE(X, 34), FirE(X, 35), \
832 FirE(X, 36), FirE(X, 37), FirE(X, 38), FirE(X, 39), FirE(X, 40), \
833 FirE(X, 41), FirE(X, 42), FirE(X, 43), FirE(X, 44), FirE(X, 45), \
834 FirE(X, 46), FirE(X, 47), FirE(X, 48), FirE(X, 49)
835#define FirExpandKey(X) FirMacroExpandKey(FirQuoteKey(X))
836#define FirFullSeq(X) std::integer_sequence<char, FirExpandKey(X)>
837#define FirAsSequence(X) \
838 decltype(fir::runtime::details::filter(FirFullSeq(X){}))
840 fir::runtime::RuntimeTableEntry<fir::runtime::RuntimeTableKey<decltype(X)>, \
842#define mkRTKey(X) FirmkKey(RTNAME(X))
843#define EXPAND_AND_QUOTE_KEY(S) ExpandAndQuoteKey(RTNAME(S))
847template <
typename RuntimeEntry>
848static mlir::func::FuncOp getRuntimeFunc(mlir::Location loc,
851 using namespace Fortran::runtime;
852 auto name = RuntimeEntry::name;
856 auto funTy = RuntimeEntry::getTypeModel()(builder.getContext());
862static mlir::func::FuncOp getIORuntimeFunc(mlir::Location loc,
863 fir::FirOpBuilder &builder) {
864 return getRuntimeFunc<E>(loc, builder,
true);
867inline llvm::SmallVector<mlir::Value>
868createArguments(fir::FirOpBuilder &builder, mlir::Location loc,
869 mlir::FunctionType fTy, llvm::ArrayRef<mlir::Value> args) {
870 return llvm::map_to_vector(llvm::zip_equal(fTy.getInputs(), args),
871 [&](
const auto &pair) -> mlir::Value {
872 auto [type, argument] = pair;
873 return builder.createConvertWithVolatileCast(
874 loc, type, argument);
879template <
typename... As>
880llvm::SmallVector<mlir::Value>
882 mlir::FunctionType fTy, As... args) {
883 return createArguments(builder, loc, fTy, {args...});
Definition FIRBuilder.h:56
mlir::func::FuncOp createRuntimeFunction(mlir::Location loc, llvm::StringRef name, mlir::FunctionType ty, bool isIO=false)
Definition FIRBuilder.cpp:53
mlir::func::FuncOp getNamedFunction(llvm::StringRef name)
Definition FIRBuilder.h:395
Definition RTBuilder.h:800