1//===-- OpenMPOps.td - OpenMP dialect operation 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 defines the basic operations for the OpenMP dialect.
10//
11//===----------------------------------------------------------------------===//
12
13
14#ifndef OPENMP_OPS
15#define OPENMP_OPS
16
17include "mlir/IR/OpBase.td"
18include "mlir/Interfaces/SideEffectInterfaces.td"
19include "mlir/Interfaces/ControlFlowInterfaces.td"
20include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
21include "mlir/Dialect/OpenMP/OmpCommon.td"
22
23def OpenMP_Dialect : Dialect {
24  let name = "omp";
25  let cppNamespace = "::mlir::omp";
26}
27
28class OpenMP_Op<string mnemonic, list<OpTrait> traits = []> :
29      Op<OpenMP_Dialect, mnemonic, traits>;
30
31// Type which can be constraint accepting standard integers, indices and
32// LLVM integer types.
33def IntLikeType : AnyTypeOf<[AnyInteger, Index, LLVM_AnyInteger]>;
34
35//===----------------------------------------------------------------------===//
36// 2.6 parallel Construct
37//===----------------------------------------------------------------------===//
38
39// Possible values for the default clause
40def ClauseDefaultPrivate : StrEnumAttrCase<"defprivate">;
41def ClauseDefaultFirstPrivate : StrEnumAttrCase<"deffirstprivate">;
42def ClauseDefaultShared : StrEnumAttrCase<"defshared">;
43def ClauseDefaultNone : StrEnumAttrCase<"defnone">;
44
45def ClauseDefault : StrEnumAttr<
46    "ClauseDefault",
47    "default clause",
48    [ClauseDefaultPrivate, ClauseDefaultFirstPrivate, ClauseDefaultShared,
49     ClauseDefaultNone]> {
50  let cppNamespace = "::mlir::omp";
51}
52
53def ParallelOp : OpenMP_Op<"parallel", [AttrSizedOperandSegments]> {
54  let summary = "parallel construct";
55  let description = [{
56    The parallel construct includes a region of code which is to be executed
57    by a team of threads.
58
59    The optional $if_expr_var parameter specifies a boolean result of a
60    conditional check. If this value is 1 or is not provided then the parallel
61    region runs as normal, if it is 0 then the parallel region is executed with
62    one thread.
63
64    The optional $num_threads_var parameter specifies the number of threads which
65    should be used to execute the parallel region.
66
67    The optional $default_val attribute specifies the default data sharing attribute
68    of values used in the parallel region that are not passed explicitly as parameters
69    to the operation.
70
71    The $private_vars, $firstprivate_vars, $shared_vars and $copyin_vars parameters
72    are a variadic list of values that specify the data sharing attribute of
73    those values.
74
75    The $allocators_vars and $allocate_vars parameters are a variadic list of values
76    that specify the memory allocator to be used to obtain storage for private values.
77
78    The optional $proc_bind_val attribute controls the thread affinity for the execution
79    of the parallel region.
80  }];
81
82  let arguments = (ins Optional<AnyType>:$if_expr_var,
83             Optional<AnyType>:$num_threads_var,
84             OptionalAttr<ClauseDefault>:$default_val,
85             Variadic<AnyType>:$private_vars,
86             Variadic<AnyType>:$firstprivate_vars,
87             Variadic<AnyType>:$shared_vars,
88             Variadic<AnyType>:$copyin_vars,
89             Variadic<AnyType>:$allocate_vars,
90             Variadic<AnyType>:$allocators_vars,
91             OptionalAttr<ProcBindKind>:$proc_bind_val);
92
93  let regions = (region AnyRegion:$region);
94
95  let builders = [
96    OpBuilderDAG<(ins CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes)>
97  ];
98  let parser = [{ return parseParallelOp(parser, result); }];
99  let printer = [{ return printParallelOp(p, *this); }];
100  let verifier = [{ return ::verifyParallelOp(*this); }];
101}
102
103def TerminatorOp : OpenMP_Op<"terminator", [Terminator]> {
104  let summary = "terminator for OpenMP regions";
105  let description = [{
106    A terminator operation for regions that appear in the body of OpenMP
107    operation.  These regions are not expected to return any value so the
108    terminator takes no operands. The terminator op returns control to the
109    enclosing op.
110  }];
111
112  let assemblyFormat = "attr-dict";
113}
114
115//===----------------------------------------------------------------------===//
116// 2.9.2 Workshare Loop Construct
117//===----------------------------------------------------------------------===//
118
119def WsLoopOp : OpenMP_Op<"wsloop", [AttrSizedOperandSegments]> {
120  let summary = "workshare loop construct";
121  let description = [{
122    The workshare loop construct specifies that the iterations of the loop(s)
123    will be executed in parallel by threads in the current context. These
124    iterations are spread across threads that already exist in the enclosing
125    parallel region.
126
127    The body region can contain any number of blocks. The region is terminated
128    by "omp.yield" instruction without operands.
129
130    ```
131      omp.wsloop (%i1, %i2) = (%c0, %c0) to (%c10, %c10) step (%c1, %c1) {
132        %a = load %arrA[%i1, %i2] : memref<?x?xf32>
133        %b = load %arrB[%i1, %i2] : memref<?x?xf32>
134        %sum = addf %a, %b : f32
135        store %sum, %arrC[%i1, %i2] : memref<?x?xf32>
136        omp.yield
137      }
138    ```
139
140    `private_vars`, `firstprivate_vars`, `lastprivate_vars` and `linear_vars`
141    arguments are variadic list of operands that specify the data sharing
142    attributes of the list of values. The `linear_step_vars` operand
143    additionally specifies the step for each associated linear operand. Note
144    that the `linear_vars` and `linear_step_vars` variadic lists should contain
145    the same number of elements.
146
147    The optional `schedule_val` attribute specifies the loop schedule for this
148    loop, determining how the loop is distributed across the parallel threads.
149    The optional `schedule_chunk_var` associated with this determines further
150    controls this distribution.
151
152    The optional `collapse_val` attribute specifies the number of loops which
153    are collapsed to form the worksharing loop.
154
155    The `nowait` attribute, when present, signifies that there should be no
156    implicit barrier at the end of the loop.
157
158    The optional `ordered_val` attribute specifies how many loops are associated
159    with the do loop construct.
160
161    The optional `order` attribute specifies which order the iterations of the
162    associate loops are executed in. Currently the only option for this
163    attribute is "concurrent".
164  }];
165
166  let arguments = (ins Variadic<IntLikeType>:$lowerBound,
167             Variadic<IntLikeType>:$upperBound,
168             Variadic<IntLikeType>:$step,
169             Variadic<AnyType>:$private_vars,
170             Variadic<AnyType>:$firstprivate_vars,
171             Variadic<AnyType>:$lastprivate_vars,
172             Variadic<AnyType>:$linear_vars,
173             Variadic<AnyType>:$linear_step_vars,
174             OptionalAttr<ScheduleKind>:$schedule_val,
175             Optional<AnyType>:$schedule_chunk_var,
176             Confined<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$collapse_val,
177             OptionalAttr<UnitAttr>:$nowait,
178             Confined<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$ordered_val,
179             OptionalAttr<OrderKind>:$order_val);
180
181  let builders = [
182    OpBuilderDAG<(ins "ValueRange":$lowerBound, "ValueRange":$upperBound,
183                  "ValueRange":$step,
184                  CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes)>
185  ];
186
187  let regions = (region AnyRegion:$region);
188}
189
190def YieldOp : OpenMP_Op<"yield", [NoSideEffect, ReturnLike, Terminator,
191                                  HasParent<"WsLoopOp">]> {
192  let summary = "loop yield and termination operation";
193  let description = [{
194    "omp.yield" yields SSA values from the OpenMP dialect op region and
195    terminates the region. The semantics of how the values are yielded is
196    defined by the parent operation.
197    If "omp.yield" has any operands, the operands must match the parent
198    operation's results.
199  }];
200
201  let arguments = (ins Variadic<AnyType>:$results);
202
203  let assemblyFormat = [{ ( `(` $results^ `:` type($results) `)` )? attr-dict}];
204}
205
206//===----------------------------------------------------------------------===//
207// 2.10.4 taskyield Construct
208//===----------------------------------------------------------------------===//
209
210def TaskyieldOp : OpenMP_Op<"taskyield"> {
211  let summary = "taskyield construct";
212  let description = [{
213    The taskyield construct specifies that the current task can be suspended
214    in favor of execution of a different task.
215  }];
216
217  let assemblyFormat = "attr-dict";
218}
219
220//===----------------------------------------------------------------------===//
221// 2.13.7 flush Construct
222//===----------------------------------------------------------------------===//
223def FlushOp : OpenMP_Op<"flush"> {
224  let summary = "flush construct";
225  let description = [{
226    The flush construct executes the OpenMP flush operation. This operation
227    makes a thread’s temporary view of memory consistent with memory and
228    enforces an order on the memory operations of the variables explicitly
229    specified or implied.
230  }];
231
232  let arguments = (ins Variadic<AnyType>:$varList);
233
234  let assemblyFormat = [{ ( `(` $varList^ `:` type($varList) `)` )? attr-dict}];
235}
236
237//===----------------------------------------------------------------------===//
238// 2.16 master Construct
239//===----------------------------------------------------------------------===//
240def MasterOp : OpenMP_Op<"master"> {
241  let summary = "master construct";
242  let description = [{
243    The master construct specifies a structured block that is executed by
244    the master thread of the team.
245  }];
246
247  let regions = (region AnyRegion:$region);
248
249  let assemblyFormat = "$region attr-dict";
250}
251
252//===----------------------------------------------------------------------===//
253// 2.17.2 barrier Construct
254//===----------------------------------------------------------------------===//
255
256def BarrierOp : OpenMP_Op<"barrier"> {
257  let summary = "barrier construct";
258  let description = [{
259    The barrier construct specifies an explicit barrier at the point at which
260    the construct appears.
261  }];
262
263  let assemblyFormat = "attr-dict";
264}
265
266//===----------------------------------------------------------------------===//
267// 2.17.5 taskwait Construct
268//===----------------------------------------------------------------------===//
269
270def TaskwaitOp : OpenMP_Op<"taskwait"> {
271  let summary = "taskwait construct";
272  let description = [{
273    The taskwait construct specifies a wait on the completion of child tasks
274    of the current task.
275  }];
276
277  let assemblyFormat = "attr-dict";
278}
279
280#endif // OPENMP_OPS
281