10b57cec5SDimitry Andric //===--- OpenMPKinds.h - OpenMP enums ---------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Defines some OpenMP-specific enums and functions.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_CLANG_BASIC_OPENMPKINDS_H
150b57cec5SDimitry Andric #define LLVM_CLANG_BASIC_OPENMPKINDS_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
18480093f4SDimitry Andric #include "llvm/Frontend/OpenMP/OMPConstants.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric namespace clang {
210b57cec5SDimitry Andric 
22480093f4SDimitry Andric /// OpenMP directives.
23480093f4SDimitry Andric using OpenMPDirectiveKind = llvm::omp::Directive;
24480093f4SDimitry Andric 
250b57cec5SDimitry Andric /// OpenMP clauses.
265ffd83dbSDimitry Andric using OpenMPClauseKind = llvm::omp::Clause;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric /// OpenMP attributes for 'schedule' clause.
290b57cec5SDimitry Andric enum OpenMPScheduleClauseKind {
300b57cec5SDimitry Andric #define OPENMP_SCHEDULE_KIND(Name) \
310b57cec5SDimitry Andric   OMPC_SCHEDULE_##Name,
320b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
330b57cec5SDimitry Andric   OMPC_SCHEDULE_unknown
340b57cec5SDimitry Andric };
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric /// OpenMP modifiers for 'schedule' clause.
370b57cec5SDimitry Andric enum OpenMPScheduleClauseModifier {
380b57cec5SDimitry Andric   OMPC_SCHEDULE_MODIFIER_unknown = OMPC_SCHEDULE_unknown,
390b57cec5SDimitry Andric #define OPENMP_SCHEDULE_MODIFIER(Name) \
400b57cec5SDimitry Andric   OMPC_SCHEDULE_MODIFIER_##Name,
410b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
420b57cec5SDimitry Andric   OMPC_SCHEDULE_MODIFIER_last
430b57cec5SDimitry Andric };
440b57cec5SDimitry Andric 
455ffd83dbSDimitry Andric /// OpenMP modifiers for 'device' clause.
465ffd83dbSDimitry Andric enum OpenMPDeviceClauseModifier {
475ffd83dbSDimitry Andric #define OPENMP_DEVICE_MODIFIER(Name) OMPC_DEVICE_##Name,
485ffd83dbSDimitry Andric #include "clang/Basic/OpenMPKinds.def"
495ffd83dbSDimitry Andric   OMPC_DEVICE_unknown,
505ffd83dbSDimitry Andric };
515ffd83dbSDimitry Andric 
520b57cec5SDimitry Andric /// OpenMP attributes for 'depend' clause.
530b57cec5SDimitry Andric enum OpenMPDependClauseKind {
540b57cec5SDimitry Andric #define OPENMP_DEPEND_KIND(Name) \
550b57cec5SDimitry Andric   OMPC_DEPEND_##Name,
560b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
570b57cec5SDimitry Andric   OMPC_DEPEND_unknown
580b57cec5SDimitry Andric };
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric /// OpenMP attributes for 'linear' clause.
610b57cec5SDimitry Andric enum OpenMPLinearClauseKind {
620b57cec5SDimitry Andric #define OPENMP_LINEAR_KIND(Name) \
630b57cec5SDimitry Andric   OMPC_LINEAR_##Name,
640b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
650b57cec5SDimitry Andric   OMPC_LINEAR_unknown
660b57cec5SDimitry Andric };
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric /// OpenMP mapping kind for 'map' clause.
690b57cec5SDimitry Andric enum OpenMPMapClauseKind {
700b57cec5SDimitry Andric #define OPENMP_MAP_KIND(Name) \
710b57cec5SDimitry Andric   OMPC_MAP_##Name,
720b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
730b57cec5SDimitry Andric   OMPC_MAP_unknown
740b57cec5SDimitry Andric };
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric /// OpenMP modifier kind for 'map' clause.
770b57cec5SDimitry Andric enum OpenMPMapModifierKind {
780b57cec5SDimitry Andric   OMPC_MAP_MODIFIER_unknown = OMPC_MAP_unknown,
790b57cec5SDimitry Andric #define OPENMP_MAP_MODIFIER_KIND(Name) \
800b57cec5SDimitry Andric   OMPC_MAP_MODIFIER_##Name,
810b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
820b57cec5SDimitry Andric   OMPC_MAP_MODIFIER_last
830b57cec5SDimitry Andric };
840b57cec5SDimitry Andric 
855ffd83dbSDimitry Andric   /// Number of allowed map-type-modifiers.
865ffd83dbSDimitry Andric static constexpr unsigned NumberOfOMPMapClauseModifiers =
875ffd83dbSDimitry Andric     OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1;
885ffd83dbSDimitry Andric 
89e8d8bef9SDimitry Andric /// OpenMP modifier kind for 'to' or 'from' clause.
90e8d8bef9SDimitry Andric enum OpenMPMotionModifierKind {
91e8d8bef9SDimitry Andric #define OPENMP_MOTION_MODIFIER_KIND(Name) \
92e8d8bef9SDimitry Andric   OMPC_MOTION_MODIFIER_##Name,
930b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
94e8d8bef9SDimitry Andric   OMPC_MOTION_MODIFIER_unknown
950b57cec5SDimitry Andric };
960b57cec5SDimitry Andric 
97e8d8bef9SDimitry Andric /// Number of allowed motion-modifiers.
98e8d8bef9SDimitry Andric static constexpr unsigned NumberOfOMPMotionModifiers =
99e8d8bef9SDimitry Andric     OMPC_MOTION_MODIFIER_unknown;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric /// OpenMP attributes for 'dist_schedule' clause.
1020b57cec5SDimitry Andric enum OpenMPDistScheduleClauseKind {
1030b57cec5SDimitry Andric #define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name,
1040b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
1050b57cec5SDimitry Andric   OMPC_DIST_SCHEDULE_unknown
1060b57cec5SDimitry Andric };
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric /// OpenMP attributes for 'defaultmap' clause.
1090b57cec5SDimitry Andric enum OpenMPDefaultmapClauseKind {
1100b57cec5SDimitry Andric #define OPENMP_DEFAULTMAP_KIND(Name) \
1110b57cec5SDimitry Andric   OMPC_DEFAULTMAP_##Name,
1120b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
1130b57cec5SDimitry Andric   OMPC_DEFAULTMAP_unknown
1140b57cec5SDimitry Andric };
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric /// OpenMP modifiers for 'defaultmap' clause.
1170b57cec5SDimitry Andric enum OpenMPDefaultmapClauseModifier {
1180b57cec5SDimitry Andric   OMPC_DEFAULTMAP_MODIFIER_unknown = OMPC_DEFAULTMAP_unknown,
1190b57cec5SDimitry Andric #define OPENMP_DEFAULTMAP_MODIFIER(Name) \
1200b57cec5SDimitry Andric   OMPC_DEFAULTMAP_MODIFIER_##Name,
1210b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
1220b57cec5SDimitry Andric   OMPC_DEFAULTMAP_MODIFIER_last
1230b57cec5SDimitry Andric };
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric /// OpenMP attributes for 'atomic_default_mem_order' clause.
1260b57cec5SDimitry Andric enum OpenMPAtomicDefaultMemOrderClauseKind {
1270b57cec5SDimitry Andric #define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name)  \
1280b57cec5SDimitry Andric   OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name,
1290b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
1300b57cec5SDimitry Andric   OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
1310b57cec5SDimitry Andric };
1320b57cec5SDimitry Andric 
133a7dea167SDimitry Andric /// OpenMP device type for 'device_type' clause.
134a7dea167SDimitry Andric enum OpenMPDeviceType {
135a7dea167SDimitry Andric #define OPENMP_DEVICE_TYPE_KIND(Name) \
136a7dea167SDimitry Andric   OMPC_DEVICE_TYPE_##Name,
137a7dea167SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
138a7dea167SDimitry Andric   OMPC_DEVICE_TYPE_unknown
139a7dea167SDimitry Andric };
140a7dea167SDimitry Andric 
141480093f4SDimitry Andric /// OpenMP 'lastprivate' clause modifier.
142480093f4SDimitry Andric enum OpenMPLastprivateModifier {
143480093f4SDimitry Andric #define OPENMP_LASTPRIVATE_KIND(Name) OMPC_LASTPRIVATE_##Name,
144480093f4SDimitry Andric #include "clang/Basic/OpenMPKinds.def"
145480093f4SDimitry Andric   OMPC_LASTPRIVATE_unknown,
146480093f4SDimitry Andric };
147480093f4SDimitry Andric 
1485ffd83dbSDimitry Andric /// OpenMP attributes for 'order' clause.
1495ffd83dbSDimitry Andric enum OpenMPOrderClauseKind {
1505ffd83dbSDimitry Andric #define OPENMP_ORDER_KIND(Name) OMPC_ORDER_##Name,
1515ffd83dbSDimitry Andric #include "clang/Basic/OpenMPKinds.def"
1525ffd83dbSDimitry Andric   OMPC_ORDER_unknown,
1535ffd83dbSDimitry Andric };
1545ffd83dbSDimitry Andric 
1550b57cec5SDimitry Andric /// Scheduling data for loop-based OpenMP directives.
1560b57cec5SDimitry Andric struct OpenMPScheduleTy final {
1570b57cec5SDimitry Andric   OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown;
1580b57cec5SDimitry Andric   OpenMPScheduleClauseModifier M1 = OMPC_SCHEDULE_MODIFIER_unknown;
1590b57cec5SDimitry Andric   OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown;
1600b57cec5SDimitry Andric };
1610b57cec5SDimitry Andric 
1625ffd83dbSDimitry Andric /// OpenMP modifiers for 'reduction' clause.
1635ffd83dbSDimitry Andric enum OpenMPReductionClauseModifier {
1645ffd83dbSDimitry Andric #define OPENMP_REDUCTION_MODIFIER(Name) OMPC_REDUCTION_##Name,
1655ffd83dbSDimitry Andric #include "clang/Basic/OpenMPKinds.def"
1665ffd83dbSDimitry Andric   OMPC_REDUCTION_unknown,
1675ffd83dbSDimitry Andric };
1680b57cec5SDimitry Andric 
169e8d8bef9SDimitry Andric unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str,
170e8d8bef9SDimitry Andric                                    unsigned OpenMPVersion);
1710b57cec5SDimitry Andric const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
1720b57cec5SDimitry Andric 
1730b57cec5SDimitry Andric /// Checks if the specified directive is a directive with an associated
1740b57cec5SDimitry Andric /// loop construct.
1750b57cec5SDimitry Andric /// \param DKind Specified directive.
1760b57cec5SDimitry Andric /// \return true - the directive is a loop-associated directive like 'omp simd'
1770b57cec5SDimitry Andric /// or 'omp for' directive, otherwise - false.
1780b57cec5SDimitry Andric bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind);
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric /// Checks if the specified directive is a worksharing directive.
1810b57cec5SDimitry Andric /// \param DKind Specified directive.
1820b57cec5SDimitry Andric /// \return true - the directive is a worksharing directive like 'omp for',
1830b57cec5SDimitry Andric /// otherwise - false.
1840b57cec5SDimitry Andric bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind);
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric /// Checks if the specified directive is a taskloop directive.
1870b57cec5SDimitry Andric /// \param DKind Specified directive.
1880b57cec5SDimitry Andric /// \return true - the directive is a worksharing directive like 'omp taskloop',
1890b57cec5SDimitry Andric /// otherwise - false.
1900b57cec5SDimitry Andric bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
1910b57cec5SDimitry Andric 
1920b57cec5SDimitry Andric /// Checks if the specified directive is a parallel-kind directive.
1930b57cec5SDimitry Andric /// \param DKind Specified directive.
1940b57cec5SDimitry Andric /// \return true - the directive is a parallel-like directive like 'omp
1950b57cec5SDimitry Andric /// parallel', otherwise - false.
1960b57cec5SDimitry Andric bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric /// Checks if the specified directive is a target code offload directive.
1990b57cec5SDimitry Andric /// \param DKind Specified directive.
2000b57cec5SDimitry Andric /// \return true - the directive is a target code offload directive like
2010b57cec5SDimitry Andric /// 'omp target', 'omp target parallel', 'omp target xxx'
2020b57cec5SDimitry Andric /// otherwise - false.
2030b57cec5SDimitry Andric bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind);
2040b57cec5SDimitry Andric 
2050b57cec5SDimitry Andric /// Checks if the specified directive is a target data offload directive.
2060b57cec5SDimitry Andric /// \param DKind Specified directive.
2070b57cec5SDimitry Andric /// \return true - the directive is a target data offload directive like
2080b57cec5SDimitry Andric /// 'omp target data', 'omp target update', 'omp target enter data',
2090b57cec5SDimitry Andric /// 'omp target exit data'
2100b57cec5SDimitry Andric /// otherwise - false.
2110b57cec5SDimitry Andric bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind);
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric /// Checks if the specified composite/combined directive constitutes a teams
2140b57cec5SDimitry Andric /// directive in the outermost nest.  For example
2150b57cec5SDimitry Andric /// 'omp teams distribute' or 'omp teams distribute parallel for'.
2160b57cec5SDimitry Andric /// \param DKind Specified directive.
2170b57cec5SDimitry Andric /// \return true - the directive has teams on the outermost nest, otherwise -
2180b57cec5SDimitry Andric /// false.
2190b57cec5SDimitry Andric bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind);
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric /// Checks if the specified directive is a teams-kind directive.  For example,
2220b57cec5SDimitry Andric /// 'omp teams distribute' or 'omp target teams'.
2230b57cec5SDimitry Andric /// \param DKind Specified directive.
2240b57cec5SDimitry Andric /// \return true - the directive is a teams-like directive, otherwise - false.
2250b57cec5SDimitry Andric bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind);
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric /// Checks if the specified directive is a simd directive.
2280b57cec5SDimitry Andric /// \param DKind Specified directive.
2290b57cec5SDimitry Andric /// \return true - the directive is a simd directive like 'omp simd',
2300b57cec5SDimitry Andric /// otherwise - false.
2310b57cec5SDimitry Andric bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind);
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric /// Checks if the specified directive is a distribute directive.
2340b57cec5SDimitry Andric /// \param DKind Specified directive.
2350b57cec5SDimitry Andric /// \return true - the directive is a distribute-directive like 'omp
2360b57cec5SDimitry Andric /// distribute',
2370b57cec5SDimitry Andric /// otherwise - false.
2380b57cec5SDimitry Andric bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind);
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric /// Checks if the specified composite/combined directive constitutes a
2410b57cec5SDimitry Andric /// distribute directive in the outermost nest.  For example,
2420b57cec5SDimitry Andric /// 'omp distribute parallel for' or 'omp distribute'.
2430b57cec5SDimitry Andric /// \param DKind Specified directive.
2440b57cec5SDimitry Andric /// \return true - the directive has distribute on the outermost nest.
2450b57cec5SDimitry Andric /// otherwise - false.
2460b57cec5SDimitry Andric bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind);
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric /// Checks if the specified clause is one of private clauses like
2490b57cec5SDimitry Andric /// 'private', 'firstprivate', 'reduction' etc..
2500b57cec5SDimitry Andric /// \param Kind Clause kind.
2510b57cec5SDimitry Andric /// \return true - the clause is a private clause, otherwise - false.
2520b57cec5SDimitry Andric bool isOpenMPPrivate(OpenMPClauseKind Kind);
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric /// Checks if the specified clause is one of threadprivate clauses like
2550b57cec5SDimitry Andric /// 'threadprivate', 'copyin' or 'copyprivate'.
2560b57cec5SDimitry Andric /// \param Kind Clause kind.
2570b57cec5SDimitry Andric /// \return true - the clause is a threadprivate clause, otherwise - false.
2580b57cec5SDimitry Andric bool isOpenMPThreadPrivate(OpenMPClauseKind Kind);
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric /// Checks if the specified directive kind is one of tasking directives - task,
261480093f4SDimitry Andric /// taskloop, taksloop simd, master taskloop, parallel master taskloop, master
262480093f4SDimitry Andric /// taskloop simd, or parallel master taskloop simd.
2630b57cec5SDimitry Andric bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind);
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric /// Checks if the specified directive kind is one of the composite or combined
2660b57cec5SDimitry Andric /// directives that need loop bound sharing across loops outlined in nested
2670b57cec5SDimitry Andric /// functions
2680b57cec5SDimitry Andric bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind);
2690b57cec5SDimitry Andric 
270fe6060f1SDimitry Andric /// Checks if the specified directive is a loop transformation directive.
271fe6060f1SDimitry Andric /// \param DKind Specified directive.
272fe6060f1SDimitry Andric /// \return True iff the directive is a loop transformation.
273fe6060f1SDimitry Andric bool isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind);
274fe6060f1SDimitry Andric 
2750b57cec5SDimitry Andric /// Return the captured regions of an OpenMP directive.
2760b57cec5SDimitry Andric void getOpenMPCaptureRegions(
2770b57cec5SDimitry Andric     llvm::SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
2780b57cec5SDimitry Andric     OpenMPDirectiveKind DKind);
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric #endif
2820b57cec5SDimitry Andric 
283