1//===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===//
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/// \file
9/// This file implements the OpenMP enum and support functions.
10///
11//===----------------------------------------------------------------------===//
12
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"
18#include <cassert>
19
20using namespace clang;
21using namespace llvm::omp;
22
23unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,
24 const LangOptions &LangOpts) {
25 switch (Kind) {
26 case OMPC_default:
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(Value: unsigned(llvm::omp::OMP_DEFAULT_unknown));
31 case OMPC_proc_bind:
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));
36 case OMPC_schedule:
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(Value: OMPC_SCHEDULE_unknown);
44 case OMPC_depend: {
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(Value: OMPC_DEPEND_unknown);
49 if (LangOpts.OpenMP < 51 && Type == OMPC_DEPEND_inoutset)
50 return OMPC_DEPEND_unknown;
51 return Type;
52 }
53 case OMPC_doacross:
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(Value: OMPC_DOACROSS_unknown);
58 case OMPC_linear:
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(Value: OMPC_LINEAR_unknown);
63 case OMPC_map: {
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(Value: 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;
75 return Type;
76 }
77 case OMPC_to:
78 case OMPC_from: {
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(Value: OMPC_MOTION_MODIFIER_unknown);
84 if (LangOpts.OpenMP < 51 && Type == OMPC_MOTION_MODIFIER_present)
85 return OMPC_MOTION_MODIFIER_unknown;
86 return Type;
87 }
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(Value: OMPC_DIST_SCHEDULE_unknown);
93 case OMPC_defaultmap:
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(Value: 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(Value: OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown);
107 case OMPC_fail:
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(Value: OMPC_DEVICE_TYPE_unknown);
117 case OMPC_at:
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(Value: OMPC_AT_unknown);
122 case OMPC_severity:
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(Value: 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(Value: OMPC_LASTPRIVATE_unknown);
132 case OMPC_order:
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(Value: OMPC_ORDER_unknown);
140 case OMPC_update:
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(Value: OMPC_DEPEND_unknown);
145 case OMPC_device:
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(Value: OMPC_DEVICE_unknown);
150 case OMPC_reduction:
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(Value: 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(Value: OMPC_ADJUST_ARGS_unknown);
160 case OMPC_bind:
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(Value: 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(Value: OMPC_GRAINSIZE_unknown);
170 if (LangOpts.OpenMP < 51)
171 return OMPC_GRAINSIZE_unknown;
172 return Type;
173 }
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(Value: OMPC_NUMTASKS_unknown);
179 if (LangOpts.OpenMP < 51)
180 return OMPC_NUMTASKS_unknown;
181 return Type;
182 }
183 case OMPC_allocate:
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(Value: OMPC_ALLOCATE_unknown);
188 case OMPC_unknown:
189 case OMPC_threadprivate:
190 case OMPC_if:
191 case OMPC_final:
192 case OMPC_num_threads:
193 case OMPC_safelen:
194 case OMPC_simdlen:
195 case OMPC_sizes:
196 case OMPC_permutation:
197 case OMPC_allocator:
198 case OMPC_collapse:
199 case OMPC_private:
200 case OMPC_firstprivate:
201 case OMPC_shared:
202 case OMPC_task_reduction:
203 case OMPC_in_reduction:
204 case OMPC_aligned:
205 case OMPC_copyin:
206 case OMPC_copyprivate:
207 case OMPC_ordered:
208 case OMPC_nowait:
209 case OMPC_untied:
210 case OMPC_mergeable:
211 case OMPC_flush:
212 case OMPC_depobj:
213 case OMPC_read:
214 case OMPC_write:
215 case OMPC_capture:
216 case OMPC_compare:
217 case OMPC_seq_cst:
218 case OMPC_acq_rel:
219 case OMPC_acquire:
220 case OMPC_release:
221 case OMPC_relaxed:
222 case OMPC_threads:
223 case OMPC_simd:
224 case OMPC_num_teams:
225 case OMPC_thread_limit:
226 case OMPC_priority:
227 case OMPC_nogroup:
228 case OMPC_hint:
229 case OMPC_uniform:
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:
238 case OMPC_self_maps:
239 case OMPC_match:
240 case OMPC_nontemporal:
241 case OMPC_destroy:
242 case OMPC_novariants:
243 case OMPC_nocontext:
244 case OMPC_detach:
245 case OMPC_inclusive:
246 case OMPC_exclusive:
247 case OMPC_uses_allocators:
248 case OMPC_affinity:
249 case OMPC_when:
250 case OMPC_append_args:
251 break;
252 default:
253 break;
254 }
255 llvm_unreachable("Invalid OpenMP simple clause kind");
256}
257
258const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
259 unsigned Type) {
260 switch (Kind) {
261 case OMPC_default:
262 switch (llvm::omp::DefaultKind(Type)) {
263#define OMP_DEFAULT_KIND(Enum, Name) \
264 case Enum: \
265 return Name;
266#include "llvm/Frontend/OpenMP/OMPKinds.def"
267 }
268 llvm_unreachable("Invalid OpenMP 'default' clause type");
269 case OMPC_proc_bind:
270 switch (Type) {
271#define OMP_PROC_BIND_KIND(Enum, Name, Value) \
272 case Value: \
273 return Name;
274#include "llvm/Frontend/OpenMP/OMPKinds.def"
275 }
276 llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
277 case OMPC_schedule:
278 switch (Type) {
279 case OMPC_SCHEDULE_unknown:
280 case OMPC_SCHEDULE_MODIFIER_last:
281 return "unknown";
282#define OPENMP_SCHEDULE_KIND(Name) \
283 case OMPC_SCHEDULE_##Name: \
284 return #Name;
285#define OPENMP_SCHEDULE_MODIFIER(Name) \
286 case OMPC_SCHEDULE_MODIFIER_##Name: \
287 return #Name;
288#include "clang/Basic/OpenMPKinds.def"
289 }
290 llvm_unreachable("Invalid OpenMP 'schedule' clause type");
291 case OMPC_depend:
292 switch (Type) {
293 case OMPC_DEPEND_unknown:
294 return "unknown";
295#define OPENMP_DEPEND_KIND(Name) \
296 case OMPC_DEPEND_##Name: \
297 return #Name;
298#include "clang/Basic/OpenMPKinds.def"
299 }
300 llvm_unreachable("Invalid OpenMP 'depend' clause type");
301 case OMPC_doacross:
302 switch (Type) {
303 case OMPC_DOACROSS_unknown:
304 return "unknown";
305#define OPENMP_DOACROSS_MODIFIER(Name) \
306 case OMPC_DOACROSS_##Name: \
307 return #Name;
308#include "clang/Basic/OpenMPKinds.def"
309 }
310 llvm_unreachable("Invalid OpenMP 'doacross' clause type");
311 case OMPC_linear:
312 switch (Type) {
313 case OMPC_LINEAR_unknown:
314 return "unknown";
315#define OPENMP_LINEAR_KIND(Name) \
316 case OMPC_LINEAR_##Name: \
317 return #Name;
318#include "clang/Basic/OpenMPKinds.def"
319 }
320 llvm_unreachable("Invalid OpenMP 'linear' clause type");
321 case OMPC_map:
322 switch (Type) {
323 case OMPC_MAP_unknown:
324 case OMPC_MAP_MODIFIER_last:
325 return "unknown";
326#define OPENMP_MAP_KIND(Name) \
327 case OMPC_MAP_##Name: \
328 return #Name;
329#define OPENMP_MAP_MODIFIER_KIND(Name) \
330 case OMPC_MAP_MODIFIER_##Name: \
331 return #Name;
332#include "clang/Basic/OpenMPKinds.def"
333 default:
334 break;
335 }
336 llvm_unreachable("Invalid OpenMP 'map' clause type");
337 case OMPC_to:
338 case OMPC_from:
339 switch (Type) {
340 case OMPC_MOTION_MODIFIER_unknown:
341 return "unknown";
342#define OPENMP_MOTION_MODIFIER_KIND(Name) \
343 case OMPC_MOTION_MODIFIER_##Name: \
344 return #Name;
345#include "clang/Basic/OpenMPKinds.def"
346 default:
347 break;
348 }
349 llvm_unreachable("Invalid OpenMP 'to' or 'from' clause type");
350 case OMPC_dist_schedule:
351 switch (Type) {
352 case OMPC_DIST_SCHEDULE_unknown:
353 return "unknown";
354#define OPENMP_DIST_SCHEDULE_KIND(Name) \
355 case OMPC_DIST_SCHEDULE_##Name: \
356 return #Name;
357#include "clang/Basic/OpenMPKinds.def"
358 }
359 llvm_unreachable("Invalid OpenMP 'dist_schedule' clause type");
360 case OMPC_defaultmap:
361 switch (Type) {
362 case OMPC_DEFAULTMAP_unknown:
363 case OMPC_DEFAULTMAP_MODIFIER_last:
364 return "unknown";
365#define OPENMP_DEFAULTMAP_KIND(Name) \
366 case OMPC_DEFAULTMAP_##Name: \
367 return #Name;
368#define OPENMP_DEFAULTMAP_MODIFIER(Name) \
369 case OMPC_DEFAULTMAP_MODIFIER_##Name: \
370 return #Name;
371#include "clang/Basic/OpenMPKinds.def"
372 }
373 llvm_unreachable("Invalid OpenMP 'schedule' clause type");
374 case OMPC_atomic_default_mem_order:
375 switch (Type) {
376 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown:
377 return "unknown";
378#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \
379 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name: \
380 return #Name;
381#include "clang/Basic/OpenMPKinds.def"
382}
383 llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type");
384 case OMPC_device_type:
385 switch (Type) {
386 case OMPC_DEVICE_TYPE_unknown:
387 return "unknown";
388#define OPENMP_DEVICE_TYPE_KIND(Name) \
389 case OMPC_DEVICE_TYPE_##Name: \
390 return #Name;
391#include "clang/Basic/OpenMPKinds.def"
392 }
393 llvm_unreachable("Invalid OpenMP 'device_type' clause type");
394 case OMPC_at:
395 switch (Type) {
396 case OMPC_AT_unknown:
397 return "unknown";
398#define OPENMP_AT_KIND(Name) \
399 case OMPC_AT_##Name: \
400 return #Name;
401#include "clang/Basic/OpenMPKinds.def"
402 }
403 llvm_unreachable("Invalid OpenMP 'at' clause type");
404 case OMPC_severity:
405 switch (Type) {
406 case OMPC_SEVERITY_unknown:
407 return "unknown";
408#define OPENMP_SEVERITY_KIND(Name) \
409 case OMPC_SEVERITY_##Name: \
410 return #Name;
411#include "clang/Basic/OpenMPKinds.def"
412 }
413 llvm_unreachable("Invalid OpenMP 'severity' clause type");
414 case OMPC_lastprivate:
415 switch (Type) {
416 case OMPC_LASTPRIVATE_unknown:
417 return "unknown";
418#define OPENMP_LASTPRIVATE_KIND(Name) \
419 case OMPC_LASTPRIVATE_##Name: \
420 return #Name;
421#include "clang/Basic/OpenMPKinds.def"
422 }
423 llvm_unreachable("Invalid OpenMP 'lastprivate' clause type");
424 case OMPC_order:
425 switch (Type) {
426 case OMPC_ORDER_unknown:
427 case OMPC_ORDER_MODIFIER_last:
428 return "unknown";
429#define OPENMP_ORDER_KIND(Name) \
430 case OMPC_ORDER_##Name: \
431 return #Name;
432#define OPENMP_ORDER_MODIFIER(Name) \
433 case OMPC_ORDER_MODIFIER_##Name: \
434 return #Name;
435#include "clang/Basic/OpenMPKinds.def"
436 }
437 llvm_unreachable("Invalid OpenMP 'order' clause type");
438 case OMPC_update:
439 switch (Type) {
440 case OMPC_DEPEND_unknown:
441 return "unknown";
442#define OPENMP_DEPEND_KIND(Name) \
443 case OMPC_DEPEND_##Name: \
444 return #Name;
445#include "clang/Basic/OpenMPKinds.def"
446 }
447 llvm_unreachable("Invalid OpenMP 'depend' clause type");
448 case OMPC_fail: {
449 OpenMPClauseKind CK = static_cast<OpenMPClauseKind>(Type);
450 return getOpenMPClauseName(CK).data();
451 llvm_unreachable("Invalid OpenMP 'fail' clause modifier");
452 }
453 case OMPC_device:
454 switch (Type) {
455 case OMPC_DEVICE_unknown:
456 return "unknown";
457#define OPENMP_DEVICE_MODIFIER(Name) \
458 case OMPC_DEVICE_##Name: \
459 return #Name;
460#include "clang/Basic/OpenMPKinds.def"
461 }
462 llvm_unreachable("Invalid OpenMP 'device' clause modifier");
463 case OMPC_reduction:
464 switch (Type) {
465 case OMPC_REDUCTION_unknown:
466 return "unknown";
467#define OPENMP_REDUCTION_MODIFIER(Name) \
468 case OMPC_REDUCTION_##Name: \
469 return #Name;
470#include "clang/Basic/OpenMPKinds.def"
471 }
472 llvm_unreachable("Invalid OpenMP 'reduction' clause modifier");
473 case OMPC_adjust_args:
474 switch (Type) {
475 case OMPC_ADJUST_ARGS_unknown:
476 return "unknown";
477#define OPENMP_ADJUST_ARGS_KIND(Name) \
478 case OMPC_ADJUST_ARGS_##Name: \
479 return #Name;
480#include "clang/Basic/OpenMPKinds.def"
481 }
482 llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind");
483 case OMPC_bind:
484 switch (Type) {
485 case OMPC_BIND_unknown:
486 return "unknown";
487#define OPENMP_BIND_KIND(Name) \
488 case OMPC_BIND_##Name: \
489 return #Name;
490#include "clang/Basic/OpenMPKinds.def"
491 }
492 llvm_unreachable("Invalid OpenMP 'bind' clause type");
493 case OMPC_grainsize:
494 switch (Type) {
495 case OMPC_GRAINSIZE_unknown:
496 return "unknown";
497#define OPENMP_GRAINSIZE_MODIFIER(Name) \
498 case OMPC_GRAINSIZE_##Name: \
499 return #Name;
500#include "clang/Basic/OpenMPKinds.def"
501 }
502 llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier");
503 case OMPC_num_tasks:
504 switch (Type) {
505 case OMPC_NUMTASKS_unknown:
506 return "unknown";
507#define OPENMP_NUMTASKS_MODIFIER(Name) \
508 case OMPC_NUMTASKS_##Name: \
509 return #Name;
510#include "clang/Basic/OpenMPKinds.def"
511 }
512 llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");
513 case OMPC_allocate:
514 switch (Type) {
515 case OMPC_ALLOCATE_unknown:
516 return "unknown";
517#define OPENMP_ALLOCATE_MODIFIER(Name) \
518 case OMPC_ALLOCATE_##Name: \
519 return #Name;
520#include "clang/Basic/OpenMPKinds.def"
521 }
522 llvm_unreachable("Invalid OpenMP 'allocate' clause modifier");
523 case OMPC_unknown:
524 case OMPC_threadprivate:
525 case OMPC_if:
526 case OMPC_final:
527 case OMPC_num_threads:
528 case OMPC_safelen:
529 case OMPC_simdlen:
530 case OMPC_sizes:
531 case OMPC_permutation:
532 case OMPC_allocator:
533 case OMPC_collapse:
534 case OMPC_private:
535 case OMPC_firstprivate:
536 case OMPC_shared:
537 case OMPC_task_reduction:
538 case OMPC_in_reduction:
539 case OMPC_aligned:
540 case OMPC_copyin:
541 case OMPC_copyprivate:
542 case OMPC_ordered:
543 case OMPC_nowait:
544 case OMPC_untied:
545 case OMPC_mergeable:
546 case OMPC_flush:
547 case OMPC_depobj:
548 case OMPC_read:
549 case OMPC_write:
550 case OMPC_capture:
551 case OMPC_compare:
552 case OMPC_seq_cst:
553 case OMPC_acq_rel:
554 case OMPC_acquire:
555 case OMPC_release:
556 case OMPC_relaxed:
557 case OMPC_threads:
558 case OMPC_simd:
559 case OMPC_num_teams:
560 case OMPC_thread_limit:
561 case OMPC_priority:
562 case OMPC_nogroup:
563 case OMPC_hint:
564 case OMPC_uniform:
565 case OMPC_use_device_ptr:
566 case OMPC_use_device_addr:
567 case OMPC_is_device_ptr:
568 case OMPC_has_device_addr:
569 case OMPC_unified_address:
570 case OMPC_unified_shared_memory:
571 case OMPC_reverse_offload:
572 case OMPC_dynamic_allocators:
573 case OMPC_self_maps:
574 case OMPC_match:
575 case OMPC_nontemporal:
576 case OMPC_destroy:
577 case OMPC_detach:
578 case OMPC_novariants:
579 case OMPC_nocontext:
580 case OMPC_inclusive:
581 case OMPC_exclusive:
582 case OMPC_uses_allocators:
583 case OMPC_affinity:
584 case OMPC_when:
585 case OMPC_append_args:
586 break;
587 default:
588 break;
589 }
590 llvm_unreachable("Invalid OpenMP simple clause kind");
591}
592
593bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
594 return getDirectiveAssociation(DKind) == Association::Loop;
595}
596
597bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
598 return DKind == OMPD_for || DKind == OMPD_for_simd ||
599 DKind == OMPD_sections || DKind == OMPD_section ||
600 DKind == OMPD_single || DKind == OMPD_parallel_for ||
601 DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||
602 DKind == OMPD_target_parallel_for ||
603 DKind == OMPD_distribute_parallel_for ||
604 DKind == OMPD_distribute_parallel_for_simd ||
605 DKind == OMPD_target_parallel_for_simd ||
606 DKind == OMPD_teams_distribute_parallel_for_simd ||
607 DKind == OMPD_teams_distribute_parallel_for ||
608 DKind == OMPD_target_teams_distribute_parallel_for ||
609 DKind == OMPD_target_teams_distribute_parallel_for_simd ||
610 DKind == OMPD_parallel_loop || DKind == OMPD_teams_loop ||
611 DKind == OMPD_target_parallel_loop || DKind == OMPD_target_teams_loop;
612}
613
614bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {
615 return DKind == OMPD_taskloop ||
616 llvm::is_contained(getLeafConstructs(DKind), OMPD_taskloop);
617}
618
619bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
620 if (DKind == OMPD_teams_loop)
621 return true;
622 return DKind == OMPD_parallel ||
623 llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);
624}
625
626bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {
627 return DKind == OMPD_target ||
628 llvm::is_contained(getLeafConstructs(DKind), OMPD_target);
629}
630
631bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {
632 return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||
633 DKind == OMPD_target_exit_data || DKind == OMPD_target_update;
634}
635
636bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {
637 if (DKind == OMPD_teams)
638 return true;
639 ArrayRef<Directive> Leaves = getLeafConstructs(DKind);
640 return !Leaves.empty() && Leaves.front() == OMPD_teams;
641}
642
643bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {
644 return DKind == OMPD_teams ||
645 llvm::is_contained(getLeafConstructs(DKind), OMPD_teams);
646}
647
648bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
649 // Avoid OMPD_declare_simd
650 if (getDirectiveAssociation(DKind) != Association::Loop)
651 return false;
652 // Formally, OMPD_end_do_simd also has a loop association, but
653 // it's a Fortran-specific directive.
654
655 return DKind == OMPD_simd ||
656 llvm::is_contained(getLeafConstructs(DKind), OMPD_simd);
657}
658
659bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {
660 if (Kind == OMPD_distribute)
661 return true;
662 ArrayRef<Directive> Leaves = getLeafConstructs(Kind);
663 return !Leaves.empty() && Leaves.front() == OMPD_distribute;
664}
665
666bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
667 return Kind == OMPD_distribute ||
668 llvm::is_contained(getLeafConstructs(Kind), OMPD_distribute);
669}
670
671bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {
672 if (Kind == OMPD_loop)
673 return true;
674 ArrayRef<Directive> Leaves = getLeafConstructs(Kind);
675 return !Leaves.empty() && Leaves.back() == OMPD_loop;
676}
677
678bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
679 return Kind == OMPC_private || Kind == OMPC_firstprivate ||
680 Kind == OMPC_lastprivate || Kind == OMPC_linear ||
681 Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
682 Kind == OMPC_in_reduction; // TODO add next clauses like 'reduction'.
683}
684
685bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
686 return Kind == OMPC_threadprivate || Kind == OMPC_copyin;
687}
688
689bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) {
690 return Kind == OMPD_task || isOpenMPTaskLoopDirective(Kind);
691}
692
693bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {
694 return Kind == OMPD_distribute_parallel_for ||
695 Kind == OMPD_distribute_parallel_for_simd ||
696 Kind == OMPD_teams_distribute_parallel_for_simd ||
697 Kind == OMPD_teams_distribute_parallel_for ||
698 Kind == OMPD_target_teams_distribute_parallel_for ||
699 Kind == OMPD_target_teams_distribute_parallel_for_simd ||
700 Kind == OMPD_teams_loop || Kind == OMPD_target_teams_loop;
701}
702
703bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) {
704 return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse ||
705 DKind == OMPD_interchange || DKind == OMPD_stripe;
706}
707
708bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) {
709 return DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||
710 DKind == OMPD_parallel_master ||
711 DKind == OMPD_parallel_master_taskloop ||
712 DKind == OMPD_parallel_master_taskloop_simd ||
713 DKind == OMPD_parallel_sections;
714}
715
716bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind) {
717 return DKind == OMPD_target || DKind == OMPD_target_parallel ||
718 DKind == OMPD_target_parallel_for ||
719 DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||
720 DKind == OMPD_target_parallel_loop;
721}
722
723bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) {
724 if (DKind == OMPD_error)
725 return true;
726 Category Cat = getDirectiveCategory(DKind);
727 return Cat == Category::Executable || Cat == Category::Subsidiary;
728}
729
730bool clang::isOpenMPInformationalDirective(OpenMPDirectiveKind DKind) {
731 if (DKind == OMPD_error)
732 return true;
733 Category Cat = getDirectiveCategory(DKind);
734 return Cat == Category::Informational;
735}
736
737bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) {
738 if (isOpenMPExecutableDirective(DKind)) {
739 switch (DKind) {
740 case OMPD_atomic:
741 case OMPD_barrier:
742 case OMPD_cancel:
743 case OMPD_cancellation_point:
744 case OMPD_critical:
745 case OMPD_depobj:
746 case OMPD_error:
747 case OMPD_flush:
748 case OMPD_masked:
749 case OMPD_master:
750 case OMPD_section:
751 case OMPD_taskwait:
752 case OMPD_taskyield:
753 case OMPD_assume:
754 return false;
755 default:
756 return !isOpenMPLoopTransformationDirective(DKind);
757 }
758 }
759 // Non-executable directives.
760 switch (DKind) {
761 case OMPD_metadirective:
762 case OMPD_nothing:
763 return true;
764 default:
765 break;
766 }
767 return false;
768}
769
770bool clang::isOpenMPOrderConcurrentNestableDirective(
771 OpenMPDirectiveKind DKind, const LangOptions &LangOpts) {
772 // Directives strictly nestable in a construct with order(concurrent) are:
773 // OpenMP 5.x: loop, parallel, simd, combined directive starting with parallel
774 // OpenMP 6.0: above plus atomic and all loop-transformation directives
775
776 if (DKind == OMPD_loop || DKind == OMPD_parallel || DKind == OMPD_simd ||
777 isOpenMPCombinedParallelADirective(DKind))
778 return true;
779
780 if (LangOpts.OpenMP >= 60)
781 return DKind == OMPD_atomic ||
782 isOpenMPLoopTransformationDirective(DKind);
783
784 return false;
785}
786
787void clang::getOpenMPCaptureRegions(
788 SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,
789 OpenMPDirectiveKind DKind) {
790 assert(unsigned(DKind) < llvm::omp::Directive_enumSize);
791 assert(isOpenMPCapturingDirective(DKind) && "Expecting capturing directive");
792
793 auto GetRegionsForLeaf = [&](OpenMPDirectiveKind LKind) {
794 assert(isLeafConstruct(LKind) && "Epecting leaf directive");
795 // Whether a leaf would require OMPD_unknown if it occured on its own.
796 switch (LKind) {
797 case OMPD_metadirective:
798 CaptureRegions.push_back(OMPD_metadirective);
799 break;
800 case OMPD_nothing:
801 CaptureRegions.push_back(OMPD_nothing);
802 break;
803 case OMPD_parallel:
804 CaptureRegions.push_back(OMPD_parallel);
805 break;
806 case OMPD_target:
807 CaptureRegions.push_back(OMPD_task);
808 CaptureRegions.push_back(OMPD_target);
809 break;
810 case OMPD_task:
811 case OMPD_target_enter_data:
812 case OMPD_target_exit_data:
813 case OMPD_target_update:
814 CaptureRegions.push_back(OMPD_task);
815 break;
816 case OMPD_teams:
817 CaptureRegions.push_back(OMPD_teams);
818 break;
819 case OMPD_taskloop:
820 CaptureRegions.push_back(OMPD_taskloop);
821 break;
822 case OMPD_loop:
823 // TODO: 'loop' may require different capture regions depending on the
824 // bind clause or the parent directive when there is no bind clause.
825 // If any of the directives that push regions here are parents of 'loop',
826 // assume 'parallel'. Otherwise do nothing.
827 if (!CaptureRegions.empty() &&
828 !llvm::is_contained(CaptureRegions, OMPD_parallel))
829 CaptureRegions.push_back(OMPD_parallel);
830 else
831 return true;
832 break;
833 case OMPD_dispatch:
834 case OMPD_distribute:
835 case OMPD_for:
836 case OMPD_ordered:
837 case OMPD_scope:
838 case OMPD_sections:
839 case OMPD_simd:
840 case OMPD_single:
841 case OMPD_target_data:
842 case OMPD_taskgroup:
843 case OMPD_stripe:
844 // These directives (when standalone) use OMPD_unknown as the region,
845 // but when they're constituents of a compound directive, and other
846 // leafs from that directive have specific regions, then these directives
847 // add no additional regions.
848 return true;
849 case OMPD_masked:
850 case OMPD_master:
851 return false;
852 default:
853 llvm::errs() << getOpenMPDirectiveName(LKind, llvm::omp::FallbackVersion)
854 << '\n';
855 llvm_unreachable("Unexpected directive");
856 }
857 return false;
858 };
859
860 bool MayNeedUnknownRegion = false;
861 for (OpenMPDirectiveKind L : getLeafConstructsOrSelf(DKind))
862 MayNeedUnknownRegion |= GetRegionsForLeaf(L);
863
864 // We need OMPD_unknown when no regions were added, and specific leaf
865 // constructs were present. Push a single OMPD_unknown as the capture
866 /// region.
867 if (CaptureRegions.empty() && MayNeedUnknownRegion)
868 CaptureRegions.push_back(OMPD_unknown);
869
870 // OMPD_unknown is only expected as the only region. If other regions
871 // are present OMPD_unknown should not be present.
872 assert((CaptureRegions[0] == OMPD_unknown ||
873 !llvm::is_contained(CaptureRegions, OMPD_unknown)) &&
874 "Misplaced OMPD_unknown");
875}
876
877bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter) {
878 return FailClauseParameter == llvm::omp::OMPC_acquire ||
879 FailClauseParameter == llvm::omp::OMPC_relaxed ||
880 FailClauseParameter == llvm::omp::OMPC_seq_cst;
881}
882
883

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of clang/lib/Basic/OpenMPKinds.cpp