1 //===--- OpenMPKinds.h - OpenMP enums ---------------------------*- C++ -*-===//
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 /// \file
10 /// Defines some OpenMP-specific enums and functions.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_BASIC_OPENMPKINDS_H
15 #define LLVM_CLANG_BASIC_OPENMPKINDS_H
16 
17 #include "clang/Basic/LangOptions.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Frontend/OpenMP/OMPConstants.h"
20 
21 namespace clang {
22 
23 /// OpenMP directives.
24 using OpenMPDirectiveKind = llvm::omp::Directive;
25 
26 /// OpenMP clauses.
27 using OpenMPClauseKind = llvm::omp::Clause;
28 
29 /// OpenMP attributes for 'schedule' clause.
30 enum OpenMPScheduleClauseKind {
31 #define OPENMP_SCHEDULE_KIND(Name) \
32   OMPC_SCHEDULE_##Name,
33 #include "clang/Basic/OpenMPKinds.def"
34   OMPC_SCHEDULE_unknown
35 };
36 
37 /// OpenMP modifiers for 'schedule' clause.
38 enum OpenMPScheduleClauseModifier {
39   OMPC_SCHEDULE_MODIFIER_unknown = OMPC_SCHEDULE_unknown,
40 #define OPENMP_SCHEDULE_MODIFIER(Name) \
41   OMPC_SCHEDULE_MODIFIER_##Name,
42 #include "clang/Basic/OpenMPKinds.def"
43   OMPC_SCHEDULE_MODIFIER_last
44 };
45 
46 /// OpenMP modifiers for 'device' clause.
47 enum OpenMPDeviceClauseModifier {
48 #define OPENMP_DEVICE_MODIFIER(Name) OMPC_DEVICE_##Name,
49 #include "clang/Basic/OpenMPKinds.def"
50   OMPC_DEVICE_unknown,
51 };
52 
53 /// OpenMP attributes for 'depend' clause.
54 enum OpenMPDependClauseKind {
55 #define OPENMP_DEPEND_KIND(Name) \
56   OMPC_DEPEND_##Name,
57 #include "clang/Basic/OpenMPKinds.def"
58   OMPC_DEPEND_unknown
59 };
60 
61 /// OpenMP attributes for 'linear' clause.
62 enum OpenMPLinearClauseKind {
63 #define OPENMP_LINEAR_KIND(Name) \
64   OMPC_LINEAR_##Name,
65 #include "clang/Basic/OpenMPKinds.def"
66   OMPC_LINEAR_unknown
67 };
68 
69 /// OpenMP mapping kind for 'map' clause.
70 enum OpenMPMapClauseKind {
71 #define OPENMP_MAP_KIND(Name) \
72   OMPC_MAP_##Name,
73 #include "clang/Basic/OpenMPKinds.def"
74   OMPC_MAP_unknown
75 };
76 
77 /// OpenMP modifier kind for 'map' clause.
78 enum OpenMPMapModifierKind {
79   OMPC_MAP_MODIFIER_unknown = OMPC_MAP_unknown,
80 #define OPENMP_MAP_MODIFIER_KIND(Name) \
81   OMPC_MAP_MODIFIER_##Name,
82 #include "clang/Basic/OpenMPKinds.def"
83   OMPC_MAP_MODIFIER_last
84 };
85 
86 /// Number of allowed map-type-modifiers.
87 static constexpr unsigned NumberOfOMPMapClauseModifiers =
88     OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1;
89 
90 /// OpenMP modifier kind for 'to' or 'from' clause.
91 enum OpenMPMotionModifierKind {
92 #define OPENMP_MOTION_MODIFIER_KIND(Name) \
93   OMPC_MOTION_MODIFIER_##Name,
94 #include "clang/Basic/OpenMPKinds.def"
95   OMPC_MOTION_MODIFIER_unknown
96 };
97 
98 /// Number of allowed motion-modifiers.
99 static constexpr unsigned NumberOfOMPMotionModifiers =
100     OMPC_MOTION_MODIFIER_unknown;
101 
102 /// OpenMP attributes for 'dist_schedule' clause.
103 enum OpenMPDistScheduleClauseKind {
104 #define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name,
105 #include "clang/Basic/OpenMPKinds.def"
106   OMPC_DIST_SCHEDULE_unknown
107 };
108 
109 /// OpenMP attributes for 'defaultmap' clause.
110 enum OpenMPDefaultmapClauseKind {
111 #define OPENMP_DEFAULTMAP_KIND(Name) \
112   OMPC_DEFAULTMAP_##Name,
113 #include "clang/Basic/OpenMPKinds.def"
114   OMPC_DEFAULTMAP_unknown
115 };
116 
117 /// OpenMP modifiers for 'defaultmap' clause.
118 enum OpenMPDefaultmapClauseModifier {
119   OMPC_DEFAULTMAP_MODIFIER_unknown = OMPC_DEFAULTMAP_unknown,
120 #define OPENMP_DEFAULTMAP_MODIFIER(Name) \
121   OMPC_DEFAULTMAP_MODIFIER_##Name,
122 #include "clang/Basic/OpenMPKinds.def"
123   OMPC_DEFAULTMAP_MODIFIER_last
124 };
125 
126 /// OpenMP attributes for 'atomic_default_mem_order' clause.
127 enum OpenMPAtomicDefaultMemOrderClauseKind {
128 #define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name)  \
129   OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name,
130 #include "clang/Basic/OpenMPKinds.def"
131   OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
132 };
133 
134 /// OpenMP attributes for 'at' clause.
135 enum OpenMPAtClauseKind {
136 #define OPENMP_AT_KIND(Name) OMPC_AT_##Name,
137 #include "clang/Basic/OpenMPKinds.def"
138   OMPC_AT_unknown
139 };
140 
141 /// OpenMP attributes for 'severity' clause.
142 enum OpenMPSeverityClauseKind {
143 #define OPENMP_SEVERITY_KIND(Name) OMPC_SEVERITY_##Name,
144 #include "clang/Basic/OpenMPKinds.def"
145   OMPC_SEVERITY_unknown
146 };
147 
148 /// OpenMP device type for 'device_type' clause.
149 enum OpenMPDeviceType {
150 #define OPENMP_DEVICE_TYPE_KIND(Name) \
151   OMPC_DEVICE_TYPE_##Name,
152 #include "clang/Basic/OpenMPKinds.def"
153   OMPC_DEVICE_TYPE_unknown
154 };
155 
156 /// OpenMP 'lastprivate' clause modifier.
157 enum OpenMPLastprivateModifier {
158 #define OPENMP_LASTPRIVATE_KIND(Name) OMPC_LASTPRIVATE_##Name,
159 #include "clang/Basic/OpenMPKinds.def"
160   OMPC_LASTPRIVATE_unknown,
161 };
162 
163 /// OpenMP attributes for 'order' clause.
164 enum OpenMPOrderClauseKind {
165 #define OPENMP_ORDER_KIND(Name) OMPC_ORDER_##Name,
166 #include "clang/Basic/OpenMPKinds.def"
167   OMPC_ORDER_unknown,
168 };
169 
170 /// OpenMP modifiers for 'order' clause.
171 enum OpenMPOrderClauseModifier {
172   OMPC_ORDER_MODIFIER_unknown = OMPC_ORDER_unknown,
173 #define OPENMP_ORDER_MODIFIER(Name) OMPC_ORDER_MODIFIER_##Name,
174 #include "clang/Basic/OpenMPKinds.def"
175   OMPC_ORDER_MODIFIER_last
176 };
177 
178 /// Scheduling data for loop-based OpenMP directives.
179 struct OpenMPScheduleTy final {
180   OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown;
181   OpenMPScheduleClauseModifier M1 = OMPC_SCHEDULE_MODIFIER_unknown;
182   OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown;
183 };
184 
185 /// OpenMP modifiers for 'reduction' clause.
186 enum OpenMPReductionClauseModifier {
187 #define OPENMP_REDUCTION_MODIFIER(Name) OMPC_REDUCTION_##Name,
188 #include "clang/Basic/OpenMPKinds.def"
189   OMPC_REDUCTION_unknown,
190 };
191 
192 /// OpenMP adjust-op kinds for 'adjust_args' clause.
193 enum OpenMPAdjustArgsOpKind {
194 #define OPENMP_ADJUST_ARGS_KIND(Name) OMPC_ADJUST_ARGS_##Name,
195 #include "clang/Basic/OpenMPKinds.def"
196   OMPC_ADJUST_ARGS_unknown,
197 };
198 
199 /// OpenMP bindings for the 'bind' clause.
200 enum OpenMPBindClauseKind {
201 #define OPENMP_BIND_KIND(Name) OMPC_BIND_##Name,
202 #include "clang/Basic/OpenMPKinds.def"
203   OMPC_BIND_unknown
204 };
205 
206 enum OpenMPGrainsizeClauseModifier {
207 #define OPENMP_GRAINSIZE_MODIFIER(Name) OMPC_GRAINSIZE_##Name,
208 #include "clang/Basic/OpenMPKinds.def"
209   OMPC_GRAINSIZE_unknown
210 };
211 
212 enum OpenMPNumTasksClauseModifier {
213 #define OPENMP_NUMTASKS_MODIFIER(Name) OMPC_NUMTASKS_##Name,
214 #include "clang/Basic/OpenMPKinds.def"
215   OMPC_NUMTASKS_unknown
216 };
217 
218 /// OpenMP dependence types for 'doacross' clause.
219 enum OpenMPDoacrossClauseModifier {
220 #define OPENMP_DOACROSS_MODIFIER(Name) OMPC_DOACROSS_##Name,
221 #include "clang/Basic/OpenMPKinds.def"
222   OMPC_DOACROSS_unknown
223 };
224 
225 /// Contains 'interop' data for 'append_args' and 'init' clauses.
226 class Expr;
227 struct OMPInteropInfo final {
228   OMPInteropInfo(bool IsTarget = false, bool IsTargetSync = false)
229       : IsTarget(IsTarget), IsTargetSync(IsTargetSync) {}
230   bool IsTarget;
231   bool IsTargetSync;
232   llvm::SmallVector<Expr *, 4> PreferTypes;
233 };
234 
235 unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str,
236                                    const LangOptions &LangOpts);
237 const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
238 
239 /// Checks if the specified directive is a directive with an associated
240 /// loop construct.
241 /// \param DKind Specified directive.
242 /// \return true - the directive is a loop-associated directive like 'omp simd'
243 /// or 'omp for' directive, otherwise - false.
244 bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind);
245 
246 /// Checks if the specified directive is a worksharing directive.
247 /// \param DKind Specified directive.
248 /// \return true - the directive is a worksharing directive like 'omp for',
249 /// otherwise - false.
250 bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind);
251 
252 /// Checks if the specified directive is a taskloop directive.
253 /// \param DKind Specified directive.
254 /// \return true - the directive is a worksharing directive like 'omp taskloop',
255 /// otherwise - false.
256 bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind);
257 
258 /// Checks if the specified directive is a parallel-kind directive.
259 /// \param DKind Specified directive.
260 /// \return true - the directive is a parallel-like directive like 'omp
261 /// parallel', otherwise - false.
262 bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind);
263 
264 /// Checks if the specified directive is a target code offload directive.
265 /// \param DKind Specified directive.
266 /// \return true - the directive is a target code offload directive like
267 /// 'omp target', 'omp target parallel', 'omp target xxx'
268 /// otherwise - false.
269 bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind);
270 
271 /// Checks if the specified directive is a target data offload directive.
272 /// \param DKind Specified directive.
273 /// \return true - the directive is a target data offload directive like
274 /// 'omp target data', 'omp target update', 'omp target enter data',
275 /// 'omp target exit data'
276 /// otherwise - false.
277 bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind);
278 
279 /// Checks if the specified composite/combined directive constitutes a teams
280 /// directive in the outermost nest.  For example
281 /// 'omp teams distribute' or 'omp teams distribute parallel for'.
282 /// \param DKind Specified directive.
283 /// \return true - the directive has teams on the outermost nest, otherwise -
284 /// false.
285 bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind);
286 
287 /// Checks if the specified directive is a teams-kind directive.  For example,
288 /// 'omp teams distribute' or 'omp target teams'.
289 /// \param DKind Specified directive.
290 /// \return true - the directive is a teams-like directive, otherwise - false.
291 bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind);
292 
293 /// Checks if the specified directive is a simd directive.
294 /// \param DKind Specified directive.
295 /// \return true - the directive is a simd directive like 'omp simd',
296 /// otherwise - false.
297 bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind);
298 
299 /// Checks if the specified directive is a distribute directive.
300 /// \param DKind Specified directive.
301 /// \return true - the directive is a distribute-directive like 'omp
302 /// distribute',
303 /// otherwise - false.
304 bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind);
305 
306 /// Checks if the specified composite/combined directive constitutes a
307 /// distribute directive in the outermost nest.  For example,
308 /// 'omp distribute parallel for' or 'omp distribute'.
309 /// \param DKind Specified directive.
310 /// \return true - the directive has distribute on the outermost nest.
311 /// otherwise - false.
312 bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind);
313 
314 /// Checks if the specified directive constitutes a 'loop' directive in the
315 /// outermost nest.  For example, 'omp teams loop' or 'omp loop'.
316 /// \param DKind Specified directive.
317 /// \return true - the directive has loop on the outermost nest.
318 /// otherwise - false.
319 bool isOpenMPGenericLoopDirective(OpenMPDirectiveKind DKind);
320 
321 /// Checks if the specified clause is one of private clauses like
322 /// 'private', 'firstprivate', 'reduction' etc..
323 /// \param Kind Clause kind.
324 /// \return true - the clause is a private clause, otherwise - false.
325 bool isOpenMPPrivate(OpenMPClauseKind Kind);
326 
327 /// Checks if the specified clause is one of threadprivate clauses like
328 /// 'threadprivate', 'copyin' or 'copyprivate'.
329 /// \param Kind Clause kind.
330 /// \return true - the clause is a threadprivate clause, otherwise - false.
331 bool isOpenMPThreadPrivate(OpenMPClauseKind Kind);
332 
333 /// Checks if the specified directive kind is one of tasking directives - task,
334 /// taskloop, taksloop simd, master taskloop, parallel master taskloop, master
335 /// taskloop simd, or parallel master taskloop simd.
336 bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind);
337 
338 /// Checks if the specified directive kind is one of the composite or combined
339 /// directives that need loop bound sharing across loops outlined in nested
340 /// functions
341 bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind);
342 
343 /// Checks if the specified directive is a loop transformation directive.
344 /// \param DKind Specified directive.
345 /// \return True iff the directive is a loop transformation.
346 bool isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind);
347 
348 /// Return the captured regions of an OpenMP directive.
349 void getOpenMPCaptureRegions(
350     llvm::SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
351     OpenMPDirectiveKind DKind);
352 
353 /// Checks if the specified directive is a combined construct for which
354 /// the first construct is a parallel construct.
355 /// \param DKind Specified directive.
356 /// \return true - if the above condition is met for this directive
357 /// otherwise - false.
358 bool isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind);
359 }
360 
361 #endif
362 
363