File indexing completed on 2026-05-10 08:43:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 #ifndef LLVM_FRONTEND_OPENMP_CLAUSET_H
0042 #define LLVM_FRONTEND_OPENMP_CLAUSET_H
0043
0044 #include "llvm/ADT/ArrayRef.h"
0045 #include "llvm/ADT/DenseMap.h"
0046 #include "llvm/ADT/DenseSet.h"
0047 #include "llvm/ADT/STLExtras.h"
0048 #include "llvm/ADT/SmallVector.h"
0049 #include "llvm/Frontend/OpenMP/OMP.h"
0050 #include "llvm/Support/ErrorHandling.h"
0051 #include "llvm/Support/raw_ostream.h"
0052
0053 #include <algorithm>
0054 #include <iterator>
0055 #include <optional>
0056 #include <tuple>
0057 #include <type_traits>
0058 #include <utility>
0059 #include <variant>
0060
0061 #define ENUM(Name, ...) enum class Name { __VA_ARGS__ }
0062 #define OPT(x) std::optional<x>
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 #define CLAUSET_SCOPED_ENUM_MEMBER_CONVERT(Ov, Tv) \
0077 if (v == OtherEnum::Ov) { \
0078 return ThisEnum::Tv; \
0079 }
0080
0081
0082 #define CLAUSET_UNSCOPED_ENUM_MEMBER_CONVERT(Ov, Tv) \
0083 if (v == Ov) { \
0084 return ThisEnum::Tv; \
0085 }
0086
0087 #define CLAUSET_ENUM_CONVERT(func, OtherE, ThisE, Maps) \
0088 auto func = [](OtherE v) -> ThisE { \
0089 using ThisEnum = ThisE; \
0090 using OtherEnum = OtherE; \
0091 (void)sizeof(OtherEnum); \
0092 Maps; \
0093 llvm_unreachable("Unexpected value in " #OtherE); \
0094 }
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 namespace detail {
0113
0114 template <typename T> struct is_variant {
0115 static constexpr bool value = false;
0116 };
0117
0118 template <typename... Ts> struct is_variant<std::variant<Ts...>> {
0119 static constexpr bool value = true;
0120 };
0121
0122 template <typename T> constexpr bool is_variant_v = is_variant<T>::value;
0123
0124
0125 template <typename...> struct UnionOfTwo;
0126
0127 template <typename... Types1, typename... Types2>
0128 struct UnionOfTwo<std::variant<Types1...>, std::variant<Types2...>> {
0129 using type = std::variant<Types1..., Types2...>;
0130 };
0131 }
0132
0133 namespace tomp {
0134 namespace type {
0135
0136
0137
0138 template <typename...> struct Union;
0139
0140 template <> struct Union<> {
0141
0142 using type = std::variant<>;
0143 };
0144
0145 template <typename T, typename... Ts> struct Union<T, Ts...> {
0146 static_assert(detail::is_variant_v<T>);
0147 using type =
0148 typename detail::UnionOfTwo<T, typename Union<Ts...>::type>::type;
0149 };
0150
0151 template <typename T> using ListT = llvm::SmallVector<T, 0>;
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 template <typename IdType, typename ExprType> struct ObjectT;
0182
0183
0184 template <typename I, typename E>
0185 bool operator==(const ObjectT<I, E> &o1, const ObjectT<I, E> &o2) {
0186 return o1.id() == o2.id();
0187 }
0188
0189 template <typename I, typename E> using ObjectListT = ListT<ObjectT<I, E>>;
0190
0191 using DirectiveName = llvm::omp::Directive;
0192
0193 template <typename I, typename E>
0194 struct DefinedOperatorT {
0195 struct DefinedOpName {
0196 using WrapperTrait = std::true_type;
0197 ObjectT<I, E> v;
0198 };
0199 ENUM(IntrinsicOperator, Power, Multiply, Divide, Add, Subtract, Concat, LT,
0200 LE, EQ, NE, GE, GT, NOT, AND, OR, EQV, NEQV, Min, Max);
0201 using UnionTrait = std::true_type;
0202 std::variant<DefinedOpName, IntrinsicOperator> u;
0203 };
0204
0205
0206 template <typename E>
0207 struct RangeT {
0208
0209 using TupleTrait = std::true_type;
0210 std::tuple<E, E, OPT(E)> t;
0211 };
0212
0213
0214 template <typename TypeType, typename IdType, typename ExprType>
0215 struct IteratorSpecifierT {
0216
0217 using TupleTrait = std::true_type;
0218 std::tuple<OPT(TypeType), ObjectT<IdType, ExprType>, RangeT<ExprType>> t;
0219 };
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230 template <typename I, typename E>
0231 struct MapperT {
0232 using MapperIdentifier = ObjectT<I, E>;
0233 using WrapperTrait = std::true_type;
0234 MapperIdentifier v;
0235 };
0236
0237
0238
0239 ENUM(MemoryOrder, AcqRel, Acquire, Relaxed, Release, SeqCst);
0240 ENUM(MotionExpectation, Present);
0241
0242
0243 ENUM(DependenceType, Depobj, In, Inout, Inoutset, Mutexinoutset, Out, Sink,
0244 Source);
0245 ENUM(Prescriptiveness, Strict);
0246
0247 template <typename I, typename E>
0248 struct LoopIterationT {
0249 struct Distance {
0250 using TupleTrait = std::true_type;
0251 std::tuple<DefinedOperatorT<I, E>, E> t;
0252 };
0253 using TupleTrait = std::true_type;
0254 std::tuple<ObjectT<I, E>, OPT(Distance)> t;
0255 };
0256
0257 template <typename I, typename E>
0258 struct ProcedureDesignatorT {
0259 using WrapperTrait = std::true_type;
0260 ObjectT<I, E> v;
0261 };
0262
0263
0264
0265
0266
0267
0268
0269
0270 template <typename I, typename E>
0271 struct ReductionIdentifierT {
0272 using UnionTrait = std::true_type;
0273 std::variant<DefinedOperatorT<I, E>, ProcedureDesignatorT<I, E>> u;
0274 };
0275
0276 template <typename T, typename I, typename E>
0277 using IteratorT = ListT<IteratorSpecifierT<T, I, E>>;
0278
0279 template <typename T>
0280 std::enable_if_t<T::EmptyTrait::value, bool> operator==(const T &a,
0281 const T &b) {
0282 return true;
0283 }
0284 template <typename T>
0285 std::enable_if_t<T::IncompleteTrait::value, bool> operator==(const T &a,
0286 const T &b) {
0287 return true;
0288 }
0289 template <typename T>
0290 std::enable_if_t<T::WrapperTrait::value, bool> operator==(const T &a,
0291 const T &b) {
0292 return a.v == b.v;
0293 }
0294 template <typename T>
0295 std::enable_if_t<T::TupleTrait::value, bool> operator==(const T &a,
0296 const T &b) {
0297 return a.t == b.t;
0298 }
0299 template <typename T>
0300 std::enable_if_t<T::UnionTrait::value, bool> operator==(const T &a,
0301 const T &b) {
0302 return a.u == b.u;
0303 }
0304 }
0305
0306 template <typename T> using ListT = type::ListT<T>;
0307
0308 template <typename I, typename E> using ObjectT = type::ObjectT<I, E>;
0309 template <typename I, typename E> using ObjectListT = type::ObjectListT<I, E>;
0310
0311 template <typename T, typename I, typename E>
0312 using IteratorT = type::IteratorT<T, I, E>;
0313
0314 template <
0315 typename ContainerTy, typename FunctionTy,
0316 typename ElemTy = typename llvm::remove_cvref_t<ContainerTy>::value_type,
0317 typename ResultTy = std::invoke_result_t<FunctionTy, ElemTy>>
0318 ListT<ResultTy> makeList(ContainerTy &&container, FunctionTy &&func) {
0319 ListT<ResultTy> v;
0320 llvm::transform(container, std::back_inserter(v), func);
0321 return v;
0322 }
0323
0324 namespace clause {
0325 using type::operator==;
0326
0327
0328 template <typename T, typename I, typename E>
0329 struct AbsentT {
0330 using List = ListT<type::DirectiveName>;
0331 using WrapperTrait = std::true_type;
0332 List v;
0333 };
0334
0335
0336 template <typename T, typename I, typename E>
0337 struct AcqRelT {
0338 using EmptyTrait = std::true_type;
0339 };
0340
0341
0342 template <typename T, typename I, typename E>
0343 struct AcquireT {
0344 using EmptyTrait = std::true_type;
0345 };
0346
0347
0348 template <typename T, typename I, typename E>
0349 struct AdjustArgsT {
0350 using IncompleteTrait = std::true_type;
0351 };
0352
0353
0354 template <typename T, typename I, typename E>
0355 struct AffinityT {
0356 using Iterator = type::IteratorT<T, I, E>;
0357 using LocatorList = ObjectListT<I, E>;
0358
0359 using TupleTrait = std::true_type;
0360 std::tuple<OPT(Iterator), LocatorList> t;
0361 };
0362
0363
0364 template <typename T, typename I, typename E>
0365 struct AlignT {
0366 using Alignment = E;
0367
0368 using WrapperTrait = std::true_type;
0369 Alignment v;
0370 };
0371
0372
0373 template <typename T, typename I, typename E>
0374 struct AlignedT {
0375 using Alignment = E;
0376 using List = ObjectListT<I, E>;
0377
0378 using TupleTrait = std::true_type;
0379 std::tuple<OPT(Alignment), List> t;
0380 };
0381
0382 template <typename T, typename I, typename E>
0383 struct AllocatorT;
0384
0385
0386 template <typename T, typename I, typename E>
0387 struct AllocateT {
0388
0389 using AllocatorComplexModifier = AllocatorT<T, I, E>;
0390 using AlignModifier = AlignT<T, I, E>;
0391 using List = ObjectListT<I, E>;
0392
0393 using TupleTrait = std::true_type;
0394 std::tuple<OPT(AllocatorComplexModifier), OPT(AlignModifier), List> t;
0395 };
0396
0397
0398 template <typename T, typename I, typename E>
0399 struct AllocatorT {
0400 using Allocator = E;
0401 using WrapperTrait = std::true_type;
0402 Allocator v;
0403 };
0404
0405
0406 template <typename T, typename I, typename E>
0407 struct AppendArgsT {
0408 using IncompleteTrait = std::true_type;
0409 };
0410
0411
0412 template <typename T, typename I, typename E>
0413 struct AtT {
0414 ENUM(ActionTime, Compilation, Execution);
0415 using WrapperTrait = std::true_type;
0416 ActionTime v;
0417 };
0418
0419
0420 template <typename T, typename I, typename E>
0421 struct AtomicDefaultMemOrderT {
0422 using MemoryOrder = type::MemoryOrder;
0423 using WrapperTrait = std::true_type;
0424 MemoryOrder v;
0425 };
0426
0427
0428 template <typename T, typename I, typename E>
0429 struct BindT {
0430 ENUM(Binding, Teams, Parallel, Thread);
0431 using WrapperTrait = std::true_type;
0432 Binding v;
0433 };
0434
0435
0436 template <typename T, typename I, typename E>
0437 struct CaptureT {
0438 using EmptyTrait = std::true_type;
0439 };
0440
0441
0442 template <typename T, typename I, typename E>
0443 struct CollapseT {
0444 using N = E;
0445 using WrapperTrait = std::true_type;
0446 N v;
0447 };
0448
0449
0450 template <typename T, typename I, typename E>
0451 struct CompareT {
0452 using EmptyTrait = std::true_type;
0453 };
0454
0455
0456 template <typename T, typename I, typename E>
0457 struct ContainsT {
0458 using List = ListT<type::DirectiveName>;
0459 using WrapperTrait = std::true_type;
0460 List v;
0461 };
0462
0463
0464 template <typename T, typename I, typename E>
0465 struct CopyinT {
0466 using List = ObjectListT<I, E>;
0467 using WrapperTrait = std::true_type;
0468 List v;
0469 };
0470
0471
0472 template <typename T, typename I, typename E>
0473 struct CopyprivateT {
0474 using List = ObjectListT<I, E>;
0475 using WrapperTrait = std::true_type;
0476 List v;
0477 };
0478
0479
0480 template <typename T, typename I, typename E>
0481 struct DefaultT {
0482 ENUM(DataSharingAttribute, Firstprivate, None, Private, Shared);
0483 using WrapperTrait = std::true_type;
0484 DataSharingAttribute v;
0485 };
0486
0487
0488 template <typename T, typename I, typename E>
0489 struct DefaultmapT {
0490 ENUM(ImplicitBehavior, Alloc, To, From, Tofrom, Firstprivate, None, Default,
0491 Present);
0492 ENUM(VariableCategory, All, Scalar, Aggregate, Pointer, Allocatable);
0493 using TupleTrait = std::true_type;
0494 std::tuple<ImplicitBehavior, OPT(VariableCategory)> t;
0495 };
0496
0497 template <typename T, typename I, typename E>
0498 struct DoacrossT;
0499
0500
0501 template <typename T, typename I, typename E>
0502 struct DependT {
0503 using Iterator = type::IteratorT<T, I, E>;
0504 using LocatorList = ObjectListT<I, E>;
0505 using DependenceType = tomp::type::DependenceType;
0506
0507 struct TaskDep {
0508 using TupleTrait = std::true_type;
0509
0510 std::tuple<DependenceType, OPT(Iterator), LocatorList> t;
0511 };
0512
0513 using Doacross = DoacrossT<T, I, E>;
0514 using UnionTrait = std::true_type;
0515 std::variant<Doacross, TaskDep> u;
0516 };
0517
0518
0519 template <typename T, typename I, typename E>
0520 struct DestroyT {
0521 using DestroyVar = ObjectT<I, E>;
0522 using WrapperTrait = std::true_type;
0523
0524 OPT(DestroyVar) v;
0525 };
0526
0527
0528 template <typename T, typename I, typename E>
0529 struct DetachT {
0530 using EventHandle = ObjectT<I, E>;
0531 using WrapperTrait = std::true_type;
0532 EventHandle v;
0533 };
0534
0535
0536 template <typename T, typename I, typename E>
0537 struct DeviceT {
0538 using DeviceDescription = E;
0539 ENUM(DeviceModifier, Ancestor, DeviceNum);
0540 using TupleTrait = std::true_type;
0541 std::tuple<OPT(DeviceModifier), DeviceDescription> t;
0542 };
0543
0544
0545 template <typename T, typename I, typename E>
0546 struct DeviceTypeT {
0547 ENUM(DeviceTypeDescription, Any, Host, Nohost);
0548 using WrapperTrait = std::true_type;
0549 DeviceTypeDescription v;
0550 };
0551
0552
0553 template <typename T, typename I, typename E>
0554 struct DistScheduleT {
0555 ENUM(Kind, Static);
0556 using ChunkSize = E;
0557 using TupleTrait = std::true_type;
0558 std::tuple<Kind, OPT(ChunkSize)> t;
0559 };
0560
0561
0562 template <typename T, typename I, typename E>
0563 struct DoacrossT {
0564 using Vector = ListT<type::LoopIterationT<I, E>>;
0565 using DependenceType = tomp::type::DependenceType;
0566 using TupleTrait = std::true_type;
0567
0568 std::tuple<DependenceType, Vector> t;
0569 };
0570
0571
0572 template <typename T, typename I, typename E>
0573 struct DynamicAllocatorsT {
0574 using EmptyTrait = std::true_type;
0575 };
0576
0577
0578 template <typename T, typename I, typename E>
0579 struct EnterT {
0580 using List = ObjectListT<I, E>;
0581 using WrapperTrait = std::true_type;
0582 List v;
0583 };
0584
0585
0586 template <typename T, typename I, typename E>
0587 struct ExclusiveT {
0588 using WrapperTrait = std::true_type;
0589 using List = ObjectListT<I, E>;
0590 List v;
0591 };
0592
0593
0594 template <typename T, typename I, typename E>
0595 struct FailT {
0596 using MemoryOrder = type::MemoryOrder;
0597 using WrapperTrait = std::true_type;
0598 MemoryOrder v;
0599 };
0600
0601
0602 template <typename T, typename I, typename E>
0603 struct FilterT {
0604 using ThreadNum = E;
0605 using WrapperTrait = std::true_type;
0606 ThreadNum v;
0607 };
0608
0609
0610 template <typename T, typename I, typename E>
0611 struct FinalT {
0612 using Finalize = E;
0613 using WrapperTrait = std::true_type;
0614 Finalize v;
0615 };
0616
0617
0618 template <typename T, typename I, typename E>
0619 struct FirstprivateT {
0620 using List = ObjectListT<I, E>;
0621 using WrapperTrait = std::true_type;
0622 List v;
0623 };
0624
0625
0626 template <typename T, typename I, typename E>
0627 struct FromT {
0628 using LocatorList = ObjectListT<I, E>;
0629 using Expectation = type::MotionExpectation;
0630 using Iterator = type::IteratorT<T, I, E>;
0631
0632 using Mappers = ListT<type::MapperT<I, E>>;
0633
0634 using TupleTrait = std::true_type;
0635 std::tuple<OPT(Expectation), OPT(Mappers), OPT(Iterator), LocatorList> t;
0636 };
0637
0638
0639 template <typename T, typename I, typename E>
0640 struct FullT {
0641 using EmptyTrait = std::true_type;
0642 };
0643
0644
0645 template <typename T, typename I, typename E>
0646 struct GrainsizeT {
0647 using Prescriptiveness = type::Prescriptiveness;
0648 using GrainSize = E;
0649 using TupleTrait = std::true_type;
0650 std::tuple<OPT(Prescriptiveness), GrainSize> t;
0651 };
0652
0653
0654 template <typename T, typename I, typename E>
0655 struct HasDeviceAddrT {
0656 using List = ObjectListT<I, E>;
0657 using WrapperTrait = std::true_type;
0658 List v;
0659 };
0660
0661
0662 template <typename T, typename I, typename E>
0663 struct HintT {
0664 using HintExpr = E;
0665 using WrapperTrait = std::true_type;
0666 HintExpr v;
0667 };
0668
0669
0670 template <typename T, typename I, typename E>
0671 struct HoldsT {
0672 using WrapperTrait = std::true_type;
0673 E v;
0674 };
0675
0676
0677 template <typename T, typename I, typename E>
0678 struct IfT {
0679 using DirectiveNameModifier = type::DirectiveName;
0680 using IfExpression = E;
0681 using TupleTrait = std::true_type;
0682 std::tuple<OPT(DirectiveNameModifier), IfExpression> t;
0683 };
0684
0685
0686 template <typename T, typename I, typename E>
0687 struct InbranchT {
0688 using EmptyTrait = std::true_type;
0689 };
0690
0691
0692 template <typename T, typename I, typename E>
0693 struct InclusiveT {
0694 using List = ObjectListT<I, E>;
0695 using WrapperTrait = std::true_type;
0696 List v;
0697 };
0698
0699
0700 template <typename T, typename I, typename E>
0701 struct IndirectT {
0702 using InvokedByFptr = E;
0703 using WrapperTrait = std::true_type;
0704 InvokedByFptr v;
0705 };
0706
0707
0708 template <typename T, typename I, typename E>
0709 struct InitT {
0710 using ForeignRuntimeId = E;
0711 using InteropVar = ObjectT<I, E>;
0712 using InteropPreference = ListT<ForeignRuntimeId>;
0713 ENUM(InteropType, Target, Targetsync);
0714 using InteropTypes = ListT<InteropType>;
0715
0716 using TupleTrait = std::true_type;
0717 std::tuple<OPT(InteropPreference), InteropTypes, InteropVar> t;
0718 };
0719
0720
0721 template <typename T, typename I, typename E>
0722 struct InitializerT {
0723 using InitializerExpr = E;
0724 using WrapperTrait = std::true_type;
0725 InitializerExpr v;
0726 };
0727
0728
0729 template <typename T, typename I, typename E>
0730 struct InReductionT {
0731 using List = ObjectListT<I, E>;
0732
0733
0734 using ReductionIdentifiers = ListT<type::ReductionIdentifierT<I, E>>;
0735 using TupleTrait = std::true_type;
0736 std::tuple<ReductionIdentifiers, List> t;
0737 };
0738
0739
0740 template <typename T, typename I, typename E>
0741 struct IsDevicePtrT {
0742 using List = ObjectListT<I, E>;
0743 using WrapperTrait = std::true_type;
0744 List v;
0745 };
0746
0747
0748 template <typename T, typename I, typename E>
0749 struct LastprivateT {
0750 using List = ObjectListT<I, E>;
0751 ENUM(LastprivateModifier, Conditional);
0752 using TupleTrait = std::true_type;
0753 std::tuple<OPT(LastprivateModifier), List> t;
0754 };
0755
0756
0757 template <typename T, typename I, typename E>
0758 struct LinearT {
0759
0760 using List = ObjectListT<I, E>;
0761
0762 using StepComplexModifier = E;
0763 ENUM(LinearModifier, Ref, Val, Uval);
0764
0765 using TupleTrait = std::true_type;
0766
0767 std::tuple<OPT(StepComplexModifier), OPT(LinearModifier), List> t;
0768 };
0769
0770
0771 template <typename T, typename I, typename E>
0772 struct LinkT {
0773 using List = ObjectListT<I, E>;
0774 using WrapperTrait = std::true_type;
0775 List v;
0776 };
0777
0778
0779 template <typename T, typename I, typename E>
0780 struct MapT {
0781 using LocatorList = ObjectListT<I, E>;
0782 ENUM(MapType, To, From, Tofrom, Alloc, Release, Delete);
0783 ENUM(MapTypeModifier, Always, Close, Present, OmpxHold);
0784
0785 using Mappers = ListT<type::MapperT<I, E>>;
0786 using Iterator = type::IteratorT<T, I, E>;
0787 using MapTypeModifiers = ListT<MapTypeModifier>;
0788
0789 using TupleTrait = std::true_type;
0790 std::tuple<OPT(MapType), OPT(MapTypeModifiers), OPT(Mappers), OPT(Iterator),
0791 LocatorList>
0792 t;
0793 };
0794
0795
0796 template <typename T, typename I, typename E>
0797 struct MatchT {
0798 using IncompleteTrait = std::true_type;
0799 };
0800
0801
0802 template <typename T, typename I, typename E>
0803 struct MergeableT {
0804 using EmptyTrait = std::true_type;
0805 };
0806
0807
0808 template <typename T, typename I, typename E>
0809 struct MessageT {
0810 using MsgString = E;
0811 using WrapperTrait = std::true_type;
0812 MsgString v;
0813 };
0814
0815
0816 template <typename T, typename I, typename E>
0817 struct NocontextT {
0818 using DoNotUpdateContext = E;
0819 using WrapperTrait = std::true_type;
0820 DoNotUpdateContext v;
0821 };
0822
0823
0824 template <typename T, typename I, typename E>
0825 struct NogroupT {
0826 using EmptyTrait = std::true_type;
0827 };
0828
0829
0830 template <typename T, typename I, typename E>
0831 struct NontemporalT {
0832 using List = ObjectListT<I, E>;
0833 using WrapperTrait = std::true_type;
0834 List v;
0835 };
0836
0837
0838 template <typename T, typename I, typename E>
0839 struct NoOpenmpT {
0840 using EmptyTrait = std::true_type;
0841 };
0842
0843
0844 template <typename T, typename I, typename E>
0845 struct NoOpenmpRoutinesT {
0846 using EmptyTrait = std::true_type;
0847 };
0848
0849
0850 template <typename T, typename I, typename E>
0851 struct NoParallelismT {
0852 using EmptyTrait = std::true_type;
0853 };
0854
0855
0856 template <typename T, typename I, typename E>
0857 struct NotinbranchT {
0858 using EmptyTrait = std::true_type;
0859 };
0860
0861
0862 template <typename T, typename I, typename E>
0863 struct NovariantsT {
0864 using DoNotUseVariant = E;
0865 using WrapperTrait = std::true_type;
0866 DoNotUseVariant v;
0867 };
0868
0869
0870 template <typename T, typename I, typename E>
0871 struct NowaitT {
0872 using EmptyTrait = std::true_type;
0873 };
0874
0875
0876 template <typename T, typename I, typename E>
0877 struct NumTasksT {
0878 using Prescriptiveness = type::Prescriptiveness;
0879 using NumTasks = E;
0880 using TupleTrait = std::true_type;
0881 std::tuple<OPT(Prescriptiveness), NumTasks> t;
0882 };
0883
0884
0885 template <typename T, typename I, typename E>
0886 struct NumTeamsT {
0887 using LowerBound = E;
0888 using UpperBound = E;
0889
0890
0891 struct Range {
0892 using TupleTrait = std::true_type;
0893 std::tuple<OPT(LowerBound), UpperBound> t;
0894 };
0895
0896
0897
0898 using List = ListT<Range>;
0899 using WrapperTrait = std::true_type;
0900 List v;
0901 };
0902
0903
0904 template <typename T, typename I, typename E>
0905 struct NumThreadsT {
0906 using Nthreads = E;
0907 using WrapperTrait = std::true_type;
0908 Nthreads v;
0909 };
0910
0911 template <typename T, typename I, typename E>
0912 struct OmpxAttributeT {
0913 using EmptyTrait = std::true_type;
0914 };
0915
0916 template <typename T, typename I, typename E>
0917 struct OmpxBareT {
0918 using EmptyTrait = std::true_type;
0919 };
0920
0921 template <typename T, typename I, typename E>
0922 struct OmpxDynCgroupMemT {
0923 using WrapperTrait = std::true_type;
0924 E v;
0925 };
0926
0927
0928 template <typename T, typename I, typename E>
0929 struct OrderT {
0930 ENUM(OrderModifier, Reproducible, Unconstrained);
0931 ENUM(Ordering, Concurrent);
0932 using TupleTrait = std::true_type;
0933 std::tuple<OPT(OrderModifier), Ordering> t;
0934 };
0935
0936
0937 template <typename T, typename I, typename E>
0938 struct OrderedT {
0939 using N = E;
0940 using WrapperTrait = std::true_type;
0941 OPT(N) v;
0942 };
0943
0944
0945 template <typename T, typename I, typename E>
0946 struct OtherwiseT {
0947 using IncompleteTrait = std::true_type;
0948 };
0949
0950
0951 template <typename T, typename I, typename E>
0952 struct PartialT {
0953 using UnrollFactor = E;
0954 using WrapperTrait = std::true_type;
0955 OPT(UnrollFactor) v;
0956 };
0957
0958
0959 template <typename T, typename I, typename E>
0960 struct PermutationT {
0961 using ArgList = ListT<E>;
0962 using WrapperTrait = std::true_type;
0963 ArgList v;
0964 };
0965
0966
0967 template <typename T, typename I, typename E>
0968 struct PriorityT {
0969 using PriorityValue = E;
0970 using WrapperTrait = std::true_type;
0971 PriorityValue v;
0972 };
0973
0974
0975 template <typename T, typename I, typename E>
0976 struct PrivateT {
0977 using List = ObjectListT<I, E>;
0978 using WrapperTrait = std::true_type;
0979 List v;
0980 };
0981
0982
0983 template <typename T, typename I, typename E>
0984 struct ProcBindT {
0985 ENUM(AffinityPolicy, Close, Master, Spread, Primary);
0986 using WrapperTrait = std::true_type;
0987 AffinityPolicy v;
0988 };
0989
0990
0991 template <typename T, typename I, typename E>
0992 struct ReadT {
0993 using EmptyTrait = std::true_type;
0994 };
0995
0996
0997 template <typename T, typename I, typename E>
0998 struct ReductionT {
0999 using List = ObjectListT<I, E>;
1000
1001
1002 using ReductionIdentifiers = ListT<type::ReductionIdentifierT<I, E>>;
1003 ENUM(ReductionModifier, Default, Inscan, Task);
1004 using TupleTrait = std::true_type;
1005 std::tuple<OPT(ReductionModifier), ReductionIdentifiers, List> t;
1006 };
1007
1008
1009 template <typename T, typename I, typename E>
1010 struct RelaxedT {
1011 using EmptyTrait = std::true_type;
1012 };
1013
1014
1015 template <typename T, typename I, typename E>
1016 struct ReleaseT {
1017 using EmptyTrait = std::true_type;
1018 };
1019
1020
1021 template <typename T, typename I, typename E>
1022 struct ReverseOffloadT {
1023 using EmptyTrait = std::true_type;
1024 };
1025
1026
1027 template <typename T, typename I, typename E>
1028 struct SafelenT {
1029 using Length = E;
1030 using WrapperTrait = std::true_type;
1031 Length v;
1032 };
1033
1034
1035 template <typename T, typename I, typename E>
1036 struct ScheduleT {
1037 ENUM(Kind, Static, Dynamic, Guided, Auto, Runtime);
1038 using ChunkSize = E;
1039 ENUM(OrderingModifier, Monotonic, Nonmonotonic);
1040 ENUM(ChunkModifier, Simd);
1041 using TupleTrait = std::true_type;
1042 std::tuple<Kind, OPT(OrderingModifier), OPT(ChunkModifier), OPT(ChunkSize)> t;
1043 };
1044
1045
1046 template <typename T, typename I, typename E>
1047 struct SeqCstT {
1048 using EmptyTrait = std::true_type;
1049 };
1050
1051
1052 template <typename T, typename I, typename E>
1053 struct SeverityT {
1054 ENUM(SevLevel, Fatal, Warning);
1055 using WrapperTrait = std::true_type;
1056 SevLevel v;
1057 };
1058
1059
1060 template <typename T, typename I, typename E>
1061 struct SharedT {
1062 using List = ObjectListT<I, E>;
1063 using WrapperTrait = std::true_type;
1064 List v;
1065 };
1066
1067
1068 template <typename T, typename I, typename E>
1069 struct SimdT {
1070 using EmptyTrait = std::true_type;
1071 };
1072
1073
1074 template <typename T, typename I, typename E>
1075 struct SimdlenT {
1076 using Length = E;
1077 using WrapperTrait = std::true_type;
1078 Length v;
1079 };
1080
1081
1082 template <typename T, typename I, typename E>
1083 struct SizesT {
1084 using SizeList = ListT<E>;
1085 using WrapperTrait = std::true_type;
1086 SizeList v;
1087 };
1088
1089
1090 template <typename T, typename I, typename E>
1091 struct TaskReductionT {
1092 using List = ObjectListT<I, E>;
1093
1094
1095 using ReductionIdentifiers = ListT<type::ReductionIdentifierT<I, E>>;
1096 using TupleTrait = std::true_type;
1097 std::tuple<ReductionIdentifiers, List> t;
1098 };
1099
1100
1101 template <typename T, typename I, typename E>
1102 struct ThreadLimitT {
1103 using Threadlim = E;
1104 using WrapperTrait = std::true_type;
1105 Threadlim v;
1106 };
1107
1108
1109 template <typename T, typename I, typename E>
1110 struct ThreadsT {
1111 using EmptyTrait = std::true_type;
1112 };
1113
1114
1115 template <typename T, typename I, typename E>
1116 struct ToT {
1117 using LocatorList = ObjectListT<I, E>;
1118 using Expectation = type::MotionExpectation;
1119
1120 using Mappers = ListT<type::MapperT<I, E>>;
1121 using Iterator = type::IteratorT<T, I, E>;
1122
1123 using TupleTrait = std::true_type;
1124 std::tuple<OPT(Expectation), OPT(Mappers), OPT(Iterator), LocatorList> t;
1125 };
1126
1127
1128 template <typename T, typename I, typename E>
1129 struct UnifiedAddressT {
1130 using EmptyTrait = std::true_type;
1131 };
1132
1133
1134 template <typename T, typename I, typename E>
1135 struct UnifiedSharedMemoryT {
1136 using EmptyTrait = std::true_type;
1137 };
1138
1139
1140 template <typename T, typename I, typename E>
1141 struct UniformT {
1142 using ParameterList = ObjectListT<I, E>;
1143 using WrapperTrait = std::true_type;
1144 ParameterList v;
1145 };
1146
1147 template <typename T, typename I, typename E>
1148 struct UnknownT {
1149 using EmptyTrait = std::true_type;
1150 };
1151
1152
1153 template <typename T, typename I, typename E>
1154 struct UntiedT {
1155 using EmptyTrait = std::true_type;
1156 };
1157
1158
1159
1160
1161 template <typename T, typename I, typename E>
1162 struct UpdateT {
1163 using DependenceType = tomp::type::DependenceType;
1164 using WrapperTrait = std::true_type;
1165 OPT(DependenceType) v;
1166 };
1167
1168
1169 template <typename T, typename I, typename E>
1170 struct UseT {
1171 using InteropVar = ObjectT<I, E>;
1172 using WrapperTrait = std::true_type;
1173 InteropVar v;
1174 };
1175
1176
1177 template <typename T, typename I, typename E>
1178 struct UseDeviceAddrT {
1179 using List = ObjectListT<I, E>;
1180 using WrapperTrait = std::true_type;
1181 List v;
1182 };
1183
1184
1185 template <typename T, typename I, typename E>
1186 struct UseDevicePtrT {
1187 using List = ObjectListT<I, E>;
1188 using WrapperTrait = std::true_type;
1189 List v;
1190 };
1191
1192
1193 template <typename T, typename I, typename E>
1194 struct UsesAllocatorsT {
1195 using MemSpace = E;
1196 using TraitsArray = ObjectT<I, E>;
1197 using Allocator = E;
1198 struct AllocatorSpec {
1199 using TupleTrait = std::true_type;
1200 std::tuple<OPT(MemSpace), OPT(TraitsArray), Allocator> t;
1201 };
1202 using Allocators = ListT<AllocatorSpec>;
1203 using WrapperTrait = std::true_type;
1204 Allocators v;
1205 };
1206
1207
1208 template <typename T, typename I, typename E>
1209 struct WeakT {
1210 using EmptyTrait = std::true_type;
1211 };
1212
1213
1214 template <typename T, typename I, typename E>
1215 struct WhenT {
1216 using IncompleteTrait = std::true_type;
1217 };
1218
1219
1220 template <typename T, typename I, typename E>
1221 struct WriteT {
1222 using EmptyTrait = std::true_type;
1223 };
1224
1225
1226
1227 template <typename T, typename I, typename E>
1228 using ExtensionClausesT =
1229 std::variant<OmpxAttributeT<T, I, E>, OmpxBareT<T, I, E>,
1230 OmpxDynCgroupMemT<T, I, E>>;
1231
1232 template <typename T, typename I, typename E>
1233 using EmptyClausesT = std::variant<
1234 AcqRelT<T, I, E>, AcquireT<T, I, E>, CaptureT<T, I, E>, CompareT<T, I, E>,
1235 DynamicAllocatorsT<T, I, E>, FullT<T, I, E>, InbranchT<T, I, E>,
1236 MergeableT<T, I, E>, NogroupT<T, I, E>, NoOpenmpRoutinesT<T, I, E>,
1237 NoOpenmpT<T, I, E>, NoParallelismT<T, I, E>, NotinbranchT<T, I, E>,
1238 NowaitT<T, I, E>, ReadT<T, I, E>, RelaxedT<T, I, E>, ReleaseT<T, I, E>,
1239 ReverseOffloadT<T, I, E>, SeqCstT<T, I, E>, SimdT<T, I, E>,
1240 ThreadsT<T, I, E>, UnifiedAddressT<T, I, E>, UnifiedSharedMemoryT<T, I, E>,
1241 UnknownT<T, I, E>, UntiedT<T, I, E>, UseT<T, I, E>, WeakT<T, I, E>,
1242 WriteT<T, I, E>>;
1243
1244 template <typename T, typename I, typename E>
1245 using IncompleteClausesT =
1246 std::variant<AdjustArgsT<T, I, E>, AppendArgsT<T, I, E>, MatchT<T, I, E>,
1247 OtherwiseT<T, I, E>, WhenT<T, I, E>>;
1248
1249 template <typename T, typename I, typename E>
1250 using TupleClausesT =
1251 std::variant<AffinityT<T, I, E>, AlignedT<T, I, E>, AllocateT<T, I, E>,
1252 DefaultmapT<T, I, E>, DeviceT<T, I, E>, DistScheduleT<T, I, E>,
1253 DoacrossT<T, I, E>, FromT<T, I, E>, GrainsizeT<T, I, E>,
1254 IfT<T, I, E>, InitT<T, I, E>, InReductionT<T, I, E>,
1255 LastprivateT<T, I, E>, LinearT<T, I, E>, MapT<T, I, E>,
1256 NumTasksT<T, I, E>, OrderT<T, I, E>, ReductionT<T, I, E>,
1257 ScheduleT<T, I, E>, TaskReductionT<T, I, E>, ToT<T, I, E>>;
1258
1259 template <typename T, typename I, typename E>
1260 using UnionClausesT = std::variant<DependT<T, I, E>>;
1261
1262 template <typename T, typename I, typename E>
1263 using WrapperClausesT = std::variant<
1264 AbsentT<T, I, E>, AlignT<T, I, E>, AllocatorT<T, I, E>,
1265 AtomicDefaultMemOrderT<T, I, E>, AtT<T, I, E>, BindT<T, I, E>,
1266 CollapseT<T, I, E>, ContainsT<T, I, E>, CopyinT<T, I, E>,
1267 CopyprivateT<T, I, E>, DefaultT<T, I, E>, DestroyT<T, I, E>,
1268 DetachT<T, I, E>, DeviceTypeT<T, I, E>, EnterT<T, I, E>,
1269 ExclusiveT<T, I, E>, FailT<T, I, E>, FilterT<T, I, E>, FinalT<T, I, E>,
1270 FirstprivateT<T, I, E>, HasDeviceAddrT<T, I, E>, HintT<T, I, E>,
1271 HoldsT<T, I, E>, InclusiveT<T, I, E>, IndirectT<T, I, E>,
1272 InitializerT<T, I, E>, IsDevicePtrT<T, I, E>, LinkT<T, I, E>,
1273 MessageT<T, I, E>, NocontextT<T, I, E>, NontemporalT<T, I, E>,
1274 NovariantsT<T, I, E>, NumTeamsT<T, I, E>, NumThreadsT<T, I, E>,
1275 OrderedT<T, I, E>, PartialT<T, I, E>, PriorityT<T, I, E>, PrivateT<T, I, E>,
1276 ProcBindT<T, I, E>, SafelenT<T, I, E>, SeverityT<T, I, E>, SharedT<T, I, E>,
1277 SimdlenT<T, I, E>, SizesT<T, I, E>, PermutationT<T, I, E>,
1278 ThreadLimitT<T, I, E>, UniformT<T, I, E>, UpdateT<T, I, E>,
1279 UseDeviceAddrT<T, I, E>, UseDevicePtrT<T, I, E>, UsesAllocatorsT<T, I, E>>;
1280
1281 template <typename T, typename I, typename E>
1282 using UnionOfAllClausesT = typename type::Union<
1283 EmptyClausesT<T, I, E>,
1284 ExtensionClausesT<T, I, E>,
1285 IncompleteClausesT<T, I, E>,
1286 TupleClausesT<T, I, E>,
1287 UnionClausesT<T, I, E>,
1288 WrapperClausesT<T, I, E>
1289 >::type;
1290 }
1291
1292 using type::operator==;
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306 template <typename TypeType, typename IdType, typename ExprType,
1307 typename... Extras>
1308 struct ClauseT {
1309 using TypeTy = TypeType;
1310 using IdTy = IdType;
1311 using ExprTy = ExprType;
1312
1313
1314 using BaseT = ClauseT<TypeType, IdType, ExprType, Extras...>;
1315
1316 using VariantTy = typename type::Union<
1317 clause::UnionOfAllClausesT<TypeType, IdType, ExprType>,
1318 std::variant<Extras...>>::type;
1319
1320 llvm::omp::Clause id;
1321 using UnionTrait = std::true_type;
1322 VariantTy u;
1323 };
1324
1325 template <typename ClauseType> struct DirectiveWithClauses {
1326 llvm::omp::Directive id = llvm::omp::Directive::OMPD_unknown;
1327 tomp::type::ListT<ClauseType> clauses;
1328 };
1329
1330 }
1331
1332 #undef OPT
1333 #undef ENUM
1334
1335 #endif