1 //===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 /// This file implements the OpenMP enum and support functions.
11 //===----------------------------------------------------------------------===//
13 #include "clang/Basic/OpenMPKinds.h"
14 #include "clang/Basic/IdentifierTable.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/Support/ErrorHandling.h"
20 using namespace clang
;
21 using namespace llvm::omp
;
23 unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind
, StringRef Str
,
24 const LangOptions
&LangOpts
) {
27 return llvm::StringSwitch
<unsigned>(Str
)
28 #define OMP_DEFAULT_KIND(Enum, Name) .Case(Name, unsigned(Enum))
29 #include "llvm/Frontend/OpenMP/OMPKinds.def"
30 .Default(unsigned(llvm::omp::OMP_DEFAULT_unknown
));
32 return llvm::StringSwitch
<unsigned>(Str
)
33 #define OMP_PROC_BIND_KIND(Enum, Name, Value) .Case(Name, Value)
34 #include "llvm/Frontend/OpenMP/OMPKinds.def"
35 .Default(unsigned(llvm::omp::OMP_PROC_BIND_unknown
));
37 return llvm::StringSwitch
<unsigned>(Str
)
38 #define OPENMP_SCHEDULE_KIND(Name) \
39 .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_##Name))
40 #define OPENMP_SCHEDULE_MODIFIER(Name) \
41 .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_MODIFIER_##Name))
42 #include "clang/Basic/OpenMPKinds.def"
43 .Default(OMPC_SCHEDULE_unknown
);
45 unsigned Type
= llvm::StringSwitch
<unsigned>(Str
)
46 #define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)
47 #include "clang/Basic/OpenMPKinds.def"
48 .Default(OMPC_DEPEND_unknown
);
49 if (LangOpts
.OpenMP
< 51 && Type
== OMPC_DEPEND_inoutset
)
50 return OMPC_DEPEND_unknown
;
54 return llvm::StringSwitch
<OpenMPDoacrossClauseModifier
>(Str
)
55 #define OPENMP_DOACROSS_MODIFIER(Name) .Case(#Name, OMPC_DOACROSS_##Name)
56 #include "clang/Basic/OpenMPKinds.def"
57 .Default(OMPC_DOACROSS_unknown
);
59 return llvm::StringSwitch
<OpenMPLinearClauseKind
>(Str
)
60 #define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name)
61 #include "clang/Basic/OpenMPKinds.def"
62 .Default(OMPC_LINEAR_unknown
);
64 unsigned Type
= llvm::StringSwitch
<unsigned>(Str
)
65 #define OPENMP_MAP_KIND(Name) \
66 .Case(#Name, static_cast<unsigned>(OMPC_MAP_##Name))
67 #define OPENMP_MAP_MODIFIER_KIND(Name) \
68 .Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name))
69 #include "clang/Basic/OpenMPKinds.def"
70 .Default(OMPC_MAP_unknown
);
71 if (LangOpts
.OpenMP
< 51 && Type
== OMPC_MAP_MODIFIER_present
)
72 return OMPC_MAP_MODIFIER_unknown
;
73 if (!LangOpts
.OpenMPExtensions
&& Type
== OMPC_MAP_MODIFIER_ompx_hold
)
74 return OMPC_MAP_MODIFIER_unknown
;
79 unsigned Type
= llvm::StringSwitch
<unsigned>(Str
)
80 #define OPENMP_MOTION_MODIFIER_KIND(Name) \
81 .Case(#Name, static_cast<unsigned>(OMPC_MOTION_MODIFIER_##Name))
82 #include "clang/Basic/OpenMPKinds.def"
83 .Default(OMPC_MOTION_MODIFIER_unknown
);
84 if (LangOpts
.OpenMP
< 51 && Type
== OMPC_MOTION_MODIFIER_present
)
85 return OMPC_MOTION_MODIFIER_unknown
;
88 case OMPC_dist_schedule
:
89 return llvm::StringSwitch
<OpenMPDistScheduleClauseKind
>(Str
)
90 #define OPENMP_DIST_SCHEDULE_KIND(Name) .Case(#Name, OMPC_DIST_SCHEDULE_##Name)
91 #include "clang/Basic/OpenMPKinds.def"
92 .Default(OMPC_DIST_SCHEDULE_unknown
);
94 return llvm::StringSwitch
<unsigned>(Str
)
95 #define OPENMP_DEFAULTMAP_KIND(Name) \
96 .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_##Name))
97 #define OPENMP_DEFAULTMAP_MODIFIER(Name) \
98 .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_MODIFIER_##Name))
99 #include "clang/Basic/OpenMPKinds.def"
100 .Default(OMPC_DEFAULTMAP_unknown
);
101 case OMPC_atomic_default_mem_order
:
102 return llvm::StringSwitch
<OpenMPAtomicDefaultMemOrderClauseKind
>(Str
)
103 #define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \
104 .Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name)
105 #include "clang/Basic/OpenMPKinds.def"
106 .Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
);
108 return static_cast<unsigned int>(llvm::StringSwitch
<llvm::omp::Clause
>(Str
)
109 #define OPENMP_ATOMIC_FAIL_MODIFIER(Name) .Case(#Name, OMPC_##Name)
110 #include "clang/Basic/OpenMPKinds.def"
111 .Default(OMPC_unknown
));
112 case OMPC_device_type
:
113 return llvm::StringSwitch
<OpenMPDeviceType
>(Str
)
114 #define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name)
115 #include "clang/Basic/OpenMPKinds.def"
116 .Default(OMPC_DEVICE_TYPE_unknown
);
118 return llvm::StringSwitch
<OpenMPAtClauseKind
>(Str
)
119 #define OPENMP_AT_KIND(Name) .Case(#Name, OMPC_AT_##Name)
120 #include "clang/Basic/OpenMPKinds.def"
121 .Default(OMPC_AT_unknown
);
123 return llvm::StringSwitch
<OpenMPSeverityClauseKind
>(Str
)
124 #define OPENMP_SEVERITY_KIND(Name) .Case(#Name, OMPC_SEVERITY_##Name)
125 #include "clang/Basic/OpenMPKinds.def"
126 .Default(OMPC_SEVERITY_unknown
);
127 case OMPC_lastprivate
:
128 return llvm::StringSwitch
<OpenMPLastprivateModifier
>(Str
)
129 #define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name)
130 #include "clang/Basic/OpenMPKinds.def"
131 .Default(OMPC_LASTPRIVATE_unknown
);
133 return llvm::StringSwitch
<unsigned>(Str
)
134 #define OPENMP_ORDER_KIND(Name) \
135 .Case(#Name, static_cast<unsigned>(OMPC_ORDER_##Name))
136 #define OPENMP_ORDER_MODIFIER(Name) \
137 .Case(#Name, static_cast<unsigned>(OMPC_ORDER_MODIFIER_##Name))
138 #include "clang/Basic/OpenMPKinds.def"
139 .Default(OMPC_ORDER_unknown
);
141 return llvm::StringSwitch
<OpenMPDependClauseKind
>(Str
)
142 #define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)
143 #include "clang/Basic/OpenMPKinds.def"
144 .Default(OMPC_DEPEND_unknown
);
146 return llvm::StringSwitch
<OpenMPDeviceClauseModifier
>(Str
)
147 #define OPENMP_DEVICE_MODIFIER(Name) .Case(#Name, OMPC_DEVICE_##Name)
148 #include "clang/Basic/OpenMPKinds.def"
149 .Default(OMPC_DEVICE_unknown
);
151 return llvm::StringSwitch
<OpenMPReductionClauseModifier
>(Str
)
152 #define OPENMP_REDUCTION_MODIFIER(Name) .Case(#Name, OMPC_REDUCTION_##Name)
153 #include "clang/Basic/OpenMPKinds.def"
154 .Default(OMPC_REDUCTION_unknown
);
155 case OMPC_adjust_args
:
156 return llvm::StringSwitch
<OpenMPAdjustArgsOpKind
>(Str
)
157 #define OPENMP_ADJUST_ARGS_KIND(Name) .Case(#Name, OMPC_ADJUST_ARGS_##Name)
158 #include "clang/Basic/OpenMPKinds.def"
159 .Default(OMPC_ADJUST_ARGS_unknown
);
161 return llvm::StringSwitch
<unsigned>(Str
)
162 #define OPENMP_BIND_KIND(Name) .Case(#Name, OMPC_BIND_##Name)
163 #include "clang/Basic/OpenMPKinds.def"
164 .Default(OMPC_BIND_unknown
);
165 case OMPC_grainsize
: {
166 unsigned Type
= llvm::StringSwitch
<unsigned>(Str
)
167 #define OPENMP_GRAINSIZE_MODIFIER(Name) .Case(#Name, OMPC_GRAINSIZE_##Name)
168 #include "clang/Basic/OpenMPKinds.def"
169 .Default(OMPC_GRAINSIZE_unknown
);
170 if (LangOpts
.OpenMP
< 51)
171 return OMPC_GRAINSIZE_unknown
;
174 case OMPC_num_tasks
: {
175 unsigned Type
= llvm::StringSwitch
<unsigned>(Str
)
176 #define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name)
177 #include "clang/Basic/OpenMPKinds.def"
178 .Default(OMPC_NUMTASKS_unknown
);
179 if (LangOpts
.OpenMP
< 51)
180 return OMPC_NUMTASKS_unknown
;
184 return llvm::StringSwitch
<OpenMPAllocateClauseModifier
>(Str
)
185 #define OPENMP_ALLOCATE_MODIFIER(Name) .Case(#Name, OMPC_ALLOCATE_##Name)
186 #include "clang/Basic/OpenMPKinds.def"
187 .Default(OMPC_ALLOCATE_unknown
);
189 case OMPC_threadprivate
:
192 case OMPC_num_threads
:
196 case OMPC_permutation
:
200 case OMPC_firstprivate
:
202 case OMPC_task_reduction
:
203 case OMPC_in_reduction
:
206 case OMPC_copyprivate
:
225 case OMPC_thread_limit
:
230 case OMPC_use_device_ptr
:
231 case OMPC_use_device_addr
:
232 case OMPC_is_device_ptr
:
233 case OMPC_has_device_addr
:
234 case OMPC_unified_address
:
235 case OMPC_unified_shared_memory
:
236 case OMPC_reverse_offload
:
237 case OMPC_dynamic_allocators
:
239 case OMPC_nontemporal
:
241 case OMPC_novariants
:
246 case OMPC_uses_allocators
:
249 case OMPC_append_args
:
254 llvm_unreachable("Invalid OpenMP simple clause kind");
257 const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind
,
261 switch (llvm::omp::DefaultKind(Type
)) {
262 #define OMP_DEFAULT_KIND(Enum, Name) \
265 #include "llvm/Frontend/OpenMP/OMPKinds.def"
267 llvm_unreachable("Invalid OpenMP 'default' clause type");
270 #define OMP_PROC_BIND_KIND(Enum, Name, Value) \
273 #include "llvm/Frontend/OpenMP/OMPKinds.def"
275 llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
278 case OMPC_SCHEDULE_unknown
:
279 case OMPC_SCHEDULE_MODIFIER_last
:
281 #define OPENMP_SCHEDULE_KIND(Name) \
282 case OMPC_SCHEDULE_##Name: \
284 #define OPENMP_SCHEDULE_MODIFIER(Name) \
285 case OMPC_SCHEDULE_MODIFIER_##Name: \
287 #include "clang/Basic/OpenMPKinds.def"
289 llvm_unreachable("Invalid OpenMP 'schedule' clause type");
292 case OMPC_DEPEND_unknown
:
294 #define OPENMP_DEPEND_KIND(Name) \
295 case OMPC_DEPEND_##Name: \
297 #include "clang/Basic/OpenMPKinds.def"
299 llvm_unreachable("Invalid OpenMP 'depend' clause type");
302 case OMPC_DOACROSS_unknown
:
304 #define OPENMP_DOACROSS_MODIFIER(Name) \
305 case OMPC_DOACROSS_##Name: \
307 #include "clang/Basic/OpenMPKinds.def"
309 llvm_unreachable("Invalid OpenMP 'doacross' clause type");
312 case OMPC_LINEAR_unknown
:
314 #define OPENMP_LINEAR_KIND(Name) \
315 case OMPC_LINEAR_##Name: \
317 #include "clang/Basic/OpenMPKinds.def"
319 llvm_unreachable("Invalid OpenMP 'linear' clause type");
322 case OMPC_MAP_unknown
:
323 case OMPC_MAP_MODIFIER_last
:
325 #define OPENMP_MAP_KIND(Name) \
326 case OMPC_MAP_##Name: \
328 #define OPENMP_MAP_MODIFIER_KIND(Name) \
329 case OMPC_MAP_MODIFIER_##Name: \
331 #include "clang/Basic/OpenMPKinds.def"
335 llvm_unreachable("Invalid OpenMP 'map' clause type");
339 case OMPC_MOTION_MODIFIER_unknown
:
341 #define OPENMP_MOTION_MODIFIER_KIND(Name) \
342 case OMPC_MOTION_MODIFIER_##Name: \
344 #include "clang/Basic/OpenMPKinds.def"
348 llvm_unreachable("Invalid OpenMP 'to' or 'from' clause type");
349 case OMPC_dist_schedule
:
351 case OMPC_DIST_SCHEDULE_unknown
:
353 #define OPENMP_DIST_SCHEDULE_KIND(Name) \
354 case OMPC_DIST_SCHEDULE_##Name: \
356 #include "clang/Basic/OpenMPKinds.def"
358 llvm_unreachable("Invalid OpenMP 'dist_schedule' clause type");
359 case OMPC_defaultmap
:
361 case OMPC_DEFAULTMAP_unknown
:
362 case OMPC_DEFAULTMAP_MODIFIER_last
:
364 #define OPENMP_DEFAULTMAP_KIND(Name) \
365 case OMPC_DEFAULTMAP_##Name: \
367 #define OPENMP_DEFAULTMAP_MODIFIER(Name) \
368 case OMPC_DEFAULTMAP_MODIFIER_##Name: \
370 #include "clang/Basic/OpenMPKinds.def"
372 llvm_unreachable("Invalid OpenMP 'schedule' clause type");
373 case OMPC_atomic_default_mem_order
:
375 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown
:
377 #define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \
378 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name: \
380 #include "clang/Basic/OpenMPKinds.def"
382 llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type");
383 case OMPC_device_type
:
385 case OMPC_DEVICE_TYPE_unknown
:
387 #define OPENMP_DEVICE_TYPE_KIND(Name) \
388 case OMPC_DEVICE_TYPE_##Name: \
390 #include "clang/Basic/OpenMPKinds.def"
392 llvm_unreachable("Invalid OpenMP 'device_type' clause type");
395 case OMPC_AT_unknown
:
397 #define OPENMP_AT_KIND(Name) \
398 case OMPC_AT_##Name: \
400 #include "clang/Basic/OpenMPKinds.def"
402 llvm_unreachable("Invalid OpenMP 'at' clause type");
405 case OMPC_SEVERITY_unknown
:
407 #define OPENMP_SEVERITY_KIND(Name) \
408 case OMPC_SEVERITY_##Name: \
410 #include "clang/Basic/OpenMPKinds.def"
412 llvm_unreachable("Invalid OpenMP 'severity' clause type");
413 case OMPC_lastprivate
:
415 case OMPC_LASTPRIVATE_unknown
:
417 #define OPENMP_LASTPRIVATE_KIND(Name) \
418 case OMPC_LASTPRIVATE_##Name: \
420 #include "clang/Basic/OpenMPKinds.def"
422 llvm_unreachable("Invalid OpenMP 'lastprivate' clause type");
425 case OMPC_ORDER_unknown
:
426 case OMPC_ORDER_MODIFIER_last
:
428 #define OPENMP_ORDER_KIND(Name) \
429 case OMPC_ORDER_##Name: \
431 #define OPENMP_ORDER_MODIFIER(Name) \
432 case OMPC_ORDER_MODIFIER_##Name: \
434 #include "clang/Basic/OpenMPKinds.def"
436 llvm_unreachable("Invalid OpenMP 'order' clause type");
439 case OMPC_DEPEND_unknown
:
441 #define OPENMP_DEPEND_KIND(Name) \
442 case OMPC_DEPEND_##Name: \
444 #include "clang/Basic/OpenMPKinds.def"
446 llvm_unreachable("Invalid OpenMP 'depend' clause type");
448 OpenMPClauseKind CK
= static_cast<OpenMPClauseKind
>(Type
);
449 return getOpenMPClauseName(CK
).data();
450 llvm_unreachable("Invalid OpenMP 'fail' clause modifier");
454 case OMPC_DEVICE_unknown
:
456 #define OPENMP_DEVICE_MODIFIER(Name) \
457 case OMPC_DEVICE_##Name: \
459 #include "clang/Basic/OpenMPKinds.def"
461 llvm_unreachable("Invalid OpenMP 'device' clause modifier");
464 case OMPC_REDUCTION_unknown
:
466 #define OPENMP_REDUCTION_MODIFIER(Name) \
467 case OMPC_REDUCTION_##Name: \
469 #include "clang/Basic/OpenMPKinds.def"
471 llvm_unreachable("Invalid OpenMP 'reduction' clause modifier");
472 case OMPC_adjust_args
:
474 case OMPC_ADJUST_ARGS_unknown
:
476 #define OPENMP_ADJUST_ARGS_KIND(Name) \
477 case OMPC_ADJUST_ARGS_##Name: \
479 #include "clang/Basic/OpenMPKinds.def"
481 llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind");
484 case OMPC_BIND_unknown
:
486 #define OPENMP_BIND_KIND(Name) \
487 case OMPC_BIND_##Name: \
489 #include "clang/Basic/OpenMPKinds.def"
491 llvm_unreachable("Invalid OpenMP 'bind' clause type");
494 case OMPC_GRAINSIZE_unknown
:
496 #define OPENMP_GRAINSIZE_MODIFIER(Name) \
497 case OMPC_GRAINSIZE_##Name: \
499 #include "clang/Basic/OpenMPKinds.def"
501 llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier");
504 case OMPC_NUMTASKS_unknown
:
506 #define OPENMP_NUMTASKS_MODIFIER(Name) \
507 case OMPC_NUMTASKS_##Name: \
509 #include "clang/Basic/OpenMPKinds.def"
511 llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");
514 case OMPC_ALLOCATE_unknown
:
516 #define OPENMP_ALLOCATE_MODIFIER(Name) \
517 case OMPC_ALLOCATE_##Name: \
519 #include "clang/Basic/OpenMPKinds.def"
521 llvm_unreachable("Invalid OpenMP 'allocate' clause modifier");
523 case OMPC_threadprivate
:
526 case OMPC_num_threads
:
530 case OMPC_permutation
:
534 case OMPC_firstprivate
:
536 case OMPC_task_reduction
:
537 case OMPC_in_reduction
:
540 case OMPC_copyprivate
:
559 case OMPC_thread_limit
:
564 case OMPC_use_device_ptr
:
565 case OMPC_use_device_addr
:
566 case OMPC_is_device_ptr
:
567 case OMPC_has_device_addr
:
568 case OMPC_unified_address
:
569 case OMPC_unified_shared_memory
:
570 case OMPC_reverse_offload
:
571 case OMPC_dynamic_allocators
:
573 case OMPC_nontemporal
:
576 case OMPC_novariants
:
580 case OMPC_uses_allocators
:
583 case OMPC_append_args
:
588 llvm_unreachable("Invalid OpenMP simple clause kind");
591 bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind
) {
592 return getDirectiveAssociation(DKind
) == Association::Loop
;
595 bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind
) {
596 return DKind
== OMPD_for
|| DKind
== OMPD_for_simd
||
597 DKind
== OMPD_sections
|| DKind
== OMPD_section
||
598 DKind
== OMPD_single
|| DKind
== OMPD_parallel_for
||
599 DKind
== OMPD_parallel_for_simd
|| DKind
== OMPD_parallel_sections
||
600 DKind
== OMPD_target_parallel_for
||
601 DKind
== OMPD_distribute_parallel_for
||
602 DKind
== OMPD_distribute_parallel_for_simd
||
603 DKind
== OMPD_target_parallel_for_simd
||
604 DKind
== OMPD_teams_distribute_parallel_for_simd
||
605 DKind
== OMPD_teams_distribute_parallel_for
||
606 DKind
== OMPD_target_teams_distribute_parallel_for
||
607 DKind
== OMPD_target_teams_distribute_parallel_for_simd
||
608 DKind
== OMPD_parallel_loop
|| DKind
== OMPD_teams_loop
||
609 DKind
== OMPD_target_parallel_loop
|| DKind
== OMPD_target_teams_loop
;
612 bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind
) {
613 return DKind
== OMPD_taskloop
||
614 llvm::is_contained(getLeafConstructs(DKind
), OMPD_taskloop
);
617 bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind
) {
618 if (DKind
== OMPD_teams_loop
)
620 return DKind
== OMPD_parallel
||
621 llvm::is_contained(getLeafConstructs(DKind
), OMPD_parallel
);
624 bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind
) {
625 return DKind
== OMPD_target
||
626 llvm::is_contained(getLeafConstructs(DKind
), OMPD_target
);
629 bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind
) {
630 return DKind
== OMPD_target_data
|| DKind
== OMPD_target_enter_data
||
631 DKind
== OMPD_target_exit_data
|| DKind
== OMPD_target_update
;
634 bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind
) {
635 if (DKind
== OMPD_teams
)
637 ArrayRef
<Directive
> Leaves
= getLeafConstructs(DKind
);
638 return !Leaves
.empty() && Leaves
.front() == OMPD_teams
;
641 bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind
) {
642 return DKind
== OMPD_teams
||
643 llvm::is_contained(getLeafConstructs(DKind
), OMPD_teams
);
646 bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind
) {
647 // Avoid OMPD_declare_simd
648 if (getDirectiveAssociation(DKind
) != Association::Loop
)
650 // Formally, OMPD_end_do_simd also has a loop association, but
651 // it's a Fortran-specific directive.
653 return DKind
== OMPD_simd
||
654 llvm::is_contained(getLeafConstructs(DKind
), OMPD_simd
);
657 bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind
) {
658 if (Kind
== OMPD_distribute
)
660 ArrayRef
<Directive
> Leaves
= getLeafConstructs(Kind
);
661 return !Leaves
.empty() && Leaves
.front() == OMPD_distribute
;
664 bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind
) {
665 return Kind
== OMPD_distribute
||
666 llvm::is_contained(getLeafConstructs(Kind
), OMPD_distribute
);
669 bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind
) {
670 if (Kind
== OMPD_loop
)
672 ArrayRef
<Directive
> Leaves
= getLeafConstructs(Kind
);
673 return !Leaves
.empty() && Leaves
.back() == OMPD_loop
;
676 bool clang::isOpenMPPrivate(OpenMPClauseKind Kind
) {
677 return Kind
== OMPC_private
|| Kind
== OMPC_firstprivate
||
678 Kind
== OMPC_lastprivate
|| Kind
== OMPC_linear
||
679 Kind
== OMPC_reduction
|| Kind
== OMPC_task_reduction
||
680 Kind
== OMPC_in_reduction
; // TODO add next clauses like 'reduction'.
683 bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind
) {
684 return Kind
== OMPC_threadprivate
|| Kind
== OMPC_copyin
;
687 bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind
) {
688 return Kind
== OMPD_task
|| isOpenMPTaskLoopDirective(Kind
);
691 bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind
) {
692 return Kind
== OMPD_distribute_parallel_for
||
693 Kind
== OMPD_distribute_parallel_for_simd
||
694 Kind
== OMPD_teams_distribute_parallel_for_simd
||
695 Kind
== OMPD_teams_distribute_parallel_for
||
696 Kind
== OMPD_target_teams_distribute_parallel_for
||
697 Kind
== OMPD_target_teams_distribute_parallel_for_simd
||
698 Kind
== OMPD_teams_loop
|| Kind
== OMPD_target_teams_loop
;
701 bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind
) {
702 return DKind
== OMPD_tile
|| DKind
== OMPD_unroll
|| DKind
== OMPD_reverse
||
703 DKind
== OMPD_interchange
;
706 bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind
) {
707 return DKind
== OMPD_parallel_for
|| DKind
== OMPD_parallel_for_simd
||
708 DKind
== OMPD_parallel_master
||
709 DKind
== OMPD_parallel_master_taskloop
||
710 DKind
== OMPD_parallel_master_taskloop_simd
||
711 DKind
== OMPD_parallel_sections
;
714 bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind
) {
715 return DKind
== OMPD_target
|| DKind
== OMPD_target_parallel
||
716 DKind
== OMPD_target_parallel_for
||
717 DKind
== OMPD_target_parallel_for_simd
|| DKind
== OMPD_target_simd
||
718 DKind
== OMPD_target_parallel_loop
;
721 bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind
) {
722 if (DKind
== OMPD_error
)
724 Category Cat
= getDirectiveCategory(DKind
);
725 return Cat
== Category::Executable
|| Cat
== Category::Subsidiary
;
728 bool clang::isOpenMPInformationalDirective(OpenMPDirectiveKind DKind
) {
729 if (DKind
== OMPD_error
)
731 Category Cat
= getDirectiveCategory(DKind
);
732 return Cat
== Category::Informational
;
735 bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind
) {
736 if (isOpenMPExecutableDirective(DKind
)) {
741 case OMPD_cancellation_point
:
754 return !isOpenMPLoopTransformationDirective(DKind
);
757 // Non-executable directives.
759 case OMPD_metadirective
:
768 void clang::getOpenMPCaptureRegions(
769 SmallVectorImpl
<OpenMPDirectiveKind
> &CaptureRegions
,
770 OpenMPDirectiveKind DKind
) {
771 assert(unsigned(DKind
) < llvm::omp::Directive_enumSize
);
772 assert(isOpenMPCapturingDirective(DKind
) && "Expecting capturing directive");
774 auto GetRegionsForLeaf
= [&](OpenMPDirectiveKind LKind
) {
775 assert(isLeafConstruct(LKind
) && "Epecting leaf directive");
776 // Whether a leaf would require OMPD_unknown if it occured on its own.
778 case OMPD_metadirective
:
779 CaptureRegions
.push_back(OMPD_metadirective
);
782 CaptureRegions
.push_back(OMPD_nothing
);
785 CaptureRegions
.push_back(OMPD_parallel
);
788 CaptureRegions
.push_back(OMPD_task
);
789 CaptureRegions
.push_back(OMPD_target
);
792 case OMPD_target_enter_data
:
793 case OMPD_target_exit_data
:
794 case OMPD_target_update
:
795 CaptureRegions
.push_back(OMPD_task
);
798 CaptureRegions
.push_back(OMPD_teams
);
801 CaptureRegions
.push_back(OMPD_taskloop
);
804 // TODO: 'loop' may require different capture regions depending on the
805 // bind clause or the parent directive when there is no bind clause.
806 // If any of the directives that push regions here are parents of 'loop',
807 // assume 'parallel'. Otherwise do nothing.
808 if (!CaptureRegions
.empty() &&
809 !llvm::is_contained(CaptureRegions
, OMPD_parallel
))
810 CaptureRegions
.push_back(OMPD_parallel
);
815 case OMPD_distribute
:
822 case OMPD_target_data
:
824 // These directives (when standalone) use OMPD_unknown as the region,
825 // but when they're constituents of a compound directive, and other
826 // leafs from that directive have specific regions, then these directives
827 // add no additional regions.
833 llvm::errs() << getOpenMPDirectiveName(LKind
) << '\n';
834 llvm_unreachable("Unexpected directive");
839 bool MayNeedUnknownRegion
= false;
840 for (OpenMPDirectiveKind L
: getLeafConstructsOrSelf(DKind
))
841 MayNeedUnknownRegion
|= GetRegionsForLeaf(L
);
843 // We need OMPD_unknown when no regions were added, and specific leaf
844 // constructs were present. Push a single OMPD_unknown as the capture
846 if (CaptureRegions
.empty() && MayNeedUnknownRegion
)
847 CaptureRegions
.push_back(OMPD_unknown
);
849 // OMPD_unknown is only expected as the only region. If other regions
850 // are present OMPD_unknown should not be present.
851 assert((CaptureRegions
[0] == OMPD_unknown
||
852 !llvm::is_contained(CaptureRegions
, OMPD_unknown
)) &&
853 "Misplaced OMPD_unknown");
856 bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter
) {
857 return FailClauseParameter
== llvm::omp::OMPC_acquire
||
858 FailClauseParameter
== llvm::omp::OMPC_relaxed
||
859 FailClauseParameter
== llvm::omp::OMPC_seq_cst
;