987 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8/// \file9/// 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 23OpenMPDefaultClauseVariableCategory24clang::getOpenMPDefaultVariableCategory(StringRef Str,25 const LangOptions &LangOpts) {26 return llvm::StringSwitch<OpenMPDefaultClauseVariableCategory>(Str)27#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \28 .Case(#Name, OMPC_DEFAULT_VC_##Name)29#include "clang/Basic/OpenMPKinds.def"30 .Default(OMPC_DEFAULT_VC_unknown);31}32 33const char *clang::getOpenMPDefaultVariableCategoryName(unsigned VC) {34 switch (VC) {35#define OPENMP_DEFAULT_VARIABLE_CATEGORY(Name) \36 case OMPC_DEFAULT_VC_##Name: \37 return #Name;38#include "clang/Basic/OpenMPKinds.def"39 }40 llvm_unreachable("Invalid Variable Category in the default clause");41}42 43unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,44 const LangOptions &LangOpts) {45 switch (Kind) {46 case OMPC_default:47 return llvm::StringSwitch<unsigned>(Str)48#define OMP_DEFAULT_KIND(Enum, Name) .Case(Name, unsigned(Enum))49#include "llvm/Frontend/OpenMP/OMPKinds.def"50 .Default(unsigned(llvm::omp::OMP_DEFAULT_unknown));51 case OMPC_proc_bind:52 return llvm::StringSwitch<unsigned>(Str)53#define OMP_PROC_BIND_KIND(Enum, Name, Value) .Case(Name, Value)54#include "llvm/Frontend/OpenMP/OMPKinds.def"55 .Default(unsigned(llvm::omp::OMP_PROC_BIND_unknown));56 case OMPC_schedule:57 return llvm::StringSwitch<unsigned>(Str)58#define OPENMP_SCHEDULE_KIND(Name) \59 .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_##Name))60#define OPENMP_SCHEDULE_MODIFIER(Name) \61 .Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_MODIFIER_##Name))62#include "clang/Basic/OpenMPKinds.def"63 .Default(OMPC_SCHEDULE_unknown);64 case OMPC_depend: {65 unsigned Type = llvm::StringSwitch<unsigned>(Str)66#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)67#include "clang/Basic/OpenMPKinds.def"68 .Default(OMPC_DEPEND_unknown);69 if (LangOpts.OpenMP < 51 && Type == OMPC_DEPEND_inoutset)70 return OMPC_DEPEND_unknown;71 return Type;72 }73 case OMPC_doacross:74 return llvm::StringSwitch<OpenMPDoacrossClauseModifier>(Str)75#define OPENMP_DOACROSS_MODIFIER(Name) .Case(#Name, OMPC_DOACROSS_##Name)76#include "clang/Basic/OpenMPKinds.def"77 .Default(OMPC_DOACROSS_unknown);78 case OMPC_linear:79 return llvm::StringSwitch<OpenMPLinearClauseKind>(Str)80#define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name)81#include "clang/Basic/OpenMPKinds.def"82 .Default(OMPC_LINEAR_unknown);83 case OMPC_map: {84 unsigned Type = llvm::StringSwitch<unsigned>(Str)85#define OPENMP_MAP_KIND(Name) \86 .Case(#Name, static_cast<unsigned>(OMPC_MAP_##Name))87#define OPENMP_MAP_MODIFIER_KIND(Name) \88 .Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name))89#include "clang/Basic/OpenMPKinds.def"90 .Default(OMPC_MAP_unknown);91 if (LangOpts.OpenMP < 51 && Type == OMPC_MAP_MODIFIER_present)92 return OMPC_MAP_MODIFIER_unknown;93 if (!LangOpts.OpenMPExtensions && Type == OMPC_MAP_MODIFIER_ompx_hold)94 return OMPC_MAP_MODIFIER_unknown;95 return Type;96 }97 case OMPC_to:98 case OMPC_from: {99 unsigned Type = llvm::StringSwitch<unsigned>(Str)100#define OPENMP_MOTION_MODIFIER_KIND(Name) \101 .Case(#Name, static_cast<unsigned>(OMPC_MOTION_MODIFIER_##Name))102#include "clang/Basic/OpenMPKinds.def"103 .Default(OMPC_MOTION_MODIFIER_unknown);104 if (LangOpts.OpenMP < 51 && Type == OMPC_MOTION_MODIFIER_present)105 return OMPC_MOTION_MODIFIER_unknown;106 return Type;107 }108 case OMPC_dist_schedule:109 return llvm::StringSwitch<OpenMPDistScheduleClauseKind>(Str)110#define OPENMP_DIST_SCHEDULE_KIND(Name) .Case(#Name, OMPC_DIST_SCHEDULE_##Name)111#include "clang/Basic/OpenMPKinds.def"112 .Default(OMPC_DIST_SCHEDULE_unknown);113 case OMPC_defaultmap: {114 unsigned Type = llvm::StringSwitch<unsigned>(Str)115#define OPENMP_DEFAULTMAP_KIND(Name) \116 .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_##Name))117#define OPENMP_DEFAULTMAP_MODIFIER(Name) \118 .Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_MODIFIER_##Name))119#include "clang/Basic/OpenMPKinds.def"120 .Default(OMPC_DEFAULTMAP_unknown);121 if (LangOpts.OpenMP < 60 && (Type == OMPC_DEFAULTMAP_MODIFIER_storage ||122 Type == OMPC_DEFAULTMAP_MODIFIER_private))123 return OMPC_DEFAULTMAP_MODIFIER_unknown;124 return Type;125 }126 case OMPC_atomic_default_mem_order:127 return llvm::StringSwitch<OpenMPAtomicDefaultMemOrderClauseKind>(Str)128#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \129 .Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name)130#include "clang/Basic/OpenMPKinds.def"131 .Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown);132 case OMPC_fail:133 return static_cast<unsigned int>(llvm::StringSwitch<llvm::omp::Clause>(Str)134#define OPENMP_ATOMIC_FAIL_MODIFIER(Name) .Case(#Name, OMPC_##Name)135#include "clang/Basic/OpenMPKinds.def"136 .Default(OMPC_unknown));137 case OMPC_device_type:138 return llvm::StringSwitch<OpenMPDeviceType>(Str)139#define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name)140#include "clang/Basic/OpenMPKinds.def"141 .Default(OMPC_DEVICE_TYPE_unknown);142 case OMPC_at:143 return llvm::StringSwitch<OpenMPAtClauseKind>(Str)144#define OPENMP_AT_KIND(Name) .Case(#Name, OMPC_AT_##Name)145#include "clang/Basic/OpenMPKinds.def"146 .Default(OMPC_AT_unknown);147 case OMPC_severity:148 return llvm::StringSwitch<OpenMPSeverityClauseKind>(Str)149#define OPENMP_SEVERITY_KIND(Name) .Case(#Name, OMPC_SEVERITY_##Name)150#include "clang/Basic/OpenMPKinds.def"151 .Default(OMPC_SEVERITY_unknown);152 case OMPC_lastprivate:153 return llvm::StringSwitch<OpenMPLastprivateModifier>(Str)154#define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name)155#include "clang/Basic/OpenMPKinds.def"156 .Default(OMPC_LASTPRIVATE_unknown);157 case OMPC_order:158 return llvm::StringSwitch<unsigned>(Str)159#define OPENMP_ORDER_KIND(Name) \160 .Case(#Name, static_cast<unsigned>(OMPC_ORDER_##Name))161#define OPENMP_ORDER_MODIFIER(Name) \162 .Case(#Name, static_cast<unsigned>(OMPC_ORDER_MODIFIER_##Name))163#include "clang/Basic/OpenMPKinds.def"164 .Default(OMPC_ORDER_unknown);165 case OMPC_update:166 return llvm::StringSwitch<OpenMPDependClauseKind>(Str)167#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)168#include "clang/Basic/OpenMPKinds.def"169 .Default(OMPC_DEPEND_unknown);170 case OMPC_device:171 return llvm::StringSwitch<OpenMPDeviceClauseModifier>(Str)172#define OPENMP_DEVICE_MODIFIER(Name) .Case(#Name, OMPC_DEVICE_##Name)173#include "clang/Basic/OpenMPKinds.def"174 .Default(OMPC_DEVICE_unknown);175 case OMPC_reduction:176 return llvm::StringSwitch<OpenMPReductionClauseModifier>(Str)177#define OPENMP_REDUCTION_MODIFIER(Name) .Case(#Name, OMPC_REDUCTION_##Name)178#include "clang/Basic/OpenMPKinds.def"179 .Default(OMPC_REDUCTION_unknown);180 case OMPC_adjust_args:181 return llvm::StringSwitch<OpenMPAdjustArgsOpKind>(Str)182#define OPENMP_ADJUST_ARGS_KIND(Name) .Case(#Name, OMPC_ADJUST_ARGS_##Name)183#include "clang/Basic/OpenMPKinds.def"184 .Default(OMPC_ADJUST_ARGS_unknown);185 case OMPC_bind:186 return llvm::StringSwitch<unsigned>(Str)187#define OPENMP_BIND_KIND(Name) .Case(#Name, OMPC_BIND_##Name)188#include "clang/Basic/OpenMPKinds.def"189 .Default(OMPC_BIND_unknown);190 case OMPC_grainsize: {191 unsigned Type = llvm::StringSwitch<unsigned>(Str)192#define OPENMP_GRAINSIZE_MODIFIER(Name) .Case(#Name, OMPC_GRAINSIZE_##Name)193#include "clang/Basic/OpenMPKinds.def"194 .Default(OMPC_GRAINSIZE_unknown);195 if (LangOpts.OpenMP < 51)196 return OMPC_GRAINSIZE_unknown;197 return Type;198 }199 case OMPC_dyn_groupprivate: {200 return llvm::StringSwitch<unsigned>(Str)201#define OPENMP_DYN_GROUPPRIVATE_MODIFIER(Name) \202 .Case(#Name, OMPC_DYN_GROUPPRIVATE_##Name)203#define OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(Name) \204 .Case(#Name, OMPC_DYN_GROUPPRIVATE_FALLBACK_##Name) \205 .Case("fallback(" #Name ")", OMPC_DYN_GROUPPRIVATE_FALLBACK_##Name)206#include "clang/Basic/OpenMPKinds.def"207 .Default(OMPC_DYN_GROUPPRIVATE_unknown);208 }209 case OMPC_num_tasks: {210 unsigned Type = llvm::StringSwitch<unsigned>(Str)211#define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name)212#include "clang/Basic/OpenMPKinds.def"213 .Default(OMPC_NUMTASKS_unknown);214 if (LangOpts.OpenMP < 51)215 return OMPC_NUMTASKS_unknown;216 return Type;217 }218 case OMPC_allocate:219 return llvm::StringSwitch<OpenMPAllocateClauseModifier>(Str)220#define OPENMP_ALLOCATE_MODIFIER(Name) .Case(#Name, OMPC_ALLOCATE_##Name)221#include "clang/Basic/OpenMPKinds.def"222 .Default(OMPC_ALLOCATE_unknown);223 case OMPC_threadset: {224 unsigned Type = llvm::StringSwitch<unsigned>(Str)225#define OPENMP_THREADSET_KIND(Name) .Case(#Name, OMPC_THREADSET_##Name)226#include "clang/Basic/OpenMPKinds.def"227 .Default(OMPC_THREADSET_unknown);228 if (LangOpts.OpenMP < 60)229 return OMPC_THREADSET_unknown;230 return Type;231 }232 case OMPC_num_threads: {233 unsigned Type = llvm::StringSwitch<unsigned>(Str)234#define OPENMP_NUMTHREADS_MODIFIER(Name) .Case(#Name, OMPC_NUMTHREADS_##Name)235#include "clang/Basic/OpenMPKinds.def"236 .Default(OMPC_NUMTHREADS_unknown);237 if (LangOpts.OpenMP < 60)238 return OMPC_NUMTHREADS_unknown;239 return Type;240 }241 case OMPC_unknown:242 case OMPC_threadprivate:243 case OMPC_groupprivate:244 case OMPC_if:245 case OMPC_final:246 case OMPC_safelen:247 case OMPC_simdlen:248 case OMPC_sizes:249 case OMPC_permutation:250 case OMPC_allocator:251 case OMPC_collapse:252 case OMPC_private:253 case OMPC_firstprivate:254 case OMPC_shared:255 case OMPC_task_reduction:256 case OMPC_in_reduction:257 case OMPC_aligned:258 case OMPC_copyin:259 case OMPC_copyprivate:260 case OMPC_ordered:261 case OMPC_nowait:262 case OMPC_untied:263 case OMPC_mergeable:264 case OMPC_flush:265 case OMPC_depobj:266 case OMPC_read:267 case OMPC_write:268 case OMPC_capture:269 case OMPC_compare:270 case OMPC_seq_cst:271 case OMPC_acq_rel:272 case OMPC_acquire:273 case OMPC_release:274 case OMPC_relaxed:275 case OMPC_threads:276 case OMPC_simd:277 case OMPC_num_teams:278 case OMPC_thread_limit:279 case OMPC_priority:280 case OMPC_nogroup:281 case OMPC_hint:282 case OMPC_uniform:283 case OMPC_use_device_ptr:284 case OMPC_use_device_addr:285 case OMPC_is_device_ptr:286 case OMPC_has_device_addr:287 case OMPC_unified_address:288 case OMPC_unified_shared_memory:289 case OMPC_reverse_offload:290 case OMPC_dynamic_allocators:291 case OMPC_self_maps:292 case OMPC_match:293 case OMPC_nontemporal:294 case OMPC_destroy:295 case OMPC_novariants:296 case OMPC_nocontext:297 case OMPC_detach:298 case OMPC_inclusive:299 case OMPC_exclusive:300 case OMPC_uses_allocators:301 case OMPC_affinity:302 case OMPC_when:303 case OMPC_append_args:304 case OMPC_looprange:305 break;306 default:307 break;308 }309 llvm_unreachable("Invalid OpenMP simple clause kind");310}311 312const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,313 unsigned Type) {314 switch (Kind) {315 case OMPC_default:316 switch (llvm::omp::DefaultKind(Type)) {317#define OMP_DEFAULT_KIND(Enum, Name) \318 case Enum: \319 return Name;320#include "llvm/Frontend/OpenMP/OMPKinds.def"321 }322 llvm_unreachable("Invalid OpenMP 'default' clause type");323 case OMPC_proc_bind:324 switch (Type) {325#define OMP_PROC_BIND_KIND(Enum, Name, Value) \326 case Value: \327 return Name;328#include "llvm/Frontend/OpenMP/OMPKinds.def"329 }330 llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");331 case OMPC_schedule:332 switch (Type) {333 case OMPC_SCHEDULE_unknown:334 case OMPC_SCHEDULE_MODIFIER_last:335 return "unknown";336#define OPENMP_SCHEDULE_KIND(Name) \337 case OMPC_SCHEDULE_##Name: \338 return #Name;339#define OPENMP_SCHEDULE_MODIFIER(Name) \340 case OMPC_SCHEDULE_MODIFIER_##Name: \341 return #Name;342#include "clang/Basic/OpenMPKinds.def"343 }344 llvm_unreachable("Invalid OpenMP 'schedule' clause type");345 case OMPC_depend:346 switch (Type) {347 case OMPC_DEPEND_unknown:348 return "unknown";349#define OPENMP_DEPEND_KIND(Name) \350 case OMPC_DEPEND_##Name: \351 return #Name;352#include "clang/Basic/OpenMPKinds.def"353 }354 llvm_unreachable("Invalid OpenMP 'depend' clause type");355 case OMPC_doacross:356 switch (Type) {357 case OMPC_DOACROSS_unknown:358 return "unknown";359#define OPENMP_DOACROSS_MODIFIER(Name) \360 case OMPC_DOACROSS_##Name: \361 return #Name;362#include "clang/Basic/OpenMPKinds.def"363 }364 llvm_unreachable("Invalid OpenMP 'doacross' clause type");365 case OMPC_linear:366 switch (Type) {367 case OMPC_LINEAR_unknown:368 return "unknown";369#define OPENMP_LINEAR_KIND(Name) \370 case OMPC_LINEAR_##Name: \371 return #Name;372#include "clang/Basic/OpenMPKinds.def"373 }374 llvm_unreachable("Invalid OpenMP 'linear' clause type");375 case OMPC_map:376 switch (Type) {377 case OMPC_MAP_unknown:378 case OMPC_MAP_MODIFIER_last:379 return "unknown";380#define OPENMP_MAP_KIND(Name) \381 case OMPC_MAP_##Name: \382 return #Name;383#define OPENMP_MAP_MODIFIER_KIND(Name) \384 case OMPC_MAP_MODIFIER_##Name: \385 return #Name;386#include "clang/Basic/OpenMPKinds.def"387 default:388 break;389 }390 llvm_unreachable("Invalid OpenMP 'map' clause type");391 case OMPC_to:392 case OMPC_from:393 switch (Type) {394 case OMPC_MOTION_MODIFIER_unknown:395 return "unknown";396#define OPENMP_MOTION_MODIFIER_KIND(Name) \397 case OMPC_MOTION_MODIFIER_##Name: \398 return #Name;399#include "clang/Basic/OpenMPKinds.def"400 default:401 break;402 }403 llvm_unreachable("Invalid OpenMP 'to' or 'from' clause type");404 case OMPC_dist_schedule:405 switch (Type) {406 case OMPC_DIST_SCHEDULE_unknown:407 return "unknown";408#define OPENMP_DIST_SCHEDULE_KIND(Name) \409 case OMPC_DIST_SCHEDULE_##Name: \410 return #Name;411#include "clang/Basic/OpenMPKinds.def"412 }413 llvm_unreachable("Invalid OpenMP 'dist_schedule' clause type");414 case OMPC_defaultmap:415 switch (Type) {416 case OMPC_DEFAULTMAP_unknown:417 case OMPC_DEFAULTMAP_MODIFIER_last:418 return "unknown";419#define OPENMP_DEFAULTMAP_KIND(Name) \420 case OMPC_DEFAULTMAP_##Name: \421 return #Name;422#define OPENMP_DEFAULTMAP_MODIFIER(Name) \423 case OMPC_DEFAULTMAP_MODIFIER_##Name: \424 return #Name;425#include "clang/Basic/OpenMPKinds.def"426 }427 llvm_unreachable("Invalid OpenMP 'defaultmap' clause type");428 case OMPC_atomic_default_mem_order:429 switch (Type) {430 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown:431 return "unknown";432#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \433 case OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name: \434 return #Name;435#include "clang/Basic/OpenMPKinds.def"436}437 llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type");438 case OMPC_device_type:439 switch (Type) {440 case OMPC_DEVICE_TYPE_unknown:441 return "unknown";442#define OPENMP_DEVICE_TYPE_KIND(Name) \443 case OMPC_DEVICE_TYPE_##Name: \444 return #Name;445#include "clang/Basic/OpenMPKinds.def"446 }447 llvm_unreachable("Invalid OpenMP 'device_type' clause type");448 case OMPC_at:449 switch (Type) {450 case OMPC_AT_unknown:451 return "unknown";452#define OPENMP_AT_KIND(Name) \453 case OMPC_AT_##Name: \454 return #Name;455#include "clang/Basic/OpenMPKinds.def"456 }457 llvm_unreachable("Invalid OpenMP 'at' clause type");458 case OMPC_severity:459 switch (Type) {460 case OMPC_SEVERITY_unknown:461 return "unknown";462#define OPENMP_SEVERITY_KIND(Name) \463 case OMPC_SEVERITY_##Name: \464 return #Name;465#include "clang/Basic/OpenMPKinds.def"466 }467 llvm_unreachable("Invalid OpenMP 'severity' clause type");468 case OMPC_lastprivate:469 switch (Type) {470 case OMPC_LASTPRIVATE_unknown:471 return "unknown";472#define OPENMP_LASTPRIVATE_KIND(Name) \473 case OMPC_LASTPRIVATE_##Name: \474 return #Name;475#include "clang/Basic/OpenMPKinds.def"476 }477 llvm_unreachable("Invalid OpenMP 'lastprivate' clause type");478 case OMPC_order:479 switch (Type) {480 case OMPC_ORDER_unknown:481 case OMPC_ORDER_MODIFIER_last:482 return "unknown";483#define OPENMP_ORDER_KIND(Name) \484 case OMPC_ORDER_##Name: \485 return #Name;486#define OPENMP_ORDER_MODIFIER(Name) \487 case OMPC_ORDER_MODIFIER_##Name: \488 return #Name;489#include "clang/Basic/OpenMPKinds.def"490 }491 llvm_unreachable("Invalid OpenMP 'order' clause type");492 case OMPC_update:493 switch (Type) {494 case OMPC_DEPEND_unknown:495 return "unknown";496#define OPENMP_DEPEND_KIND(Name) \497 case OMPC_DEPEND_##Name: \498 return #Name;499#include "clang/Basic/OpenMPKinds.def"500 }501 llvm_unreachable("Invalid OpenMP 'depend' clause type");502 case OMPC_fail: {503 OpenMPClauseKind CK = static_cast<OpenMPClauseKind>(Type);504 return getOpenMPClauseName(CK).data();505 llvm_unreachable("Invalid OpenMP 'fail' clause modifier");506 }507 case OMPC_device:508 switch (Type) {509 case OMPC_DEVICE_unknown:510 return "unknown";511#define OPENMP_DEVICE_MODIFIER(Name) \512 case OMPC_DEVICE_##Name: \513 return #Name;514#include "clang/Basic/OpenMPKinds.def"515 }516 llvm_unreachable("Invalid OpenMP 'device' clause modifier");517 case OMPC_reduction:518 switch (Type) {519 case OMPC_REDUCTION_unknown:520 return "unknown";521#define OPENMP_REDUCTION_MODIFIER(Name) \522 case OMPC_REDUCTION_##Name: \523 return #Name;524#include "clang/Basic/OpenMPKinds.def"525 }526 llvm_unreachable("Invalid OpenMP 'reduction' clause modifier");527 case OMPC_adjust_args:528 switch (Type) {529 case OMPC_ADJUST_ARGS_unknown:530 return "unknown";531#define OPENMP_ADJUST_ARGS_KIND(Name) \532 case OMPC_ADJUST_ARGS_##Name: \533 return #Name;534#include "clang/Basic/OpenMPKinds.def"535 }536 llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind");537 case OMPC_bind:538 switch (Type) {539 case OMPC_BIND_unknown:540 return "unknown";541#define OPENMP_BIND_KIND(Name) \542 case OMPC_BIND_##Name: \543 return #Name;544#include "clang/Basic/OpenMPKinds.def"545 }546 llvm_unreachable("Invalid OpenMP 'bind' clause type");547 case OMPC_grainsize:548 switch (Type) {549 case OMPC_GRAINSIZE_unknown:550 return "unknown";551#define OPENMP_GRAINSIZE_MODIFIER(Name) \552 case OMPC_GRAINSIZE_##Name: \553 return #Name;554#include "clang/Basic/OpenMPKinds.def"555 }556 llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier");557 case OMPC_dyn_groupprivate:558 switch (Type) {559 case OMPC_DYN_GROUPPRIVATE_unknown:560 case OMPC_DYN_GROUPPRIVATE_FALLBACK_last:561 return "unknown";562#define OPENMP_DYN_GROUPPRIVATE_MODIFIER(Name) \563 case OMPC_DYN_GROUPPRIVATE_##Name: \564 return #Name;565#define OPENMP_DYN_GROUPPRIVATE_FALLBACK_MODIFIER(Name) \566 case OMPC_DYN_GROUPPRIVATE_FALLBACK_##Name: \567 return "fallback(" #Name ")";568#include "clang/Basic/OpenMPKinds.def"569 }570 llvm_unreachable("Invalid OpenMP 'dyn_groupprivate' clause modifier");571 case OMPC_num_tasks:572 switch (Type) {573 case OMPC_NUMTASKS_unknown:574 return "unknown";575#define OPENMP_NUMTASKS_MODIFIER(Name) \576 case OMPC_NUMTASKS_##Name: \577 return #Name;578#include "clang/Basic/OpenMPKinds.def"579 }580 llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");581 case OMPC_allocate:582 switch (Type) {583 case OMPC_ALLOCATE_unknown:584 return "unknown";585#define OPENMP_ALLOCATE_MODIFIER(Name) \586 case OMPC_ALLOCATE_##Name: \587 return #Name;588#include "clang/Basic/OpenMPKinds.def"589 }590 llvm_unreachable("Invalid OpenMP 'allocate' clause modifier");591 case OMPC_num_threads:592 switch (Type) {593 case OMPC_NUMTHREADS_unknown:594 return "unknown";595#define OPENMP_NUMTHREADS_MODIFIER(Name) \596 case OMPC_NUMTHREADS_##Name: \597 return #Name;598#include "clang/Basic/OpenMPKinds.def"599 }600 llvm_unreachable("Invalid OpenMP 'num_threads' clause modifier");601 case OMPC_threadset:602 switch (Type) {603 case OMPC_THREADSET_unknown:604 return "unknown";605#define OPENMP_THREADSET_KIND(Name) \606 case OMPC_THREADSET_##Name: \607 return #Name;608#include "clang/Basic/OpenMPKinds.def"609 }610 llvm_unreachable("Invalid OpenMP 'threadset' clause modifier");611 case OMPC_unknown:612 case OMPC_threadprivate:613 case OMPC_groupprivate:614 case OMPC_if:615 case OMPC_final:616 case OMPC_safelen:617 case OMPC_simdlen:618 case OMPC_sizes:619 case OMPC_permutation:620 case OMPC_allocator:621 case OMPC_collapse:622 case OMPC_private:623 case OMPC_firstprivate:624 case OMPC_shared:625 case OMPC_task_reduction:626 case OMPC_in_reduction:627 case OMPC_aligned:628 case OMPC_copyin:629 case OMPC_copyprivate:630 case OMPC_ordered:631 case OMPC_nowait:632 case OMPC_untied:633 case OMPC_mergeable:634 case OMPC_flush:635 case OMPC_depobj:636 case OMPC_read:637 case OMPC_write:638 case OMPC_capture:639 case OMPC_compare:640 case OMPC_seq_cst:641 case OMPC_acq_rel:642 case OMPC_acquire:643 case OMPC_release:644 case OMPC_relaxed:645 case OMPC_threads:646 case OMPC_simd:647 case OMPC_num_teams:648 case OMPC_thread_limit:649 case OMPC_priority:650 case OMPC_nogroup:651 case OMPC_hint:652 case OMPC_uniform:653 case OMPC_use_device_ptr:654 case OMPC_use_device_addr:655 case OMPC_is_device_ptr:656 case OMPC_has_device_addr:657 case OMPC_unified_address:658 case OMPC_unified_shared_memory:659 case OMPC_reverse_offload:660 case OMPC_dynamic_allocators:661 case OMPC_self_maps:662 case OMPC_match:663 case OMPC_nontemporal:664 case OMPC_destroy:665 case OMPC_detach:666 case OMPC_novariants:667 case OMPC_nocontext:668 case OMPC_inclusive:669 case OMPC_exclusive:670 case OMPC_uses_allocators:671 case OMPC_affinity:672 case OMPC_when:673 case OMPC_append_args:674 case OMPC_looprange:675 break;676 default:677 break;678 }679 llvm_unreachable("Invalid OpenMP simple clause kind");680}681 682bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {683 return getDirectiveAssociation(DKind) == Association::LoopNest;684}685 686bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {687 return DKind == OMPD_for || DKind == OMPD_for_simd ||688 DKind == OMPD_sections || DKind == OMPD_section ||689 DKind == OMPD_single || DKind == OMPD_parallel_for ||690 DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||691 DKind == OMPD_target_parallel_for ||692 DKind == OMPD_distribute_parallel_for ||693 DKind == OMPD_distribute_parallel_for_simd ||694 DKind == OMPD_target_parallel_for_simd ||695 DKind == OMPD_teams_distribute_parallel_for_simd ||696 DKind == OMPD_teams_distribute_parallel_for ||697 DKind == OMPD_target_teams_distribute_parallel_for ||698 DKind == OMPD_target_teams_distribute_parallel_for_simd ||699 DKind == OMPD_parallel_loop || DKind == OMPD_teams_loop ||700 DKind == OMPD_target_parallel_loop || DKind == OMPD_target_teams_loop;701}702 703bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {704 return DKind == OMPD_taskloop ||705 llvm::is_contained(getLeafConstructs(DKind), OMPD_taskloop);706}707 708bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {709 if (DKind == OMPD_teams_loop)710 return true;711 return DKind == OMPD_parallel ||712 llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);713}714 715bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {716 return DKind == OMPD_target ||717 llvm::is_contained(getLeafConstructs(DKind), OMPD_target);718}719 720bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {721 return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||722 DKind == OMPD_target_exit_data || DKind == OMPD_target_update;723}724 725bool clang::isOpenMPTargetMapEnteringDirective(OpenMPDirectiveKind DKind) {726 return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||727 isOpenMPTargetExecutionDirective(DKind);728}729 730bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {731 if (DKind == OMPD_teams)732 return true;733 ArrayRef<Directive> Leaves = getLeafConstructs(DKind);734 return !Leaves.empty() && Leaves.front() == OMPD_teams;735}736 737bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {738 return DKind == OMPD_teams ||739 llvm::is_contained(getLeafConstructs(DKind), OMPD_teams);740}741 742bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {743 // Avoid OMPD_declare_simd744 if (getDirectiveAssociation(DKind) != Association::LoopNest)745 return false;746 // Formally, OMPD_end_do_simd also has a loop association, but747 // it's a Fortran-specific directive.748 749 return DKind == OMPD_simd ||750 llvm::is_contained(getLeafConstructs(DKind), OMPD_simd);751}752 753bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {754 if (Kind == OMPD_distribute)755 return true;756 ArrayRef<Directive> Leaves = getLeafConstructs(Kind);757 return !Leaves.empty() && Leaves.front() == OMPD_distribute;758}759 760bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {761 return Kind == OMPD_distribute ||762 llvm::is_contained(getLeafConstructs(Kind), OMPD_distribute);763}764 765bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {766 if (Kind == OMPD_loop)767 return true;768 ArrayRef<Directive> Leaves = getLeafConstructs(Kind);769 return !Leaves.empty() && Leaves.back() == OMPD_loop;770}771 772bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {773 return Kind == OMPC_private || Kind == OMPC_firstprivate ||774 Kind == OMPC_lastprivate || Kind == OMPC_linear ||775 Kind == OMPC_reduction || Kind == OMPC_task_reduction ||776 Kind == OMPC_in_reduction; // TODO add next clauses like 'reduction'.777}778 779bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {780 return Kind == OMPC_threadprivate || Kind == OMPC_copyin;781}782 783bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) {784 return Kind == OMPD_task || isOpenMPTaskLoopDirective(Kind);785}786 787bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {788 return Kind == OMPD_distribute_parallel_for ||789 Kind == OMPD_distribute_parallel_for_simd ||790 Kind == OMPD_teams_distribute_parallel_for_simd ||791 Kind == OMPD_teams_distribute_parallel_for ||792 Kind == OMPD_target_teams_distribute_parallel_for ||793 Kind == OMPD_target_teams_distribute_parallel_for_simd ||794 Kind == OMPD_teams_loop || Kind == OMPD_target_teams_loop;795}796 797bool clang::isOpenMPCanonicalLoopNestTransformationDirective(798 OpenMPDirectiveKind DKind) {799 return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse ||800 DKind == OMPD_interchange || DKind == OMPD_stripe;801}802 803bool clang::isOpenMPCanonicalLoopSequenceTransformationDirective(804 OpenMPDirectiveKind DKind) {805 return DKind == OMPD_fuse;806}807 808bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) {809 return isOpenMPCanonicalLoopNestTransformationDirective(DKind) ||810 isOpenMPCanonicalLoopSequenceTransformationDirective(DKind);811}812 813bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) {814 return DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||815 DKind == OMPD_parallel_master ||816 DKind == OMPD_parallel_master_taskloop ||817 DKind == OMPD_parallel_master_taskloop_simd ||818 DKind == OMPD_parallel_sections;819}820 821bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind) {822 return DKind == OMPD_target || DKind == OMPD_target_parallel ||823 DKind == OMPD_target_parallel_for ||824 DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||825 DKind == OMPD_target_parallel_loop;826}827 828bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) {829 if (DKind == OMPD_error)830 return true;831 Category Cat = getDirectiveCategory(DKind);832 return Cat == Category::Executable || Cat == Category::Subsidiary;833}834 835bool clang::isOpenMPInformationalDirective(OpenMPDirectiveKind DKind) {836 if (DKind == OMPD_error)837 return true;838 Category Cat = getDirectiveCategory(DKind);839 return Cat == Category::Informational;840}841 842bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) {843 if (isOpenMPExecutableDirective(DKind)) {844 switch (DKind) {845 case OMPD_atomic:846 case OMPD_barrier:847 case OMPD_cancel:848 case OMPD_cancellation_point:849 case OMPD_critical:850 case OMPD_depobj:851 case OMPD_error:852 case OMPD_flush:853 case OMPD_masked:854 case OMPD_master:855 case OMPD_section:856 case OMPD_taskwait:857 case OMPD_taskyield:858 case OMPD_assume:859 return false;860 default:861 return !isOpenMPLoopTransformationDirective(DKind);862 }863 }864 // Non-executable directives.865 switch (DKind) {866 case OMPD_metadirective:867 case OMPD_nothing:868 return true;869 default:870 break;871 }872 return false;873}874 875bool clang::isOpenMPOrderConcurrentNestableDirective(876 OpenMPDirectiveKind DKind, const LangOptions &LangOpts) {877 // Directives strictly nestable in a construct with order(concurrent) are:878 // OpenMP 5.x: loop, parallel, simd, combined directive starting with parallel879 // OpenMP 6.0: above plus atomic and all loop-transformation directives880 881 if (DKind == OMPD_loop || DKind == OMPD_parallel || DKind == OMPD_simd ||882 isOpenMPCombinedParallelADirective(DKind))883 return true;884 885 if (LangOpts.OpenMP >= 60)886 return DKind == OMPD_atomic ||887 isOpenMPLoopTransformationDirective(DKind);888 889 return false;890}891 892void clang::getOpenMPCaptureRegions(893 SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,894 OpenMPDirectiveKind DKind) {895 assert(unsigned(DKind) < llvm::omp::Directive_enumSize);896 assert(isOpenMPCapturingDirective(DKind) && "Expecting capturing directive");897 898 auto GetRegionsForLeaf = [&](OpenMPDirectiveKind LKind) {899 assert(isLeafConstruct(LKind) && "Epecting leaf directive");900 // Whether a leaf would require OMPD_unknown if it occured on its own.901 switch (LKind) {902 case OMPD_metadirective:903 CaptureRegions.push_back(OMPD_metadirective);904 break;905 case OMPD_nothing:906 CaptureRegions.push_back(OMPD_nothing);907 break;908 case OMPD_parallel:909 CaptureRegions.push_back(OMPD_parallel);910 break;911 case OMPD_target:912 CaptureRegions.push_back(OMPD_task);913 CaptureRegions.push_back(OMPD_target);914 break;915 case OMPD_task:916 case OMPD_target_enter_data:917 case OMPD_target_exit_data:918 case OMPD_target_update:919 CaptureRegions.push_back(OMPD_task);920 break;921 case OMPD_teams:922 CaptureRegions.push_back(OMPD_teams);923 break;924 case OMPD_taskloop:925 CaptureRegions.push_back(OMPD_taskloop);926 break;927 case OMPD_loop:928 // TODO: 'loop' may require different capture regions depending on the929 // bind clause or the parent directive when there is no bind clause.930 // If any of the directives that push regions here are parents of 'loop',931 // assume 'parallel'. Otherwise do nothing.932 if (!CaptureRegions.empty() &&933 !llvm::is_contained(CaptureRegions, OMPD_parallel))934 CaptureRegions.push_back(OMPD_parallel);935 else936 return true;937 break;938 case OMPD_dispatch:939 case OMPD_distribute:940 case OMPD_for:941 case OMPD_ordered:942 case OMPD_scope:943 case OMPD_sections:944 case OMPD_simd:945 case OMPD_single:946 case OMPD_target_data:947 case OMPD_taskgroup:948 case OMPD_stripe:949 // These directives (when standalone) use OMPD_unknown as the region,950 // but when they're constituents of a compound directive, and other951 // leafs from that directive have specific regions, then these directives952 // add no additional regions.953 return true;954 case OMPD_masked:955 case OMPD_master:956 return false;957 default:958 llvm::errs() << getOpenMPDirectiveName(LKind, llvm::omp::FallbackVersion)959 << '\n';960 llvm_unreachable("Unexpected directive");961 }962 return false;963 };964 965 bool MayNeedUnknownRegion = false;966 for (OpenMPDirectiveKind L : getLeafConstructsOrSelf(DKind))967 MayNeedUnknownRegion |= GetRegionsForLeaf(L);968 969 // We need OMPD_unknown when no regions were added, and specific leaf970 // constructs were present. Push a single OMPD_unknown as the capture971 /// region.972 if (CaptureRegions.empty() && MayNeedUnknownRegion)973 CaptureRegions.push_back(OMPD_unknown);974 975 // OMPD_unknown is only expected as the only region. If other regions976 // are present OMPD_unknown should not be present.977 assert((CaptureRegions[0] == OMPD_unknown ||978 !llvm::is_contained(CaptureRegions, OMPD_unknown)) &&979 "Misplaced OMPD_unknown");980}981 982bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter) {983 return FailClauseParameter == llvm::omp::OMPC_acquire ||984 FailClauseParameter == llvm::omp::OMPC_relaxed ||985 FailClauseParameter == llvm::omp::OMPC_seq_cst;986}987