xref: /llvm-project/flang/include/flang/Semantics/openmp-directive-sets.h (revision e67e09a77ea1e4802c0f6bc0409c9f5e9d1fae9a)
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