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