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