xref: /llvm-project/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td (revision afcbcae668f1d8061974247f2828190173aef742)
1//=== OpenMPClauses.td - OpenMP dialect clause definitions -*- tablegen -*-===//
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// This file contains clause definitions for the OpenMP dialect.
10//
11// For each "Xyz" clause, there is an "OpenMP_XyzClauseSkip" class and an
12// "OpenMP_XyzClause" definition. The latter is an instantiation of the former
13// where all "skip" template parameters are set to `false` and should be the
14// preferred variant to used whenever possible when defining `OpenMP_Op`
15// instances.
16//
17//===----------------------------------------------------------------------===//
18
19#ifndef OPENMP_CLAUSES
20#define OPENMP_CLAUSES
21
22include "mlir/Dialect/OpenMP/OpenMPOpBase.td"
23include "mlir/IR/SymbolInterfaces.td"
24
25//===----------------------------------------------------------------------===//
26// V5.2: [5.11] `aligned` clause
27//===----------------------------------------------------------------------===//
28
29class OpenMP_AlignedClauseSkip<
30    bit traits = false, bit arguments = false, bit assemblyFormat = false,
31    bit description = false, bit extraClassDeclaration = false
32  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
33                    extraClassDeclaration> {
34  let arguments = (ins
35    Variadic<OpenMP_PointerLikeType>:$aligned_vars,
36    OptionalAttr<I64ArrayAttr>:$alignments
37  );
38
39  let optAssemblyFormat = [{
40    `aligned` `(` custom<AlignedClause>($aligned_vars, type($aligned_vars),
41                                        $alignments) `)`
42  }];
43
44  let description = [{
45    The `alignments` attribute additionally specifies alignment of each
46    corresponding aligned operand. Note that `aligned_vars` and `alignments`
47    must contain the same number of elements.
48  }];
49}
50
51def OpenMP_AlignedClause : OpenMP_AlignedClauseSkip<>;
52
53//===----------------------------------------------------------------------===//
54// V5.2: [6.6] `allocate` clause
55//===----------------------------------------------------------------------===//
56
57class OpenMP_AllocateClauseSkip<
58    bit traits = false, bit arguments = false, bit assemblyFormat = false,
59    bit description = false, bit extraClassDeclaration = false
60  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
61                    extraClassDeclaration> {
62  let arguments = (ins
63    Variadic<AnyType>:$allocate_vars,
64    Variadic<AnyType>:$allocator_vars
65  );
66
67  let extraClassDeclaration = [{
68    unsigned getNumAllocateVars() { return getAllocateVars().size(); }
69    unsigned getNumAllocatorsVars() { return getAllocatorVars().size(); }
70  }];
71
72  let optAssemblyFormat = [{
73    `allocate` `(`
74      custom<AllocateAndAllocator>($allocate_vars, type($allocate_vars),
75                                   $allocator_vars, type($allocator_vars)) `)`
76  }];
77
78  let description = [{
79    The `allocator_vars` and `allocate_vars` parameters are a variadic list of
80    values that specify the memory allocator to be used to obtain storage for
81    private values.
82  }];
83}
84
85def OpenMP_AllocateClause : OpenMP_AllocateClauseSkip<>;
86
87//===----------------------------------------------------------------------===//
88// LLVM OpenMP extension `ompx_bare` clause
89//===----------------------------------------------------------------------===//
90
91class OpenMP_BareClauseSkip<
92    bit traits = false, bit arguments = false, bit assemblyFormat = false,
93    bit description = false, bit extraClassDeclaration = false
94  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
95                    extraClassDeclaration> {
96  let arguments = (ins
97    UnitAttr:$bare
98  );
99
100  let optAssemblyFormat = [{
101    `ompx_bare` $bare
102  }];
103
104  let description = [{
105    `ompx_bare` allows `omp target teams` to be executed on a GPU with an
106    explicit number of teams and threads. This clause also allows the teams and
107    threads sizes to have up to 3 dimensions.
108  }];
109}
110
111def OpenMP_BareClause : OpenMP_BareClauseSkip<>;
112
113//===----------------------------------------------------------------------===//
114// V5.2: [16.1, 16.2] `cancel-directive-name` clause set
115//===----------------------------------------------------------------------===//
116
117class OpenMP_CancelDirectiveNameClauseSkip<
118    bit traits = false, bit arguments = false, bit assemblyFormat = false,
119    bit description = false, bit extraClassDeclaration = false
120  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
121                    extraClassDeclaration> {
122  let arguments = (ins
123    CancellationConstructTypeAttr:$cancel_directive
124  );
125
126  let reqAssemblyFormat = [{
127    `cancellation_construct_type` `(`
128      custom<ClauseAttr>($cancel_directive) `)`
129  }];
130
131  // TODO: Add description.
132}
133
134def OpenMP_CancelDirectiveNameClause : OpenMP_CancelDirectiveNameClauseSkip<>;
135
136//===----------------------------------------------------------------------===//
137// V5.2: [11.7.1] `bind` clause
138//===----------------------------------------------------------------------===//
139
140class OpenMP_BindClauseSkip<
141    bit traits = false, bit arguments = false, bit assemblyFormat = false,
142    bit description = false, bit extraClassDeclaration = false
143  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
144                    extraClassDeclaration> {
145  let arguments = (ins
146    OptionalAttr<BindKindAttr>:$bind_kind
147  );
148
149  let optAssemblyFormat = [{
150    `bind` `(` custom<ClauseAttr>($bind_kind) `)`
151  }];
152
153  let description = [{
154    The `bind` clause specifies the binding region of the construct on which it
155    appears.
156  }];
157}
158
159def OpenMP_BindClause : OpenMP_BindClauseSkip<>;
160
161//===----------------------------------------------------------------------===//
162// V5.2: [5.7.2] `copyprivate` clause
163//===----------------------------------------------------------------------===//
164
165class OpenMP_CopyprivateClauseSkip<
166    bit traits = false, bit arguments = false, bit assemblyFormat = false,
167    bit description = false, bit extraClassDeclaration = false
168  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
169                    extraClassDeclaration> {
170  let arguments = (ins
171    Variadic<OpenMP_PointerLikeType>:$copyprivate_vars,
172    OptionalAttr<SymbolRefArrayAttr>:$copyprivate_syms
173  );
174
175  let optAssemblyFormat = [{
176    `copyprivate` `(`
177      custom<Copyprivate>($copyprivate_vars, type($copyprivate_vars),
178                          $copyprivate_syms) `)`
179  }];
180
181  let description = [{
182    If `copyprivate` variables and functions are specified, then each thread
183    variable is updated with the variable value of the thread that executed
184    the single region, using the specified copy functions.
185  }];
186}
187
188def OpenMP_CopyprivateClause : OpenMP_CopyprivateClauseSkip<>;
189
190//===----------------------------------------------------------------------===//
191// V5.2: [15.2] `critical` `name` argument
192//===----------------------------------------------------------------------===//
193
194class OpenMP_CriticalNameClauseSkip<
195    bit traits = false, bit arguments = false, bit assemblyFormat = false,
196    bit description = false, bit extraClassDeclaration = false
197  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
198                    extraClassDeclaration> {
199  let traits = [
200    Symbol
201  ];
202
203  let arguments = (ins
204    SymbolNameAttr:$sym_name
205  );
206
207  let reqAssemblyFormat = "$sym_name";
208
209  let description = [{
210    The `sym_name` can be used in `omp.critical` constructs in the dialect.
211  }];
212}
213
214def OpenMP_CriticalNameClause : OpenMP_CriticalNameClauseSkip<>;
215
216//===----------------------------------------------------------------------===//
217// V5.2: [15.9.5] `depend` clause
218//===----------------------------------------------------------------------===//
219
220class OpenMP_DependClauseSkip<
221    bit traits = false, bit arguments = false, bit assemblyFormat = false,
222    bit description = false, bit extraClassDeclaration = false
223  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
224                    extraClassDeclaration> {
225  let arguments = (ins
226    OptionalAttr<TaskDependArrayAttr>:$depend_kinds,
227    Variadic<OpenMP_PointerLikeType>:$depend_vars
228  );
229
230  let optAssemblyFormat = [{
231    `depend` `(`
232      custom<DependVarList>($depend_vars, type($depend_vars), $depend_kinds) `)`
233  }];
234
235  let description = [{
236    The `depend_kinds` and `depend_vars` arguments are variadic lists of values
237    that specify the dependencies of this particular task in relation to other
238    tasks.
239  }];
240}
241
242def OpenMP_DependClause : OpenMP_DependClauseSkip<>;
243
244//===----------------------------------------------------------------------===//
245// V5.2: [13.2] `device` clause
246//===----------------------------------------------------------------------===//
247
248class OpenMP_DeviceClauseSkip<
249    bit traits = false, bit arguments = false, bit assemblyFormat = false,
250    bit description = false, bit extraClassDeclaration = false
251  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
252                    extraClassDeclaration> {
253  let arguments = (ins
254    Optional<AnyInteger>:$device
255  );
256
257  let optAssemblyFormat = [{
258    `device` `(` $device `:` type($device) `)`
259  }];
260
261  let description = [{
262    The optional `device` parameter specifies the device number for the target
263    region.
264  }];
265}
266
267def OpenMP_DeviceClause : OpenMP_DeviceClauseSkip<>;
268
269//===----------------------------------------------------------------------===//
270// V5.2: [11.6.1] `dist_schedule` clause
271//===----------------------------------------------------------------------===//
272
273class OpenMP_DistScheduleClauseSkip<
274    bit traits = false, bit arguments = false, bit assemblyFormat = false,
275    bit description = false, bit extraClassDeclaration = false
276  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
277                    extraClassDeclaration> {
278  let arguments = (ins
279    UnitAttr:$dist_schedule_static,
280    Optional<IntLikeType>:$dist_schedule_chunk_size
281  );
282
283  let optAssemblyFormat = [{
284    `dist_schedule_static` $dist_schedule_static
285    | `dist_schedule_chunk_size` `(` $dist_schedule_chunk_size `:`
286      type($dist_schedule_chunk_size) `)`
287  }];
288
289  let description = [{
290    The `dist_schedule_static` attribute specifies the schedule for this loop,
291    determining how the loop is distributed across the various teams. The
292    optional `dist_schedule_chunk_size` associated with this determines further
293    controls this distribution.
294  }];
295}
296
297def OpenMP_DistScheduleClause : OpenMP_DistScheduleClauseSkip<>;
298
299//===----------------------------------------------------------------------===//
300// V5.2: [15.9.6] `doacross` clause
301//===----------------------------------------------------------------------===//
302
303class OpenMP_DoacrossClauseSkip<
304    bit traits = false, bit arguments = false, bit assemblyFormat = false,
305    bit description = false, bit extraClassDeclaration = false
306  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
307                    extraClassDeclaration> {
308  let arguments = (ins
309    OptionalAttr<ClauseDependAttr>:$doacross_depend_type,
310    ConfinedAttr<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$doacross_num_loops,
311    Variadic<AnyType>:$doacross_depend_vars
312  );
313
314  let reqAssemblyFormat = [{
315    ( `depend_type` `` $doacross_depend_type^ )?
316    ( `depend_vec` `(` $doacross_depend_vars^ `:` type($doacross_depend_vars)
317                   `)` )?
318  }];
319
320  let description = [{
321    The `doacross_depend_type` attribute refers to either the DEPEND(SOURCE)
322    clause or the DEPEND(SINK: vec) clause.
323
324    The `doacross_num_loops` attribute specifies the number of loops in the
325    doacross nest.
326
327    The `doacross_depend_vars` is a variadic list of operands that specifies the
328    index of the loop iterator in the doacross nest for the DEPEND(SOURCE)
329    clause or the index of the element of "vec" for the DEPEND(SINK: vec)
330    clause. It contains the operands in multiple "vec" when multiple
331    DEPEND(SINK: vec) clauses exist in one ORDERED directive.
332  }];
333}
334
335def OpenMP_DoacrossClause : OpenMP_DoacrossClauseSkip<>;
336
337//===----------------------------------------------------------------------===//
338// V5.2: [5.4.7] `exclusive` clause
339//===----------------------------------------------------------------------===//
340
341class OpenMP_ExclusiveClauseSkip<
342    bit traits = false, bit arguments = false, bit assemblyFormat = false,
343    bit description = false, bit extraClassDeclaration = false
344  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
345                    extraClassDeclaration> {
346  let arguments = (ins
347    Variadic<AnyType>:$exclusive_vars
348  );
349
350  let optAssemblyFormat = [{
351    `exclusive` `(` $exclusive_vars `:` type($exclusive_vars) `)`
352  }];
353
354  let extraClassDeclaration = [{
355    bool hasExclusiveVars() {
356      return !getExclusiveVars().empty();
357    }
358  }];
359
360  let description = [{
361    The exclusive clause is used on a separating directive that separates a
362    structured block into two structured block sequences. If it
363    is specified, the input phase excludes the preceding structured block
364    sequence and instead includes the following structured block sequence,
365    while the scan phase includes the preceding structured block sequence.
366
367    The `exclusive_vars` is a variadic list of operands that specifies the
368    scan-reduction accumulator symbols.
369  }];
370}
371
372def OpenMP_ExclusiveClause : OpenMP_ExclusiveClauseSkip<>;
373
374//===----------------------------------------------------------------------===//
375// V5.2: [10.5.1] `filter` clause
376//===----------------------------------------------------------------------===//
377
378class OpenMP_FilterClauseSkip<
379    bit traits = false, bit arguments = false, bit assemblyFormat = false,
380    bit description = false, bit extraClassDeclaration = false
381  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
382                    extraClassDeclaration> {
383  let arguments = (ins
384    Optional<IntLikeType>:$filtered_thread_id
385  );
386
387  let optAssemblyFormat = [{
388    `filter` `(` $filtered_thread_id `:` type($filtered_thread_id) `)`
389  }];
390
391  let description = [{
392    If `filter` is specified, the masked construct masks the execution of
393    the region to only the thread id filtered. Other threads executing the
394    parallel region are not expected to execute the region specified within
395    the `masked` directive. If `filter` is not specified, master thread is
396    expected to execute the region enclosed within `masked` directive.
397  }];
398}
399
400def OpenMP_FilterClause : OpenMP_FilterClauseSkip<>;
401
402//===----------------------------------------------------------------------===//
403// V5.2: [12.3] `final` clause
404//===----------------------------------------------------------------------===//
405
406class OpenMP_FinalClauseSkip<
407    bit traits = false, bit arguments = false, bit assemblyFormat = false,
408    bit description = false, bit extraClassDeclaration = false
409  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
410                    extraClassDeclaration> {
411  let arguments = (ins
412    Optional<I1>:$final
413  );
414
415  let optAssemblyFormat = [{
416    `final` `(` $final `)`
417  }];
418
419  let description = [{
420    When a `final` clause is present and the `final` clause expression evaluates
421    to `true`, the generated tasks will be final tasks. All task constructs
422    encountered during execution of a final task will generate final and
423    included tasks. The use of a variable in a `final` clause expression causes
424    an implicit reference to the variable in all enclosing constructs.
425  }];
426}
427
428def OpenMP_FinalClause : OpenMP_FinalClauseSkip<>;
429
430//===----------------------------------------------------------------------===//
431// V5.2: [12.6.1] `grainsize` clause
432//===----------------------------------------------------------------------===//
433
434class OpenMP_GrainsizeClauseSkip<
435    bit traits = false, bit arguments = false, bit assemblyFormat = false,
436    bit description = false, bit extraClassDeclaration = false
437  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
438                    extraClassDeclaration> {
439  let arguments = (ins
440    Optional<IntLikeType>:$grainsize
441  );
442
443  let optAssemblyFormat = [{
444    `grainsize` `(` $grainsize `:` type($grainsize) `)`
445  }];
446
447  let description = [{
448    If a `grainsize` clause is present, the number of logical loop iterations
449    assigned to each generated task is greater than or equal to the minimum of
450    the value of the grain-size expression and the number of logical loop
451    iterations, but less than two times the value of the grain-size expression.
452  }];
453}
454
455def OpenMP_GrainsizeClause : OpenMP_GrainsizeClauseSkip<>;
456
457//===----------------------------------------------------------------------===//
458// V5.2: [5.4.9] `has_device_addr` clause
459//===----------------------------------------------------------------------===//
460
461class OpenMP_HasDeviceAddrClauseSkip<
462    bit traits = false, bit arguments = false, bit assemblyFormat = false,
463    bit description = false, bit extraClassDeclaration = false
464  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
465                    extraClassDeclaration> {
466  let arguments = (ins
467    Variadic<OpenMP_PointerLikeType>:$has_device_addr_vars
468  );
469
470  let optAssemblyFormat = [{
471    `has_device_addr` `(` $has_device_addr_vars `:` type($has_device_addr_vars)
472                      `)`
473  }];
474
475  let description = [{
476    The optional `has_device_addr_vars` indicates that list items already have
477    device addresses, so they may be directly accessed from the target device.
478    This includes array sections.
479  }];
480}
481
482def OpenMP_HasDeviceAddrClause : OpenMP_HasDeviceAddrClauseSkip<>;
483
484//===----------------------------------------------------------------------===//
485// V5.2: [5.4.7] `inclusive` clause
486//===----------------------------------------------------------------------===//
487
488class OpenMP_InclusiveClauseSkip<
489    bit traits = false, bit arguments = false, bit assemblyFormat = false,
490    bit description = false, bit extraClassDeclaration = false
491  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
492                    extraClassDeclaration> {
493  let arguments = (ins
494    Variadic<AnyType>:$inclusive_vars
495  );
496
497  let optAssemblyFormat = [{
498    `inclusive` `(` $inclusive_vars `:` type($inclusive_vars) `)`
499  }];
500
501  let extraClassDeclaration = [{
502    bool hasInclusiveVars() {
503      return !getInclusiveVars().empty();
504    }
505  }];
506
507  let description = [{
508    The inclusive clause is used on a separating directive that separates a
509    structured block into two structured block sequences. If it is specified,
510    the input phase includes the preceding structured block sequence and the
511    scan phase includes the following structured block sequence.
512
513    The `inclusive_vars` is a variadic list of operands that specifies the
514    scan-reduction accumulator symbols.
515  }];
516}
517
518def OpenMP_InclusiveClause : OpenMP_InclusiveClauseSkip<>;
519
520
521//===----------------------------------------------------------------------===//
522// V5.2: [15.1.2] `hint` clause
523//===----------------------------------------------------------------------===//
524
525class OpenMP_HintClauseSkip<
526    bit traits = false, bit arguments = false, bit assemblyFormat = false,
527    bit description = false, bit extraClassDeclaration = false
528  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
529                    extraClassDeclaration> {
530  let arguments = (ins
531    DefaultValuedOptionalAttr<I64Attr, "0">:$hint
532  );
533
534  let optAssemblyFormat = [{
535    `hint` `(` custom<SynchronizationHint>($hint) `)`
536  }];
537
538  let description = [{
539    `hint` is the value of hint (as specified in the hint clause). It is a
540    compile time constant. As the name suggests, this is just a hint for
541    optimization.
542  }];
543}
544
545def OpenMP_HintClause : OpenMP_HintClauseSkip<>;
546
547//===----------------------------------------------------------------------===//
548// Not in the spec: Clause-like structure to hold host-evaluated values.
549//===----------------------------------------------------------------------===//
550
551class OpenMP_HostEvalClauseSkip<
552    bit traits = false, bit arguments = false, bit assemblyFormat = false,
553    bit description = false, bit extraClassDeclaration = false
554  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
555                    extraClassDeclaration> {
556  let traits = [
557    BlockArgOpenMPOpInterface, IsolatedFromAbove
558  ];
559
560  let arguments = (ins
561    Variadic<AnyType>:$host_eval_vars
562  );
563
564  let extraClassDeclaration = [{
565    unsigned numHostEvalBlockArgs() {
566      return getHostEvalVars().size();
567    }
568  }];
569
570  let description = [{
571    The optional `host_eval_vars` holds values defined outside of the region of
572    the `IsolatedFromAbove` operation for which a corresponding entry block
573    argument is defined. The only legal uses for these captured values are the
574    following:
575      - `num_teams` or `thread_limit` clause of an immediately nested
576      `omp.teams` operation.
577      - If the operation is the top-level `omp.target` of a target SPMD kernel:
578        - `num_threads` clause of the nested `omp.parallel` operation.
579        - Bounds and steps of the nested `omp.loop_nest` operation.
580  }];
581}
582
583def OpenMP_HostEvalClause : OpenMP_HostEvalClauseSkip<>;
584
585//===----------------------------------------------------------------------===//
586// V5.2: [3.4] `if` clause
587//===----------------------------------------------------------------------===//
588
589class OpenMP_IfClauseSkip<
590    bit traits = false, bit arguments = false, bit assemblyFormat = false,
591    bit description = false, bit extraClassDeclaration = false
592  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
593                    extraClassDeclaration> {
594  let arguments = (ins
595    Optional<I1>:$if_expr
596  );
597
598  let optAssemblyFormat = [{
599    `if` `(` $if_expr `)`
600  }];
601
602  // Description varies depending on the operation.
603}
604
605def OpenMP_IfClause : OpenMP_IfClauseSkip<>;
606
607//===----------------------------------------------------------------------===//
608// V5.2: [5.5.10] `in_reduction` clause
609//===----------------------------------------------------------------------===//
610
611class OpenMP_InReductionClauseSkip<
612    bit traits = false, bit arguments = false, bit assemblyFormat = false,
613    bit description = false, bit extraClassDeclaration = false
614  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
615                    extraClassDeclaration> {
616  let traits = [
617    BlockArgOpenMPOpInterface, ReductionClauseInterface
618  ];
619
620  let arguments = (ins
621    Variadic<OpenMP_PointerLikeType>:$in_reduction_vars,
622    OptionalAttr<DenseBoolArrayAttr>:$in_reduction_byref,
623    OptionalAttr<SymbolRefArrayAttr>:$in_reduction_syms
624  );
625
626  let extraClassDeclaration = [{
627    /// Returns the reduction variables.
628    SmallVector<Value> getReductionVars() {
629      return SmallVector<Value>(getInReductionVars().begin(),
630                                getInReductionVars().end());
631    }
632
633    unsigned numInReductionBlockArgs() { return getInReductionVars().size(); }
634  }];
635
636  // Description varies depending on the operation. Assembly format not defined
637  // because this clause must be processed together with the first region of the
638  // operation, as it defines entry block arguments.
639}
640
641def OpenMP_InReductionClause : OpenMP_InReductionClauseSkip<>;
642
643//===----------------------------------------------------------------------===//
644// V5.2: [5.4.7] `is_device_ptr` clause
645//===----------------------------------------------------------------------===//
646
647class OpenMP_IsDevicePtrClauseSkip<
648    bit traits = false, bit arguments = false, bit assemblyFormat = false,
649    bit description = false, bit extraClassDeclaration = false
650  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
651                    extraClassDeclaration> {
652  let arguments = (ins
653    Variadic<OpenMP_PointerLikeType>:$is_device_ptr_vars
654  );
655
656  let optAssemblyFormat = [{
657    `is_device_ptr` `(` $is_device_ptr_vars `:` type($is_device_ptr_vars) `)`
658  }];
659
660  let description = [{
661    The optional `is_device_ptr_vars` indicates list items are device pointers.
662  }];
663}
664
665def OpenMP_IsDevicePtrClause : OpenMP_IsDevicePtrClauseSkip<>;
666
667//===----------------------------------------------------------------------===//
668// V5.2: [5.4.6] `linear` clause
669//===----------------------------------------------------------------------===//
670
671class OpenMP_LinearClauseSkip<
672    bit traits = false, bit arguments = false, bit assemblyFormat = false,
673    bit description = false, bit extraClassDeclaration = false
674  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
675                    extraClassDeclaration> {
676  let arguments = (ins
677    Variadic<AnyType>:$linear_vars,
678    Variadic<I32>:$linear_step_vars
679  );
680
681  let optAssemblyFormat = [{
682    `linear` `(`
683      custom<LinearClause>($linear_vars, type($linear_vars),
684                           $linear_step_vars) `)`
685  }];
686
687  let description = [{
688    The `linear_step_vars` operand additionally specifies the step for each
689    associated linear operand. Note that the `linear_vars` and
690    `linear_step_vars` variadic lists should contain the same number of
691    elements.
692  }];
693}
694
695def OpenMP_LinearClause : OpenMP_LinearClauseSkip<>;
696
697//===----------------------------------------------------------------------===//
698// Not in the spec: Clause-like structure to hold loop related information.
699//===----------------------------------------------------------------------===//
700
701class OpenMP_LoopRelatedClauseSkip<
702    bit traits = false, bit arguments = false, bit assemblyFormat = false,
703    bit description = false, bit extraClassDeclaration = false
704  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
705                    extraClassDeclaration> {
706  let traits = [
707    AllTypesMatch<
708      ["loop_lower_bounds", "loop_upper_bounds", "loop_steps"]>
709  ];
710
711  let arguments = (ins
712    Variadic<IntLikeType>:$loop_lower_bounds,
713    Variadic<IntLikeType>:$loop_upper_bounds,
714    Variadic<IntLikeType>:$loop_steps,
715    UnitAttr:$loop_inclusive
716  );
717
718  let extraClassDeclaration = [{
719    /// Returns the number of loops in the loop nest.
720    unsigned getNumLoops() { return getLoopLowerBounds().size(); }
721  }];
722
723  // Description and formatting integrated in the `omp.loop_nest` operation,
724  // which is the only one currently accepting this clause.
725}
726
727def OpenMP_LoopRelatedClause : OpenMP_LoopRelatedClauseSkip<>;
728
729//===----------------------------------------------------------------------===//
730// V5.2: [5.8.3] `map` clause
731//===----------------------------------------------------------------------===//
732
733class OpenMP_MapClauseSkip<
734    bit traits = false, bit arguments = false, bit assemblyFormat = false,
735    bit description = false, bit extraClassDeclaration = false
736  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
737                    extraClassDeclaration> {
738  let traits = [
739    // Not adding the BlockArgOpenMPOpInterface here because omp.target is the
740    // only operation defining block arguments for `map` clauses.
741    MapClauseOwningOpInterface
742  ];
743
744  let arguments = (ins
745    Variadic<OpenMP_PointerLikeType>:$map_vars
746  );
747
748  let optAssemblyFormat = [{
749    `map_entries` `(` $map_vars `:` type($map_vars) `)`
750  }];
751
752  let description = [{
753    The optional `map_vars` maps data from the current task's data environment
754    to the device data environment.
755  }];
756}
757
758def OpenMP_MapClause : OpenMP_MapClauseSkip<>;
759
760//===----------------------------------------------------------------------===//
761// V5.2: [15.8.1] `memory-order` clause set
762//===----------------------------------------------------------------------===//
763
764class OpenMP_MemoryOrderClauseSkip<
765    bit traits = false, bit arguments = false, bit assemblyFormat = false,
766    bit description = false, bit extraClassDeclaration = false
767  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
768                    extraClassDeclaration> {
769  let arguments = (ins
770    OptionalAttr<MemoryOrderKindAttr>:$memory_order
771  );
772
773  let optAssemblyFormat = [{
774    `memory_order` `(` custom<ClauseAttr>($memory_order) `)`
775  }];
776
777  let description = [{
778    `memory_order` indicates the memory ordering behavior of the construct. It
779    can be one of `seq_cst`, `acq_rel`, `release`, `acquire` or `relaxed`.
780  }];
781}
782
783def OpenMP_MemoryOrderClause : OpenMP_MemoryOrderClauseSkip<>;
784
785//===----------------------------------------------------------------------===//
786// V5.2: [12.2] `mergeable` clause
787//===----------------------------------------------------------------------===//
788
789class OpenMP_MergeableClauseSkip<
790    bit traits = false, bit arguments = false, bit assemblyFormat = false,
791    bit description = false, bit extraClassDeclaration = false
792  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
793                    extraClassDeclaration> {
794  let arguments = (ins
795    UnitAttr:$mergeable
796  );
797
798  let optAssemblyFormat = [{
799    `mergeable` $mergeable
800  }];
801
802  let description = [{
803    When the `mergeable` clause is present, the tasks generated by the construct
804    are "mergeable tasks".
805  }];
806}
807
808def OpenMP_MergeableClause : OpenMP_MergeableClauseSkip<>;
809
810//===----------------------------------------------------------------------===//
811// V5.2: [15.7] `nogroup` clause
812//===----------------------------------------------------------------------===//
813
814class OpenMP_NogroupClauseSkip<
815    bit traits = false, bit arguments = false, bit assemblyFormat = false,
816    bit description = false, bit extraClassDeclaration = false
817  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
818                    extraClassDeclaration> {
819  let arguments = (ins
820    UnitAttr:$nogroup
821  );
822
823  let optAssemblyFormat = [{
824    `nogroup` $nogroup
825  }];
826
827  let description = [{
828    By default, the taskloop construct executes as if it was enclosed in a
829    taskgroup construct with no statements or directives outside of the taskloop
830    construct. Thus, the taskloop construct creates an implicit taskgroup
831    region. If the `nogroup` clause is present, no implicit taskgroup region is
832    created.
833  }];
834}
835
836def OpenMP_NogroupClause : OpenMP_NogroupClauseSkip<>;
837
838//===----------------------------------------------------------------------===//
839// V5.2: [10.4.1] `nontemporal` clause
840//===----------------------------------------------------------------------===//
841
842class OpenMP_NontemporalClauseSkip<
843    bit traits = false, bit arguments = false, bit assemblyFormat = false,
844    bit description = false, bit extraClassDeclaration = false
845  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
846                    extraClassDeclaration> {
847  let arguments = (ins
848    Variadic<OpenMP_PointerLikeType>:$nontemporal_vars
849  );
850
851  let optAssemblyFormat = [{
852    `nontemporal` `(`  $nontemporal_vars `:` type($nontemporal_vars) `)`
853  }];
854
855  let description = [{
856    The optional `nontemporal` attribute specifies variables which have low
857    temporal locality across the iterations where they are accessed.
858  }];
859}
860
861def OpenMP_NontemporalClause : OpenMP_NontemporalClauseSkip<>;
862
863//===----------------------------------------------------------------------===//
864// V5.2: [15.6] `nowait` clause
865//===----------------------------------------------------------------------===//
866
867class OpenMP_NowaitClauseSkip<
868    bit traits = false, bit arguments = false, bit assemblyFormat = false,
869    bit description = false, bit extraClassDeclaration = false
870  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
871                    extraClassDeclaration> {
872  let arguments = (ins
873    UnitAttr:$nowait
874  );
875
876  let optAssemblyFormat = [{
877    `nowait` $nowait
878  }];
879
880  let description = [{
881    The optional `nowait` attribute, when present, eliminates the implicit
882    barrier at the end of the construct, so the parent operation can make
883    progress even if the child operation has not completed yet.
884  }];
885}
886
887def OpenMP_NowaitClause : OpenMP_NowaitClauseSkip<>;
888
889//===----------------------------------------------------------------------===//
890// V5.2: [12.6.2] `num_tasks` clause
891//===----------------------------------------------------------------------===//
892
893class OpenMP_NumTasksClauseSkip<
894    bit traits = false, bit arguments = false, bit assemblyFormat = false,
895    bit description = false, bit extraClassDeclaration = false
896  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
897                    extraClassDeclaration> {
898  let arguments = (ins
899    Optional<IntLikeType>:$num_tasks
900  );
901
902  let optAssemblyFormat = [{
903    `num_tasks` `(` $num_tasks `:` type($num_tasks) `)`
904  }];
905
906  let description = [{
907    If `num_tasks` is specified, the taskloop construct creates as many tasks as
908    the minimum of the num-tasks expression and the number of logical loop
909    iterations. Each task must have at least one logical loop iteration.
910  }];
911}
912
913def OpenMP_NumTasksClause : OpenMP_NumTasksClauseSkip<>;
914
915//===----------------------------------------------------------------------===//
916// V5.2: [10.2.1] `num_teams` clause
917//===----------------------------------------------------------------------===//
918
919class OpenMP_NumTeamsClauseSkip<
920    bit traits = false, bit arguments = false, bit assemblyFormat = false,
921    bit description = false, bit extraClassDeclaration = false
922  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
923                    extraClassDeclaration> {
924  let arguments = (ins
925    Optional<AnyInteger>:$num_teams_lower,
926    Optional<AnyInteger>:$num_teams_upper
927  );
928
929  let optAssemblyFormat = [{
930    `num_teams` `(` ( $num_teams_lower^ `:` type($num_teams_lower) )? `to`
931                      $num_teams_upper `:` type($num_teams_upper) `)`
932  }];
933
934  let description = [{
935    The optional `num_teams_upper` and `num_teams_lower` arguments specify the
936    limit on the number of teams to be created. If only the upper bound is
937    specified, it acts as if the lower bound was set to the same value. It is
938    not allowed to set `num_teams_lower` if `num_teams_upper` is not specified.
939    They define a closed range, where both the lower and upper bounds are
940    included.
941  }];
942}
943
944def OpenMP_NumTeamsClause : OpenMP_NumTeamsClauseSkip<>;
945
946//===----------------------------------------------------------------------===//
947// V5.2: [10.1.2] `num_threads` clause
948//===----------------------------------------------------------------------===//
949
950class OpenMP_NumThreadsClauseSkip<
951    bit traits = false, bit arguments = false, bit assemblyFormat = false,
952    bit description = false, bit extraClassDeclaration = false
953  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
954                    extraClassDeclaration> {
955  let arguments = (ins
956    Optional<IntLikeType>:$num_threads
957  );
958
959  let optAssemblyFormat = [{
960    `num_threads` `(` $num_threads `:` type($num_threads) `)`
961  }];
962
963  let description = [{
964    The optional `num_threads` parameter specifies the number of threads which
965    should be used to execute the parallel region.
966  }];
967}
968
969def OpenMP_NumThreadsClause : OpenMP_NumThreadsClauseSkip<>;
970
971//===----------------------------------------------------------------------===//
972// V5.2: [10.3] `order` clause
973//===----------------------------------------------------------------------===//
974
975class OpenMP_OrderClauseSkip<
976    bit traits = false, bit arguments = false, bit assemblyFormat = false,
977    bit description = false, bit extraClassDeclaration = false
978  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
979                    extraClassDeclaration> {
980  let arguments = (ins
981    OptionalAttr<OrderKindAttr>:$order,
982    OptionalAttr<OrderModifierAttr>:$order_mod
983  );
984
985  let optAssemblyFormat = [{
986    `order` `(` custom<OrderClause>($order, $order_mod) `)`
987  }];
988
989  let description = [{
990    The optional `order` attribute specifies which order the iterations of the
991    associated loops are executed in. Currently the only option for this
992    attribute is "concurrent".
993  }];
994}
995
996def OpenMP_OrderClause : OpenMP_OrderClauseSkip<>;
997
998//===----------------------------------------------------------------------===//
999// V5.2: [4.4.4] `ordered` clause
1000//===----------------------------------------------------------------------===//
1001
1002class OpenMP_OrderedClauseSkip<
1003    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1004    bit description = false, bit extraClassDeclaration = false
1005  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1006                    extraClassDeclaration> {
1007  let arguments = (ins
1008    ConfinedAttr<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$ordered
1009  );
1010
1011  let optAssemblyFormat = [{
1012    `ordered` `(` $ordered `)`
1013  }];
1014
1015  let description = [{
1016    The optional `ordered` attribute specifies how many loops are associated
1017    with the worksharing-loop construct. The value of zero refers to the ordered
1018    clause specified without parameter.
1019  }];
1020}
1021
1022def OpenMP_OrderedClause : OpenMP_OrderedClauseSkip<>;
1023
1024//===----------------------------------------------------------------------===//
1025// V5.2: [15.10.3] `parallelization-level` clause set
1026//===----------------------------------------------------------------------===//
1027
1028class OpenMP_ParallelizationLevelClauseSkip<
1029    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1030    bit description = false, bit extraClassDeclaration = false
1031  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1032                    extraClassDeclaration> {
1033  let arguments = (ins
1034    UnitAttr:$par_level_simd
1035  );
1036
1037  let optAssemblyFormat = [{
1038    `par_level_simd` $par_level_simd
1039  }];
1040
1041  let description = [{
1042    The `par_level_simd` attribute corresponds to the simd clause specified. If
1043    it is not present, it behaves as if the threads clause is specified or no
1044    clause is specified.
1045  }];
1046}
1047
1048def OpenMP_ParallelizationLevelClause : OpenMP_ParallelizationLevelClauseSkip<>;
1049
1050//===----------------------------------------------------------------------===//
1051// OpenMPV5.2: [12.5.2] `detach` clause
1052//===----------------------------------------------------------------------===//
1053
1054class OpenMP_DetachClauseSkip<
1055    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1056    bit description = false, bit extraClassDeclaration = false>
1057    : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1058                    extraClassDeclaration> {
1059
1060  let traits = [BlockArgOpenMPOpInterface];
1061
1062  let arguments = (ins Optional<OpenMP_PointerLikeType>:$event_handle);
1063
1064  let optAssemblyFormat = [{
1065		`detach` `(` $event_handle `:` type($event_handle) `)`
1066	}];
1067
1068  let description = [{
1069		The detach clause specifies that the task generated by the construct on which it appears is a
1070	detachable task. A new allow-completion event is created and connected to the completion of the
1071	associated task region. The original event-handle is updated to represent that allow-completion
1072	event before the task data environment is created.
1073	}];
1074}
1075
1076def OpenMP_DetachClause : OpenMP_DetachClauseSkip<>;
1077
1078//===----------------------------------------------------------------------===//
1079// V5.2: [12.4] `priority` clause
1080//===----------------------------------------------------------------------===//
1081
1082class OpenMP_PriorityClauseSkip<
1083    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1084    bit description = false, bit extraClassDeclaration = false
1085  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1086                    extraClassDeclaration> {
1087  let arguments = (ins
1088    Optional<AnyInteger>:$priority
1089  );
1090
1091  let optAssemblyFormat = [{
1092    `priority` `(` $priority `:` type($priority) `)`
1093  }];
1094
1095  let description = [{
1096    The `priority` clause is a hint for the priority of the generated tasks.
1097    The `priority` is a non-negative integer expression that provides a hint for
1098    task execution order. Among all tasks ready to be executed, higher priority
1099    tasks (those with a higher numerical value in the priority clause
1100    expression) are recommended to execute before lower priority ones. The
1101    default priority-value when no priority clause is specified should be
1102    assumed to be zero (the lowest priority).
1103  }];
1104}
1105
1106def OpenMP_PriorityClause : OpenMP_PriorityClauseSkip<>;
1107
1108//===----------------------------------------------------------------------===//
1109// V5.2: [5.4.3, 5.4.4, 5.4.5] `private`, `firstprivate`, `lastprivate` clauses
1110//===----------------------------------------------------------------------===//
1111
1112class OpenMP_PrivateClauseSkip<
1113    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1114    bit description = false, bit extraClassDeclaration = false
1115  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1116                    extraClassDeclaration> {
1117  let traits = [
1118    BlockArgOpenMPOpInterface
1119  ];
1120
1121  let arguments = (ins
1122    Variadic<AnyType>:$private_vars,
1123    OptionalAttr<SymbolRefArrayAttr>:$private_syms
1124  );
1125
1126  let extraClassDeclaration = [{
1127    unsigned numPrivateBlockArgs() { return getPrivateVars().size(); }
1128  }];
1129
1130  // TODO: Add description.
1131  // Assembly format not defined because this clause must be processed together
1132  // with the first region of the operation, as it defines entry block
1133  // arguments.
1134}
1135
1136def OpenMP_PrivateClause : OpenMP_PrivateClauseSkip<>;
1137
1138//===----------------------------------------------------------------------===//
1139// V5.2: [10.1.4] `proc_bind` clause
1140//===----------------------------------------------------------------------===//
1141
1142class OpenMP_ProcBindClauseSkip<
1143    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1144    bit description = false, bit extraClassDeclaration = false
1145  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1146                    extraClassDeclaration> {
1147  let arguments = (ins
1148    OptionalAttr<ProcBindKindAttr>:$proc_bind_kind
1149  );
1150
1151  let optAssemblyFormat = [{
1152    `proc_bind` `(` custom<ClauseAttr>($proc_bind_kind) `)`
1153  }];
1154
1155  let description = [{
1156    The optional `proc_bind_kind` attribute controls the thread affinity for the
1157    execution of the parallel region.
1158  }];
1159}
1160
1161def OpenMP_ProcBindClause : OpenMP_ProcBindClauseSkip<>;
1162
1163//===----------------------------------------------------------------------===//
1164// V5.2: [5.5.8] `reduction` clause
1165//===----------------------------------------------------------------------===//
1166
1167class OpenMP_ReductionClauseSkip<
1168    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1169    bit description = false, bit extraClassDeclaration = false
1170  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1171                    extraClassDeclaration> {
1172  let traits = [
1173    BlockArgOpenMPOpInterface, ReductionClauseInterface
1174  ];
1175
1176  let arguments = (ins
1177    OptionalAttr<ReductionModifierAttr>:$reduction_mod,
1178    Variadic<OpenMP_PointerLikeType>:$reduction_vars,
1179    OptionalAttr<DenseBoolArrayAttr>:$reduction_byref,
1180    OptionalAttr<SymbolRefArrayAttr>:$reduction_syms
1181  );
1182
1183  let extraClassDeclaration = [{
1184    /// Returns the number of reduction variables.
1185    unsigned getNumReductionVars() { return getReductionVars().size(); }
1186    unsigned numReductionBlockArgs() { return getReductionVars().size(); }
1187  }];
1188
1189  // Description varies depending on the operation.
1190  let description = [{
1191    Reductions can be performed by specifying the reduction modifer
1192    (`default`, `inscan` or `task`) in `reduction_mod`, reduction accumulator
1193    variables in `reduction_vars`, symbols referring to reduction declarations
1194    in the `reduction_syms` attribute, and whether the reduction variable
1195    should be passed into the reduction region by value or by reference in
1196    `reduction_byref`. Each reduction is identified by the accumulator it uses
1197    and accumulators must not be repeated in the same reduction. A private
1198    variable corresponding to the accumulator is used in place of the
1199    accumulator inside the body of the operation. The reduction declaration
1200    specifies how to combine the values from each iteration, section, team,
1201    thread or simd lane defined by the operation's region into the final value,
1202    which is available in the accumulator after they all complete.
1203  }];
1204
1205  // Assembly format not defined because this clause must be processed together
1206  // with the first region of the operation, as it defines entry block
1207  // arguments.
1208}
1209
1210def OpenMP_ReductionClause : OpenMP_ReductionClauseSkip<>;
1211
1212//===----------------------------------------------------------------------===//
1213// V5.2: [10.4.2] `safelen` clause
1214//===----------------------------------------------------------------------===//
1215
1216class OpenMP_SafelenClauseSkip<
1217    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1218    bit description = false, bit extraClassDeclaration = false
1219  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1220                    extraClassDeclaration> {
1221  let arguments = (ins
1222    ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$safelen
1223  );
1224
1225  let optAssemblyFormat = [{
1226    `safelen` `(` $safelen  `)`
1227  }];
1228
1229  let description = [{
1230    The `safelen` clause specifies that no two concurrent iterations within a
1231    SIMD chunk can have a distance in the logical iteration space that is
1232    greater than or equal to the value given in the clause.
1233  }];
1234}
1235
1236def OpenMP_SafelenClause : OpenMP_SafelenClauseSkip<>;
1237
1238//===----------------------------------------------------------------------===//
1239// V5.2: [11.5.3] `schedule` clause
1240//===----------------------------------------------------------------------===//
1241
1242class OpenMP_ScheduleClauseSkip<
1243    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1244    bit description = false, bit extraClassDeclaration = false
1245  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1246                    extraClassDeclaration> {
1247  let arguments = (ins
1248    OptionalAttr<ScheduleKindAttr>:$schedule_kind,
1249    Optional<AnyType>:$schedule_chunk,
1250    OptionalAttr<ScheduleModifierAttr>:$schedule_mod,
1251    UnitAttr:$schedule_simd
1252  );
1253
1254  let optAssemblyFormat = [{
1255    `schedule` `(`
1256      custom<ScheduleClause>($schedule_kind, $schedule_mod, $schedule_simd,
1257                             $schedule_chunk, type($schedule_chunk)) `)`
1258  }];
1259
1260  let description = [{
1261    The optional `schedule_kind` attribute specifies the loop schedule for this
1262    loop, determining how the loop is distributed across the parallel threads.
1263    The optional `schedule_chunk` associated with this determines further
1264    controls this distribution.
1265  }];
1266}
1267
1268def OpenMP_ScheduleClause : OpenMP_ScheduleClauseSkip<>;
1269
1270//===----------------------------------------------------------------------===//
1271// V5.2: [10.4.3] `simdlen` clause
1272//===----------------------------------------------------------------------===//
1273
1274class OpenMP_SimdlenClauseSkip<
1275    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1276    bit description = false, bit extraClassDeclaration = false
1277  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1278                    extraClassDeclaration> {
1279  let arguments = (ins
1280    ConfinedAttr<OptionalAttr<I64Attr>, [IntPositive]>:$simdlen
1281  );
1282
1283  let optAssemblyFormat = [{
1284    `simdlen` `(` $simdlen  `)`
1285  }];
1286
1287  let description = [{
1288    When a `simdlen` clause is present, the preferred number of iterations to be
1289    executed concurrently is the value provided to the `simdlen` clause.
1290  }];
1291}
1292
1293def OpenMP_SimdlenClause : OpenMP_SimdlenClauseSkip<>;
1294
1295//===----------------------------------------------------------------------===//
1296// V5.2: [5.5.9] `task_reduction` clause
1297//===----------------------------------------------------------------------===//
1298
1299class OpenMP_TaskReductionClauseSkip<
1300    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1301    bit description = false, bit extraClassDeclaration = false
1302  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1303                    extraClassDeclaration> {
1304  let traits = [
1305    BlockArgOpenMPOpInterface, ReductionClauseInterface
1306  ];
1307
1308  let arguments = (ins
1309    Variadic<OpenMP_PointerLikeType>:$task_reduction_vars,
1310    OptionalAttr<DenseBoolArrayAttr>:$task_reduction_byref,
1311    OptionalAttr<SymbolRefArrayAttr>:$task_reduction_syms
1312  );
1313
1314  let extraClassDeclaration = [{
1315    /// Returns the reduction variables.
1316    SmallVector<Value> getReductionVars() {
1317      return SmallVector<Value>(getTaskReductionVars().begin(),
1318                                getTaskReductionVars().end());
1319    }
1320
1321    unsigned numTaskReductionBlockArgs() {
1322      return getTaskReductionVars().size();
1323    }
1324  }];
1325
1326  let description = [{
1327    The `task_reduction` clause specifies a reduction among tasks. For each list
1328    item, the number of copies is unspecified. Any copies associated with the
1329    reduction are initialized before they are accessed by the tasks
1330    participating in the reduction. After the end of the region, the original
1331    list item contains the result of the reduction. Similarly to the `reduction`
1332    clause, accumulator variables must be passed in `task_reduction_vars`,
1333    symbols referring to reduction declarations in the `task_reduction_syms`
1334    attribute, and whether the reduction variable should be passed into the
1335    reduction region by value or by reference in `task_reduction_byref`.
1336  }];
1337
1338  // Assembly format not defined because this clause must be processed together
1339  // with the first region of the operation, as it defines entry block
1340  // arguments.
1341}
1342
1343def OpenMP_TaskReductionClause : OpenMP_TaskReductionClauseSkip<>;
1344
1345//===----------------------------------------------------------------------===//
1346// V5.2: [13.3] `thread_limit` clause
1347//===----------------------------------------------------------------------===//
1348
1349class OpenMP_ThreadLimitClauseSkip<
1350    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1351    bit description = false, bit extraClassDeclaration = false
1352  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1353                    extraClassDeclaration> {
1354  let arguments = (ins
1355    Optional<AnyInteger>:$thread_limit
1356  );
1357
1358  let optAssemblyFormat = [{
1359    `thread_limit` `(` $thread_limit `:` type($thread_limit) `)`
1360  }];
1361
1362  let description = [{
1363    The optional `thread_limit` specifies the limit on the number of threads.
1364  }];
1365}
1366
1367def OpenMP_ThreadLimitClause : OpenMP_ThreadLimitClauseSkip<>;
1368
1369//===----------------------------------------------------------------------===//
1370// V5.2: [12.1] `untied` clause
1371//===----------------------------------------------------------------------===//
1372
1373class OpenMP_UntiedClauseSkip<
1374    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1375    bit description = false, bit extraClassDeclaration = false
1376  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1377                    extraClassDeclaration> {
1378  let arguments = (ins
1379    UnitAttr:$untied
1380  );
1381
1382  let optAssemblyFormat = [{
1383    `untied` $untied
1384  }];
1385
1386  let description = [{
1387    If the `untied` clause is present on a task construct, any thread in the
1388    team can resume the task region after a suspension. The `untied` clause is
1389    ignored if a `final` clause is present on the same task construct and the
1390    `final` expression evaluates to `true`, or if a task is an included task.
1391  }];
1392}
1393
1394def OpenMP_UntiedClause : OpenMP_UntiedClauseSkip<>;
1395
1396//===----------------------------------------------------------------------===//
1397// V5.2: [5.4.10] `use_device_addr` clause
1398//===----------------------------------------------------------------------===//
1399
1400class OpenMP_UseDeviceAddrClauseSkip<
1401    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1402    bit description = false, bit extraClassDeclaration = false
1403  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1404                    extraClassDeclaration> {
1405  let traits = [
1406    BlockArgOpenMPOpInterface
1407  ];
1408
1409  let arguments = (ins
1410    Variadic<OpenMP_PointerLikeType>:$use_device_addr_vars
1411  );
1412
1413  let extraClassDeclaration = [{
1414    unsigned numUseDeviceAddrBlockArgs() {
1415      return getUseDeviceAddrVars().size();
1416    }
1417  }];
1418
1419  let description = [{
1420    The optional `use_device_addr_vars` specifies the address of the objects in
1421    the device data environment.
1422  }];
1423
1424  // Assembly format not defined because this clause must be processed together
1425  // with the first region of the operation, as it defines entry block
1426  // arguments.
1427}
1428
1429def OpenMP_UseDeviceAddrClause : OpenMP_UseDeviceAddrClauseSkip<>;
1430
1431//===----------------------------------------------------------------------===//
1432// V5.2: [5.4.8] `use_device_ptr` clause
1433//===----------------------------------------------------------------------===//
1434
1435class OpenMP_UseDevicePtrClauseSkip<
1436    bit traits = false, bit arguments = false, bit assemblyFormat = false,
1437    bit description = false, bit extraClassDeclaration = false
1438  > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
1439                    extraClassDeclaration> {
1440  let traits = [
1441    BlockArgOpenMPOpInterface
1442  ];
1443
1444  let arguments = (ins
1445    Variadic<OpenMP_PointerLikeType>:$use_device_ptr_vars
1446  );
1447
1448  let extraClassDeclaration = [{
1449    unsigned numUseDevicePtrBlockArgs() {
1450      return getUseDevicePtrVars().size();
1451    }
1452  }];
1453
1454  let description = [{
1455    The optional `use_device_ptr_vars` specifies the device pointers to the
1456    corresponding list items in the device data environment.
1457  }];
1458
1459  // Assembly format not defined because this clause must be processed together
1460  // with the first region of the operation, as it defines entry block
1461  // arguments.
1462}
1463
1464def OpenMP_UseDevicePtrClause : OpenMP_UseDevicePtrClauseSkip<>;
1465
1466#endif // OPENMP_CLAUSES
1467