1 //===-- include/flang/Semantics/openmp-directive-sets.h ---------*- 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 #ifndef FORTRAN_SEMANTICS_OPENMP_DIRECTIVE_SETS_H_ 10 #define FORTRAN_SEMANTICS_OPENMP_DIRECTIVE_SETS_H_ 11 12 #include "flang/Common/enum-set.h" 13 #include "llvm/Frontend/OpenMP/OMPConstants.h" 14 15 using OmpDirectiveSet = Fortran::common::EnumSet<llvm::omp::Directive, 16 llvm::omp::Directive_enumSize>; 17 18 namespace llvm::omp { 19 //===----------------------------------------------------------------------===// 20 // Directive sets for single directives 21 //===----------------------------------------------------------------------===// 22 // - top<Directive>Set: The directive appears alone or as the first in a 23 // compound construct. 24 // - all<Directive>Set: All standalone or compound uses of the directive. 25 26 static const OmpDirectiveSet topDistributeSet{ 27 Directive::OMPD_distribute, 28 Directive::OMPD_distribute_parallel_do, 29 Directive::OMPD_distribute_parallel_do_simd, 30 Directive::OMPD_distribute_simd, 31 }; 32 33 static const OmpDirectiveSet allDistributeSet{ 34 OmpDirectiveSet{ 35 Directive::OMPD_target_teams_distribute, 36 Directive::OMPD_target_teams_distribute_parallel_do, 37 Directive::OMPD_target_teams_distribute_parallel_do_simd, 38 Directive::OMPD_target_teams_distribute_simd, 39 Directive::OMPD_teams_distribute, 40 Directive::OMPD_teams_distribute_parallel_do, 41 Directive::OMPD_teams_distribute_parallel_do_simd, 42 Directive::OMPD_teams_distribute_simd, 43 } | topDistributeSet, 44 }; 45 46 static const OmpDirectiveSet topDoSet{ 47 Directive::OMPD_do, 48 Directive::OMPD_do_simd, 49 }; 50 51 static const OmpDirectiveSet allDoSet{ 52 OmpDirectiveSet{ 53 Directive::OMPD_distribute_parallel_do, 54 Directive::OMPD_distribute_parallel_do_simd, 55 Directive::OMPD_parallel_do, 56 Directive::OMPD_parallel_do_simd, 57 Directive::OMPD_target_parallel_do, 58 Directive::OMPD_target_parallel_do_simd, 59 Directive::OMPD_target_teams_distribute_parallel_do, 60 Directive::OMPD_target_teams_distribute_parallel_do_simd, 61 Directive::OMPD_teams_distribute_parallel_do, 62 Directive::OMPD_teams_distribute_parallel_do_simd, 63 } | topDoSet, 64 }; 65 66 static const OmpDirectiveSet topLoopSet{ 67 Directive::OMPD_loop, 68 }; 69 70 static const OmpDirectiveSet allLoopSet{ 71 OmpDirectiveSet{ 72 Directive::OMPD_parallel_loop, 73 Directive::OMPD_target_parallel_loop, 74 Directive::OMPD_target_teams_loop, 75 Directive::OMPD_teams_loop, 76 } | topLoopSet, 77 }; 78 79 static const OmpDirectiveSet topParallelSet{ 80 Directive::OMPD_parallel, 81 Directive::OMPD_parallel_do, 82 Directive::OMPD_parallel_do_simd, 83 Directive::OMPD_parallel_loop, 84 Directive::OMPD_parallel_masked_taskloop, 85 Directive::OMPD_parallel_masked_taskloop_simd, 86 Directive::OMPD_parallel_master_taskloop, 87 Directive::OMPD_parallel_master_taskloop_simd, 88 Directive::OMPD_parallel_sections, 89 Directive::OMPD_parallel_workshare, 90 }; 91 92 static const OmpDirectiveSet allParallelSet{ 93 OmpDirectiveSet{ 94 Directive::OMPD_distribute_parallel_do, 95 Directive::OMPD_distribute_parallel_do_simd, 96 Directive::OMPD_target_parallel, 97 Directive::OMPD_target_parallel_do, 98 Directive::OMPD_target_parallel_do_simd, 99 Directive::OMPD_target_parallel_loop, 100 Directive::OMPD_target_teams_distribute_parallel_do, 101 Directive::OMPD_target_teams_distribute_parallel_do_simd, 102 Directive::OMPD_teams_distribute_parallel_do, 103 Directive::OMPD_teams_distribute_parallel_do_simd, 104 } | topParallelSet, 105 }; 106 107 static const OmpDirectiveSet topSimdSet{ 108 Directive::OMPD_simd, 109 }; 110 111 static const OmpDirectiveSet allSimdSet{ 112 OmpDirectiveSet{ 113 Directive::OMPD_distribute_parallel_do_simd, 114 Directive::OMPD_distribute_simd, 115 Directive::OMPD_do_simd, 116 Directive::OMPD_masked_taskloop_simd, 117 Directive::OMPD_master_taskloop_simd, 118 Directive::OMPD_parallel_do_simd, 119 Directive::OMPD_parallel_masked_taskloop_simd, 120 Directive::OMPD_parallel_master_taskloop_simd, 121 Directive::OMPD_target_parallel_do_simd, 122 Directive::OMPD_target_simd, 123 Directive::OMPD_target_teams_distribute_parallel_do_simd, 124 Directive::OMPD_target_teams_distribute_simd, 125 Directive::OMPD_taskloop_simd, 126 Directive::OMPD_teams_distribute_parallel_do_simd, 127 Directive::OMPD_teams_distribute_simd, 128 } | topSimdSet, 129 }; 130 131 static const OmpDirectiveSet topTargetSet{ 132 Directive::OMPD_target, 133 Directive::OMPD_target_parallel, 134 Directive::OMPD_target_parallel_do, 135 Directive::OMPD_target_parallel_do_simd, 136 Directive::OMPD_target_parallel_loop, 137 Directive::OMPD_target_simd, 138 Directive::OMPD_target_teams, 139 Directive::OMPD_target_teams_distribute, 140 Directive::OMPD_target_teams_distribute_parallel_do, 141 Directive::OMPD_target_teams_distribute_parallel_do_simd, 142 Directive::OMPD_target_teams_distribute_simd, 143 Directive::OMPD_target_teams_loop, 144 }; 145 146 static const OmpDirectiveSet allTargetSet{topTargetSet}; 147 148 static const OmpDirectiveSet topTaskloopSet{ 149 Directive::OMPD_taskloop, 150 Directive::OMPD_taskloop_simd, 151 }; 152 153 static const OmpDirectiveSet allTaskloopSet{ 154 OmpDirectiveSet{ 155 Directive::OMPD_masked_taskloop, 156 Directive::OMPD_masked_taskloop_simd, 157 Directive::OMPD_master_taskloop, 158 Directive::OMPD_master_taskloop_simd, 159 Directive::OMPD_parallel_masked_taskloop, 160 Directive::OMPD_parallel_masked_taskloop_simd, 161 Directive::OMPD_parallel_master_taskloop, 162 Directive::OMPD_parallel_master_taskloop_simd, 163 } | topTaskloopSet, 164 }; 165 166 static const OmpDirectiveSet topTeamsSet{ 167 Directive::OMPD_teams, 168 Directive::OMPD_teams_distribute, 169 Directive::OMPD_teams_distribute_parallel_do, 170 Directive::OMPD_teams_distribute_parallel_do_simd, 171 Directive::OMPD_teams_distribute_simd, 172 Directive::OMPD_teams_loop, 173 }; 174 175 static const OmpDirectiveSet allTeamsSet{ 176 OmpDirectiveSet{ 177 Directive::OMPD_target_teams, 178 Directive::OMPD_target_teams_distribute, 179 Directive::OMPD_target_teams_distribute_parallel_do, 180 Directive::OMPD_target_teams_distribute_parallel_do_simd, 181 Directive::OMPD_target_teams_distribute_simd, 182 Directive::OMPD_target_teams_loop, 183 } | topTeamsSet, 184 }; 185 186 //===----------------------------------------------------------------------===// 187 // Directive sets for groups of multiple directives 188 //===----------------------------------------------------------------------===// 189 190 // Composite constructs 191 static const OmpDirectiveSet allDistributeParallelDoSet{ 192 allDistributeSet & allParallelSet & allDoSet}; 193 static const OmpDirectiveSet allDistributeParallelDoSimdSet{ 194 allDistributeSet & allParallelSet & allDoSet & allSimdSet}; 195 static const OmpDirectiveSet allDistributeSimdSet{ 196 allDistributeSet & allSimdSet}; 197 static const OmpDirectiveSet allDoSimdSet{allDoSet & allSimdSet}; 198 static const OmpDirectiveSet allTaskloopSimdSet{allTaskloopSet & allSimdSet}; 199 200 static const OmpDirectiveSet compositeConstructSet{ 201 Directive::OMPD_distribute_parallel_do, 202 Directive::OMPD_distribute_parallel_do_simd, 203 Directive::OMPD_distribute_simd, 204 Directive::OMPD_do_simd, 205 Directive::OMPD_taskloop_simd, 206 }; 207 208 static const OmpDirectiveSet blockConstructSet{ 209 Directive::OMPD_masked, 210 Directive::OMPD_master, 211 Directive::OMPD_ordered, 212 Directive::OMPD_parallel, 213 Directive::OMPD_parallel_masked, 214 Directive::OMPD_parallel_master, 215 Directive::OMPD_parallel_workshare, 216 Directive::OMPD_scope, 217 Directive::OMPD_single, 218 Directive::OMPD_target, 219 Directive::OMPD_target_data, 220 Directive::OMPD_target_parallel, 221 Directive::OMPD_target_teams, 222 Directive::OMPD_task, 223 Directive::OMPD_taskgroup, 224 Directive::OMPD_teams, 225 Directive::OMPD_workshare, 226 }; 227 228 static const OmpDirectiveSet loopConstructSet{ 229 Directive::OMPD_distribute, 230 Directive::OMPD_distribute_parallel_do, 231 Directive::OMPD_distribute_parallel_do_simd, 232 Directive::OMPD_distribute_simd, 233 Directive::OMPD_do, 234 Directive::OMPD_do_simd, 235 Directive::OMPD_loop, 236 Directive::OMPD_masked_taskloop, 237 Directive::OMPD_masked_taskloop_simd, 238 Directive::OMPD_master_taskloop, 239 Directive::OMPD_master_taskloop_simd, 240 Directive::OMPD_parallel_do, 241 Directive::OMPD_parallel_do_simd, 242 Directive::OMPD_parallel_loop, 243 Directive::OMPD_parallel_masked_taskloop, 244 Directive::OMPD_parallel_masked_taskloop_simd, 245 Directive::OMPD_parallel_master_taskloop, 246 Directive::OMPD_parallel_master_taskloop_simd, 247 Directive::OMPD_simd, 248 Directive::OMPD_target_loop, 249 Directive::OMPD_target_parallel_do, 250 Directive::OMPD_target_parallel_do_simd, 251 Directive::OMPD_target_parallel_loop, 252 Directive::OMPD_target_simd, 253 Directive::OMPD_target_teams_distribute, 254 Directive::OMPD_target_teams_distribute_parallel_do, 255 Directive::OMPD_target_teams_distribute_parallel_do_simd, 256 Directive::OMPD_target_teams_distribute_simd, 257 Directive::OMPD_target_teams_loop, 258 Directive::OMPD_taskloop, 259 Directive::OMPD_taskloop_simd, 260 Directive::OMPD_teams_distribute, 261 Directive::OMPD_teams_distribute_parallel_do, 262 Directive::OMPD_teams_distribute_parallel_do_simd, 263 Directive::OMPD_teams_distribute_simd, 264 Directive::OMPD_teams_loop, 265 Directive::OMPD_tile, 266 Directive::OMPD_unroll, 267 }; 268 269 static const OmpDirectiveSet nonPartialVarSet{ 270 Directive::OMPD_allocate, 271 Directive::OMPD_allocators, 272 Directive::OMPD_threadprivate, 273 Directive::OMPD_declare_target, 274 }; 275 276 static const OmpDirectiveSet taskGeneratingSet{ 277 OmpDirectiveSet{ 278 Directive::OMPD_task, 279 } | allTaskloopSet, 280 }; 281 282 static const OmpDirectiveSet workShareSet{ 283 OmpDirectiveSet{ 284 Directive::OMPD_workshare, 285 Directive::OMPD_parallel_workshare, 286 Directive::OMPD_parallel_sections, 287 Directive::OMPD_scope, 288 Directive::OMPD_sections, 289 Directive::OMPD_single, 290 } | allDoSet, 291 }; 292 293 //===----------------------------------------------------------------------===// 294 // Directive sets for parent directives that do allow/not allow a construct 295 //===----------------------------------------------------------------------===// 296 297 static const OmpDirectiveSet scanParentAllowedSet{allDoSet | allSimdSet}; 298 299 //===----------------------------------------------------------------------===// 300 // Directive sets for allowed/not allowed nested directives 301 //===----------------------------------------------------------------------===// 302 303 static const OmpDirectiveSet nestedBarrierErrSet{ 304 OmpDirectiveSet{ 305 Directive::OMPD_atomic, 306 Directive::OMPD_critical, 307 Directive::OMPD_master, 308 Directive::OMPD_ordered, 309 } | taskGeneratingSet | 310 workShareSet, 311 }; 312 313 static const OmpDirectiveSet nestedCancelDoAllowedSet{ 314 Directive::OMPD_distribute_parallel_do, 315 Directive::OMPD_do, 316 Directive::OMPD_parallel_do, 317 Directive::OMPD_target_parallel_do, 318 Directive::OMPD_target_teams_distribute_parallel_do, 319 Directive::OMPD_teams_distribute_parallel_do, 320 }; 321 322 static const OmpDirectiveSet nestedCancelParallelAllowedSet{ 323 Directive::OMPD_parallel, 324 Directive::OMPD_target_parallel, 325 }; 326 327 static const OmpDirectiveSet nestedCancelSectionsAllowedSet{ 328 Directive::OMPD_parallel_sections, 329 Directive::OMPD_sections, 330 }; 331 332 static const OmpDirectiveSet nestedCancelTaskgroupAllowedSet{ 333 Directive::OMPD_task, 334 Directive::OMPD_taskloop, 335 }; 336 337 static const OmpDirectiveSet nestedMasterErrSet{ 338 OmpDirectiveSet{ 339 Directive::OMPD_atomic, 340 } | taskGeneratingSet | 341 workShareSet, 342 }; 343 344 static const OmpDirectiveSet nestedOrderedDoAllowedSet{ 345 Directive::OMPD_do, 346 Directive::OMPD_parallel_do, 347 Directive::OMPD_target_parallel_do, 348 }; 349 350 static const OmpDirectiveSet nestedOrderedErrSet{ 351 Directive::OMPD_atomic, 352 Directive::OMPD_critical, 353 Directive::OMPD_ordered, 354 Directive::OMPD_task, 355 Directive::OMPD_taskloop, 356 }; 357 358 static const OmpDirectiveSet nestedOrderedParallelErrSet{ 359 Directive::OMPD_parallel, 360 Directive::OMPD_parallel_sections, 361 Directive::OMPD_parallel_workshare, 362 Directive::OMPD_target_parallel, 363 }; 364 365 static const OmpDirectiveSet nestedReduceWorkshareAllowedSet{ 366 Directive::OMPD_do, 367 Directive::OMPD_do_simd, 368 Directive::OMPD_sections, 369 }; 370 371 static const OmpDirectiveSet nestedTeamsAllowedSet{ 372 Directive::OMPD_distribute, 373 Directive::OMPD_distribute_parallel_do, 374 Directive::OMPD_distribute_parallel_do_simd, 375 Directive::OMPD_distribute_simd, 376 Directive::OMPD_loop, 377 Directive::OMPD_parallel, 378 Directive::OMPD_parallel_do, 379 Directive::OMPD_parallel_do_simd, 380 Directive::OMPD_parallel_master, 381 Directive::OMPD_parallel_master_taskloop, 382 Directive::OMPD_parallel_master_taskloop_simd, 383 Directive::OMPD_parallel_sections, 384 Directive::OMPD_parallel_workshare, 385 }; 386 387 static const OmpDirectiveSet nestedWorkshareErrSet{ 388 OmpDirectiveSet{ 389 Directive::OMPD_atomic, 390 Directive::OMPD_critical, 391 Directive::OMPD_master, 392 Directive::OMPD_ordered, 393 Directive::OMPD_task, 394 Directive::OMPD_taskloop, 395 } | workShareSet, 396 }; 397 } // namespace llvm::omp 398 399 #endif // FORTRAN_SEMANTICS_OPENMP_DIRECTIVE_SETS_H_ 400