Path: blob/main/contrib/llvm-project/clang/lib/Basic/OpenMPKinds.cpp
35234 views
//===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7/// \file8/// This file implements the OpenMP enum and support functions.9///10//===----------------------------------------------------------------------===//1112#include "clang/Basic/OpenMPKinds.h"13#include "clang/Basic/IdentifierTable.h"14#include "llvm/ADT/StringRef.h"15#include "llvm/ADT/StringSwitch.h"16#include "llvm/Support/ErrorHandling.h"17#include <cassert>1819using namespace clang;20using namespace llvm::omp;2122unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, StringRef Str,23const LangOptions &LangOpts) {24switch (Kind) {25case OMPC_default:26return llvm::StringSwitch<unsigned>(Str)27#define OMP_DEFAULT_KIND(Enum, Name) .Case(Name, unsigned(Enum))28#include "llvm/Frontend/OpenMP/OMPKinds.def"29.Default(unsigned(llvm::omp::OMP_DEFAULT_unknown));30case OMPC_proc_bind:31return llvm::StringSwitch<unsigned>(Str)32#define OMP_PROC_BIND_KIND(Enum, Name, Value) .Case(Name, Value)33#include "llvm/Frontend/OpenMP/OMPKinds.def"34.Default(unsigned(llvm::omp::OMP_PROC_BIND_unknown));35case OMPC_schedule:36return llvm::StringSwitch<unsigned>(Str)37#define OPENMP_SCHEDULE_KIND(Name) \38.Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_##Name))39#define OPENMP_SCHEDULE_MODIFIER(Name) \40.Case(#Name, static_cast<unsigned>(OMPC_SCHEDULE_MODIFIER_##Name))41#include "clang/Basic/OpenMPKinds.def"42.Default(OMPC_SCHEDULE_unknown);43case OMPC_depend: {44unsigned Type = llvm::StringSwitch<unsigned>(Str)45#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)46#include "clang/Basic/OpenMPKinds.def"47.Default(OMPC_DEPEND_unknown);48if (LangOpts.OpenMP < 51 && Type == OMPC_DEPEND_inoutset)49return OMPC_DEPEND_unknown;50return Type;51}52case OMPC_doacross:53return llvm::StringSwitch<OpenMPDoacrossClauseModifier>(Str)54#define OPENMP_DOACROSS_MODIFIER(Name) .Case(#Name, OMPC_DOACROSS_##Name)55#include "clang/Basic/OpenMPKinds.def"56.Default(OMPC_DOACROSS_unknown);57case OMPC_linear:58return llvm::StringSwitch<OpenMPLinearClauseKind>(Str)59#define OPENMP_LINEAR_KIND(Name) .Case(#Name, OMPC_LINEAR_##Name)60#include "clang/Basic/OpenMPKinds.def"61.Default(OMPC_LINEAR_unknown);62case OMPC_map: {63unsigned Type = llvm::StringSwitch<unsigned>(Str)64#define OPENMP_MAP_KIND(Name) \65.Case(#Name, static_cast<unsigned>(OMPC_MAP_##Name))66#define OPENMP_MAP_MODIFIER_KIND(Name) \67.Case(#Name, static_cast<unsigned>(OMPC_MAP_MODIFIER_##Name))68#include "clang/Basic/OpenMPKinds.def"69.Default(OMPC_MAP_unknown);70if (LangOpts.OpenMP < 51 && Type == OMPC_MAP_MODIFIER_present)71return OMPC_MAP_MODIFIER_unknown;72if (!LangOpts.OpenMPExtensions && Type == OMPC_MAP_MODIFIER_ompx_hold)73return OMPC_MAP_MODIFIER_unknown;74return Type;75}76case OMPC_to:77case OMPC_from: {78unsigned Type = llvm::StringSwitch<unsigned>(Str)79#define OPENMP_MOTION_MODIFIER_KIND(Name) \80.Case(#Name, static_cast<unsigned>(OMPC_MOTION_MODIFIER_##Name))81#include "clang/Basic/OpenMPKinds.def"82.Default(OMPC_MOTION_MODIFIER_unknown);83if (LangOpts.OpenMP < 51 && Type == OMPC_MOTION_MODIFIER_present)84return OMPC_MOTION_MODIFIER_unknown;85return Type;86}87case OMPC_dist_schedule:88return llvm::StringSwitch<OpenMPDistScheduleClauseKind>(Str)89#define OPENMP_DIST_SCHEDULE_KIND(Name) .Case(#Name, OMPC_DIST_SCHEDULE_##Name)90#include "clang/Basic/OpenMPKinds.def"91.Default(OMPC_DIST_SCHEDULE_unknown);92case OMPC_defaultmap:93return llvm::StringSwitch<unsigned>(Str)94#define OPENMP_DEFAULTMAP_KIND(Name) \95.Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_##Name))96#define OPENMP_DEFAULTMAP_MODIFIER(Name) \97.Case(#Name, static_cast<unsigned>(OMPC_DEFAULTMAP_MODIFIER_##Name))98#include "clang/Basic/OpenMPKinds.def"99.Default(OMPC_DEFAULTMAP_unknown);100case OMPC_atomic_default_mem_order:101return llvm::StringSwitch<OpenMPAtomicDefaultMemOrderClauseKind>(Str)102#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \103.Case(#Name, OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name)104#include "clang/Basic/OpenMPKinds.def"105.Default(OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown);106case OMPC_fail:107return static_cast<unsigned int>(llvm::StringSwitch<llvm::omp::Clause>(Str)108#define OPENMP_ATOMIC_FAIL_MODIFIER(Name) .Case(#Name, OMPC_##Name)109#include "clang/Basic/OpenMPKinds.def"110.Default(OMPC_unknown));111case OMPC_device_type:112return llvm::StringSwitch<OpenMPDeviceType>(Str)113#define OPENMP_DEVICE_TYPE_KIND(Name) .Case(#Name, OMPC_DEVICE_TYPE_##Name)114#include "clang/Basic/OpenMPKinds.def"115.Default(OMPC_DEVICE_TYPE_unknown);116case OMPC_at:117return llvm::StringSwitch<OpenMPAtClauseKind>(Str)118#define OPENMP_AT_KIND(Name) .Case(#Name, OMPC_AT_##Name)119#include "clang/Basic/OpenMPKinds.def"120.Default(OMPC_AT_unknown);121case OMPC_severity:122return llvm::StringSwitch<OpenMPSeverityClauseKind>(Str)123#define OPENMP_SEVERITY_KIND(Name) .Case(#Name, OMPC_SEVERITY_##Name)124#include "clang/Basic/OpenMPKinds.def"125.Default(OMPC_SEVERITY_unknown);126case OMPC_lastprivate:127return llvm::StringSwitch<OpenMPLastprivateModifier>(Str)128#define OPENMP_LASTPRIVATE_KIND(Name) .Case(#Name, OMPC_LASTPRIVATE_##Name)129#include "clang/Basic/OpenMPKinds.def"130.Default(OMPC_LASTPRIVATE_unknown);131case OMPC_order:132return llvm::StringSwitch<unsigned>(Str)133#define OPENMP_ORDER_KIND(Name) \134.Case(#Name, static_cast<unsigned>(OMPC_ORDER_##Name))135#define OPENMP_ORDER_MODIFIER(Name) \136.Case(#Name, static_cast<unsigned>(OMPC_ORDER_MODIFIER_##Name))137#include "clang/Basic/OpenMPKinds.def"138.Default(OMPC_ORDER_unknown);139case OMPC_update:140return llvm::StringSwitch<OpenMPDependClauseKind>(Str)141#define OPENMP_DEPEND_KIND(Name) .Case(#Name, OMPC_DEPEND_##Name)142#include "clang/Basic/OpenMPKinds.def"143.Default(OMPC_DEPEND_unknown);144case OMPC_device:145return llvm::StringSwitch<OpenMPDeviceClauseModifier>(Str)146#define OPENMP_DEVICE_MODIFIER(Name) .Case(#Name, OMPC_DEVICE_##Name)147#include "clang/Basic/OpenMPKinds.def"148.Default(OMPC_DEVICE_unknown);149case OMPC_reduction:150return llvm::StringSwitch<OpenMPReductionClauseModifier>(Str)151#define OPENMP_REDUCTION_MODIFIER(Name) .Case(#Name, OMPC_REDUCTION_##Name)152#include "clang/Basic/OpenMPKinds.def"153.Default(OMPC_REDUCTION_unknown);154case OMPC_adjust_args:155return llvm::StringSwitch<OpenMPAdjustArgsOpKind>(Str)156#define OPENMP_ADJUST_ARGS_KIND(Name) .Case(#Name, OMPC_ADJUST_ARGS_##Name)157#include "clang/Basic/OpenMPKinds.def"158.Default(OMPC_ADJUST_ARGS_unknown);159case OMPC_bind:160return llvm::StringSwitch<unsigned>(Str)161#define OPENMP_BIND_KIND(Name) .Case(#Name, OMPC_BIND_##Name)162#include "clang/Basic/OpenMPKinds.def"163.Default(OMPC_BIND_unknown);164case OMPC_grainsize: {165unsigned Type = llvm::StringSwitch<unsigned>(Str)166#define OPENMP_GRAINSIZE_MODIFIER(Name) .Case(#Name, OMPC_GRAINSIZE_##Name)167#include "clang/Basic/OpenMPKinds.def"168.Default(OMPC_GRAINSIZE_unknown);169if (LangOpts.OpenMP < 51)170return OMPC_GRAINSIZE_unknown;171return Type;172}173case OMPC_num_tasks: {174unsigned Type = llvm::StringSwitch<unsigned>(Str)175#define OPENMP_NUMTASKS_MODIFIER(Name) .Case(#Name, OMPC_NUMTASKS_##Name)176#include "clang/Basic/OpenMPKinds.def"177.Default(OMPC_NUMTASKS_unknown);178if (LangOpts.OpenMP < 51)179return OMPC_NUMTASKS_unknown;180return Type;181}182case OMPC_unknown:183case OMPC_threadprivate:184case OMPC_if:185case OMPC_final:186case OMPC_num_threads:187case OMPC_safelen:188case OMPC_simdlen:189case OMPC_sizes:190case OMPC_allocator:191case OMPC_allocate:192case OMPC_collapse:193case OMPC_private:194case OMPC_firstprivate:195case OMPC_shared:196case OMPC_task_reduction:197case OMPC_in_reduction:198case OMPC_aligned:199case OMPC_copyin:200case OMPC_copyprivate:201case OMPC_ordered:202case OMPC_nowait:203case OMPC_untied:204case OMPC_mergeable:205case OMPC_flush:206case OMPC_depobj:207case OMPC_read:208case OMPC_write:209case OMPC_capture:210case OMPC_compare:211case OMPC_seq_cst:212case OMPC_acq_rel:213case OMPC_acquire:214case OMPC_release:215case OMPC_relaxed:216case OMPC_threads:217case OMPC_simd:218case OMPC_num_teams:219case OMPC_thread_limit:220case OMPC_priority:221case OMPC_nogroup:222case OMPC_hint:223case OMPC_uniform:224case OMPC_use_device_ptr:225case OMPC_use_device_addr:226case OMPC_is_device_ptr:227case OMPC_has_device_addr:228case OMPC_unified_address:229case OMPC_unified_shared_memory:230case OMPC_reverse_offload:231case OMPC_dynamic_allocators:232case OMPC_match:233case OMPC_nontemporal:234case OMPC_destroy:235case OMPC_novariants:236case OMPC_nocontext:237case OMPC_detach:238case OMPC_inclusive:239case OMPC_exclusive:240case OMPC_uses_allocators:241case OMPC_affinity:242case OMPC_when:243case OMPC_append_args:244break;245default:246break;247}248llvm_unreachable("Invalid OpenMP simple clause kind");249}250251const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,252unsigned Type) {253switch (Kind) {254case OMPC_default:255switch (llvm::omp::DefaultKind(Type)) {256#define OMP_DEFAULT_KIND(Enum, Name) \257case Enum: \258return Name;259#include "llvm/Frontend/OpenMP/OMPKinds.def"260}261llvm_unreachable("Invalid OpenMP 'default' clause type");262case OMPC_proc_bind:263switch (Type) {264#define OMP_PROC_BIND_KIND(Enum, Name, Value) \265case Value: \266return Name;267#include "llvm/Frontend/OpenMP/OMPKinds.def"268}269llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");270case OMPC_schedule:271switch (Type) {272case OMPC_SCHEDULE_unknown:273case OMPC_SCHEDULE_MODIFIER_last:274return "unknown";275#define OPENMP_SCHEDULE_KIND(Name) \276case OMPC_SCHEDULE_##Name: \277return #Name;278#define OPENMP_SCHEDULE_MODIFIER(Name) \279case OMPC_SCHEDULE_MODIFIER_##Name: \280return #Name;281#include "clang/Basic/OpenMPKinds.def"282}283llvm_unreachable("Invalid OpenMP 'schedule' clause type");284case OMPC_depend:285switch (Type) {286case OMPC_DEPEND_unknown:287return "unknown";288#define OPENMP_DEPEND_KIND(Name) \289case OMPC_DEPEND_##Name: \290return #Name;291#include "clang/Basic/OpenMPKinds.def"292}293llvm_unreachable("Invalid OpenMP 'depend' clause type");294case OMPC_doacross:295switch (Type) {296case OMPC_DOACROSS_unknown:297return "unknown";298#define OPENMP_DOACROSS_MODIFIER(Name) \299case OMPC_DOACROSS_##Name: \300return #Name;301#include "clang/Basic/OpenMPKinds.def"302}303llvm_unreachable("Invalid OpenMP 'doacross' clause type");304case OMPC_linear:305switch (Type) {306case OMPC_LINEAR_unknown:307return "unknown";308#define OPENMP_LINEAR_KIND(Name) \309case OMPC_LINEAR_##Name: \310return #Name;311#include "clang/Basic/OpenMPKinds.def"312}313llvm_unreachable("Invalid OpenMP 'linear' clause type");314case OMPC_map:315switch (Type) {316case OMPC_MAP_unknown:317case OMPC_MAP_MODIFIER_last:318return "unknown";319#define OPENMP_MAP_KIND(Name) \320case OMPC_MAP_##Name: \321return #Name;322#define OPENMP_MAP_MODIFIER_KIND(Name) \323case OMPC_MAP_MODIFIER_##Name: \324return #Name;325#include "clang/Basic/OpenMPKinds.def"326default:327break;328}329llvm_unreachable("Invalid OpenMP 'map' clause type");330case OMPC_to:331case OMPC_from:332switch (Type) {333case OMPC_MOTION_MODIFIER_unknown:334return "unknown";335#define OPENMP_MOTION_MODIFIER_KIND(Name) \336case OMPC_MOTION_MODIFIER_##Name: \337return #Name;338#include "clang/Basic/OpenMPKinds.def"339default:340break;341}342llvm_unreachable("Invalid OpenMP 'to' or 'from' clause type");343case OMPC_dist_schedule:344switch (Type) {345case OMPC_DIST_SCHEDULE_unknown:346return "unknown";347#define OPENMP_DIST_SCHEDULE_KIND(Name) \348case OMPC_DIST_SCHEDULE_##Name: \349return #Name;350#include "clang/Basic/OpenMPKinds.def"351}352llvm_unreachable("Invalid OpenMP 'dist_schedule' clause type");353case OMPC_defaultmap:354switch (Type) {355case OMPC_DEFAULTMAP_unknown:356case OMPC_DEFAULTMAP_MODIFIER_last:357return "unknown";358#define OPENMP_DEFAULTMAP_KIND(Name) \359case OMPC_DEFAULTMAP_##Name: \360return #Name;361#define OPENMP_DEFAULTMAP_MODIFIER(Name) \362case OMPC_DEFAULTMAP_MODIFIER_##Name: \363return #Name;364#include "clang/Basic/OpenMPKinds.def"365}366llvm_unreachable("Invalid OpenMP 'schedule' clause type");367case OMPC_atomic_default_mem_order:368switch (Type) {369case OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown:370return "unknown";371#define OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(Name) \372case OMPC_ATOMIC_DEFAULT_MEM_ORDER_##Name: \373return #Name;374#include "clang/Basic/OpenMPKinds.def"375}376llvm_unreachable("Invalid OpenMP 'atomic_default_mem_order' clause type");377case OMPC_device_type:378switch (Type) {379case OMPC_DEVICE_TYPE_unknown:380return "unknown";381#define OPENMP_DEVICE_TYPE_KIND(Name) \382case OMPC_DEVICE_TYPE_##Name: \383return #Name;384#include "clang/Basic/OpenMPKinds.def"385}386llvm_unreachable("Invalid OpenMP 'device_type' clause type");387case OMPC_at:388switch (Type) {389case OMPC_AT_unknown:390return "unknown";391#define OPENMP_AT_KIND(Name) \392case OMPC_AT_##Name: \393return #Name;394#include "clang/Basic/OpenMPKinds.def"395}396llvm_unreachable("Invalid OpenMP 'at' clause type");397case OMPC_severity:398switch (Type) {399case OMPC_SEVERITY_unknown:400return "unknown";401#define OPENMP_SEVERITY_KIND(Name) \402case OMPC_SEVERITY_##Name: \403return #Name;404#include "clang/Basic/OpenMPKinds.def"405}406llvm_unreachable("Invalid OpenMP 'severity' clause type");407case OMPC_lastprivate:408switch (Type) {409case OMPC_LASTPRIVATE_unknown:410return "unknown";411#define OPENMP_LASTPRIVATE_KIND(Name) \412case OMPC_LASTPRIVATE_##Name: \413return #Name;414#include "clang/Basic/OpenMPKinds.def"415}416llvm_unreachable("Invalid OpenMP 'lastprivate' clause type");417case OMPC_order:418switch (Type) {419case OMPC_ORDER_unknown:420case OMPC_ORDER_MODIFIER_last:421return "unknown";422#define OPENMP_ORDER_KIND(Name) \423case OMPC_ORDER_##Name: \424return #Name;425#define OPENMP_ORDER_MODIFIER(Name) \426case OMPC_ORDER_MODIFIER_##Name: \427return #Name;428#include "clang/Basic/OpenMPKinds.def"429}430llvm_unreachable("Invalid OpenMP 'order' clause type");431case OMPC_update:432switch (Type) {433case OMPC_DEPEND_unknown:434return "unknown";435#define OPENMP_DEPEND_KIND(Name) \436case OMPC_DEPEND_##Name: \437return #Name;438#include "clang/Basic/OpenMPKinds.def"439}440llvm_unreachable("Invalid OpenMP 'depend' clause type");441case OMPC_fail: {442OpenMPClauseKind CK = static_cast<OpenMPClauseKind>(Type);443return getOpenMPClauseName(CK).data();444llvm_unreachable("Invalid OpenMP 'fail' clause modifier");445}446case OMPC_device:447switch (Type) {448case OMPC_DEVICE_unknown:449return "unknown";450#define OPENMP_DEVICE_MODIFIER(Name) \451case OMPC_DEVICE_##Name: \452return #Name;453#include "clang/Basic/OpenMPKinds.def"454}455llvm_unreachable("Invalid OpenMP 'device' clause modifier");456case OMPC_reduction:457switch (Type) {458case OMPC_REDUCTION_unknown:459return "unknown";460#define OPENMP_REDUCTION_MODIFIER(Name) \461case OMPC_REDUCTION_##Name: \462return #Name;463#include "clang/Basic/OpenMPKinds.def"464}465llvm_unreachable("Invalid OpenMP 'reduction' clause modifier");466case OMPC_adjust_args:467switch (Type) {468case OMPC_ADJUST_ARGS_unknown:469return "unknown";470#define OPENMP_ADJUST_ARGS_KIND(Name) \471case OMPC_ADJUST_ARGS_##Name: \472return #Name;473#include "clang/Basic/OpenMPKinds.def"474}475llvm_unreachable("Invalid OpenMP 'adjust_args' clause kind");476case OMPC_bind:477switch (Type) {478case OMPC_BIND_unknown:479return "unknown";480#define OPENMP_BIND_KIND(Name) \481case OMPC_BIND_##Name: \482return #Name;483#include "clang/Basic/OpenMPKinds.def"484}485llvm_unreachable("Invalid OpenMP 'bind' clause type");486case OMPC_grainsize:487switch (Type) {488case OMPC_GRAINSIZE_unknown:489return "unknown";490#define OPENMP_GRAINSIZE_MODIFIER(Name) \491case OMPC_GRAINSIZE_##Name: \492return #Name;493#include "clang/Basic/OpenMPKinds.def"494}495llvm_unreachable("Invalid OpenMP 'grainsize' clause modifier");496case OMPC_num_tasks:497switch (Type) {498case OMPC_NUMTASKS_unknown:499return "unknown";500#define OPENMP_NUMTASKS_MODIFIER(Name) \501case OMPC_NUMTASKS_##Name: \502return #Name;503#include "clang/Basic/OpenMPKinds.def"504}505llvm_unreachable("Invalid OpenMP 'num_tasks' clause modifier");506case OMPC_unknown:507case OMPC_threadprivate:508case OMPC_if:509case OMPC_final:510case OMPC_num_threads:511case OMPC_safelen:512case OMPC_simdlen:513case OMPC_sizes:514case OMPC_allocator:515case OMPC_allocate:516case OMPC_collapse:517case OMPC_private:518case OMPC_firstprivate:519case OMPC_shared:520case OMPC_task_reduction:521case OMPC_in_reduction:522case OMPC_aligned:523case OMPC_copyin:524case OMPC_copyprivate:525case OMPC_ordered:526case OMPC_nowait:527case OMPC_untied:528case OMPC_mergeable:529case OMPC_flush:530case OMPC_depobj:531case OMPC_read:532case OMPC_write:533case OMPC_capture:534case OMPC_compare:535case OMPC_seq_cst:536case OMPC_acq_rel:537case OMPC_acquire:538case OMPC_release:539case OMPC_relaxed:540case OMPC_threads:541case OMPC_simd:542case OMPC_num_teams:543case OMPC_thread_limit:544case OMPC_priority:545case OMPC_nogroup:546case OMPC_hint:547case OMPC_uniform:548case OMPC_use_device_ptr:549case OMPC_use_device_addr:550case OMPC_is_device_ptr:551case OMPC_has_device_addr:552case OMPC_unified_address:553case OMPC_unified_shared_memory:554case OMPC_reverse_offload:555case OMPC_dynamic_allocators:556case OMPC_match:557case OMPC_nontemporal:558case OMPC_destroy:559case OMPC_detach:560case OMPC_novariants:561case OMPC_nocontext:562case OMPC_inclusive:563case OMPC_exclusive:564case OMPC_uses_allocators:565case OMPC_affinity:566case OMPC_when:567case OMPC_append_args:568break;569default:570break;571}572llvm_unreachable("Invalid OpenMP simple clause kind");573}574575bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {576return getDirectiveAssociation(DKind) == Association::Loop;577}578579bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {580return DKind == OMPD_for || DKind == OMPD_for_simd ||581DKind == OMPD_sections || DKind == OMPD_section ||582DKind == OMPD_single || DKind == OMPD_parallel_for ||583DKind == OMPD_parallel_for_simd || DKind == OMPD_parallel_sections ||584DKind == OMPD_target_parallel_for ||585DKind == OMPD_distribute_parallel_for ||586DKind == OMPD_distribute_parallel_for_simd ||587DKind == OMPD_target_parallel_for_simd ||588DKind == OMPD_teams_distribute_parallel_for_simd ||589DKind == OMPD_teams_distribute_parallel_for ||590DKind == OMPD_target_teams_distribute_parallel_for ||591DKind == OMPD_target_teams_distribute_parallel_for_simd ||592DKind == OMPD_parallel_loop || DKind == OMPD_teams_loop ||593DKind == OMPD_target_parallel_loop || DKind == OMPD_target_teams_loop;594}595596bool clang::isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind) {597return DKind == OMPD_taskloop ||598llvm::is_contained(getLeafConstructs(DKind), OMPD_taskloop);599}600601bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {602if (DKind == OMPD_teams_loop)603return true;604return DKind == OMPD_parallel ||605llvm::is_contained(getLeafConstructs(DKind), OMPD_parallel);606}607608bool clang::isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind) {609return DKind == OMPD_target ||610llvm::is_contained(getLeafConstructs(DKind), OMPD_target);611}612613bool clang::isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind) {614return DKind == OMPD_target_data || DKind == OMPD_target_enter_data ||615DKind == OMPD_target_exit_data || DKind == OMPD_target_update;616}617618bool clang::isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind) {619if (DKind == OMPD_teams)620return true;621ArrayRef<Directive> Leaves = getLeafConstructs(DKind);622return !Leaves.empty() && Leaves.front() == OMPD_teams;623}624625bool clang::isOpenMPTeamsDirective(OpenMPDirectiveKind DKind) {626return DKind == OMPD_teams ||627llvm::is_contained(getLeafConstructs(DKind), OMPD_teams);628}629630bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {631// Avoid OMPD_declare_simd632if (getDirectiveAssociation(DKind) != Association::Loop)633return false;634// Formally, OMPD_end_do_simd also has a loop association, but635// it's a Fortran-specific directive.636637return DKind == OMPD_simd ||638llvm::is_contained(getLeafConstructs(DKind), OMPD_simd);639}640641bool clang::isOpenMPNestingDistributeDirective(OpenMPDirectiveKind Kind) {642if (Kind == OMPD_distribute)643return true;644ArrayRef<Directive> Leaves = getLeafConstructs(Kind);645return !Leaves.empty() && Leaves.front() == OMPD_distribute;646}647648bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {649return Kind == OMPD_distribute ||650llvm::is_contained(getLeafConstructs(Kind), OMPD_distribute);651}652653bool clang::isOpenMPGenericLoopDirective(OpenMPDirectiveKind Kind) {654if (Kind == OMPD_loop)655return true;656ArrayRef<Directive> Leaves = getLeafConstructs(Kind);657return !Leaves.empty() && Leaves.back() == OMPD_loop;658}659660bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {661return Kind == OMPC_private || Kind == OMPC_firstprivate ||662Kind == OMPC_lastprivate || Kind == OMPC_linear ||663Kind == OMPC_reduction || Kind == OMPC_task_reduction ||664Kind == OMPC_in_reduction; // TODO add next clauses like 'reduction'.665}666667bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {668return Kind == OMPC_threadprivate || Kind == OMPC_copyin;669}670671bool clang::isOpenMPTaskingDirective(OpenMPDirectiveKind Kind) {672return Kind == OMPD_task || isOpenMPTaskLoopDirective(Kind);673}674675bool clang::isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind) {676return Kind == OMPD_distribute_parallel_for ||677Kind == OMPD_distribute_parallel_for_simd ||678Kind == OMPD_teams_distribute_parallel_for_simd ||679Kind == OMPD_teams_distribute_parallel_for ||680Kind == OMPD_target_teams_distribute_parallel_for ||681Kind == OMPD_target_teams_distribute_parallel_for_simd ||682Kind == OMPD_teams_loop || Kind == OMPD_target_teams_loop;683}684685bool clang::isOpenMPLoopTransformationDirective(OpenMPDirectiveKind DKind) {686return DKind == OMPD_tile || DKind == OMPD_unroll || DKind == OMPD_reverse ||687DKind == OMPD_interchange;688}689690bool clang::isOpenMPCombinedParallelADirective(OpenMPDirectiveKind DKind) {691return DKind == OMPD_parallel_for || DKind == OMPD_parallel_for_simd ||692DKind == OMPD_parallel_master ||693DKind == OMPD_parallel_master_taskloop ||694DKind == OMPD_parallel_master_taskloop_simd ||695DKind == OMPD_parallel_sections;696}697698bool clang::needsTaskBasedThreadLimit(OpenMPDirectiveKind DKind) {699return DKind == OMPD_target || DKind == OMPD_target_parallel ||700DKind == OMPD_target_parallel_for ||701DKind == OMPD_target_parallel_for_simd || DKind == OMPD_target_simd ||702DKind == OMPD_target_parallel_loop;703}704705bool clang::isOpenMPExecutableDirective(OpenMPDirectiveKind DKind) {706if (DKind == OMPD_error)707return true;708Category Cat = getDirectiveCategory(DKind);709return Cat == Category::Executable || Cat == Category::Subsidiary;710}711712bool clang::isOpenMPCapturingDirective(OpenMPDirectiveKind DKind) {713if (isOpenMPExecutableDirective(DKind)) {714switch (DKind) {715case OMPD_atomic:716case OMPD_barrier:717case OMPD_cancel:718case OMPD_cancellation_point:719case OMPD_critical:720case OMPD_depobj:721case OMPD_error:722case OMPD_flush:723case OMPD_masked:724case OMPD_master:725case OMPD_section:726case OMPD_taskwait:727case OMPD_taskyield:728return false;729default:730return !isOpenMPLoopTransformationDirective(DKind);731}732}733// Non-executable directives.734switch (DKind) {735case OMPD_metadirective:736case OMPD_nothing:737return true;738default:739break;740}741return false;742}743744void clang::getOpenMPCaptureRegions(745SmallVectorImpl<OpenMPDirectiveKind> &CaptureRegions,746OpenMPDirectiveKind DKind) {747assert(unsigned(DKind) < llvm::omp::Directive_enumSize);748assert(isOpenMPCapturingDirective(DKind) && "Expecting capturing directive");749750auto GetRegionsForLeaf = [&](OpenMPDirectiveKind LKind) {751assert(isLeafConstruct(LKind) && "Epecting leaf directive");752// Whether a leaf would require OMPD_unknown if it occured on its own.753switch (LKind) {754case OMPD_metadirective:755CaptureRegions.push_back(OMPD_metadirective);756break;757case OMPD_nothing:758CaptureRegions.push_back(OMPD_nothing);759break;760case OMPD_parallel:761CaptureRegions.push_back(OMPD_parallel);762break;763case OMPD_target:764CaptureRegions.push_back(OMPD_task);765CaptureRegions.push_back(OMPD_target);766break;767case OMPD_task:768case OMPD_target_enter_data:769case OMPD_target_exit_data:770case OMPD_target_update:771CaptureRegions.push_back(OMPD_task);772break;773case OMPD_teams:774CaptureRegions.push_back(OMPD_teams);775break;776case OMPD_taskloop:777CaptureRegions.push_back(OMPD_taskloop);778break;779case OMPD_loop:780// TODO: 'loop' may require different capture regions depending on the781// bind clause or the parent directive when there is no bind clause.782// If any of the directives that push regions here are parents of 'loop',783// assume 'parallel'. Otherwise do nothing.784if (!CaptureRegions.empty() &&785!llvm::is_contained(CaptureRegions, OMPD_parallel))786CaptureRegions.push_back(OMPD_parallel);787else788return true;789break;790case OMPD_dispatch:791case OMPD_distribute:792case OMPD_for:793case OMPD_masked:794case OMPD_master:795case OMPD_ordered:796case OMPD_scope:797case OMPD_sections:798case OMPD_simd:799case OMPD_single:800case OMPD_target_data:801case OMPD_taskgroup:802// These directives (when standalone) use OMPD_unknown as the region,803// but when they're constituents of a compound directive, and other804// leafs from that directive have specific regions, then these directives805// add no additional regions.806return true;807default:808llvm::errs() << getOpenMPDirectiveName(LKind) << '\n';809llvm_unreachable("Unexpected directive");810}811return false;812};813814bool MayNeedUnknownRegion = false;815for (OpenMPDirectiveKind L : getLeafConstructsOrSelf(DKind))816MayNeedUnknownRegion |= GetRegionsForLeaf(L);817818// We need OMPD_unknown when no regions were added, and specific leaf819// constructs were present. Push a single OMPD_unknown as the capture820/// region.821if (CaptureRegions.empty() && MayNeedUnknownRegion)822CaptureRegions.push_back(OMPD_unknown);823824// OMPD_unknown is only expected as the only region. If other regions825// are present OMPD_unknown should not be present.826assert((CaptureRegions[0] == OMPD_unknown ||827!llvm::is_contained(CaptureRegions, OMPD_unknown)) &&828"Misplaced OMPD_unknown");829}830831bool clang::checkFailClauseParameter(OpenMPClauseKind FailClauseParameter) {832return FailClauseParameter == llvm::omp::OMPC_acquire ||833FailClauseParameter == llvm::omp::OMPC_relaxed ||834FailClauseParameter == llvm::omp::OMPC_seq_cst;835}836837838839