@@ -231,3 +231,59 @@ corresponding operation, except if it is explicitly skipped as described
231
231
[ above] ( #overriding-clause-inherited-properties ) . This way, in case of a later
232
232
tablegen failure while processing OpenMP dialect operations, earlier messages
233
233
triggered by that pass can point to a likely solution.
234
+
235
+ ## Loop-Associated Directives
236
+
237
+ Loop-associated OpenMP constructs are represented in the dialect as loop wrapper
238
+ operations. These implement the ` LoopWrapperInterface ` , which enforces a series
239
+ of restrictions upon the operation:
240
+ - It contains a single region with a single block; and
241
+ - Its block contains exactly two operations: another loop wrapper or
242
+ ` omp.loop_nest ` operation and a terminator.
243
+
244
+ This approach splits the representation for a loop nest and the loop-associated
245
+ constructs that specify how its iterations are executed, possibly across various
246
+ SIMD lanes (` omp.simd ` ), threads (` omp.wsloop ` ), teams of threads
247
+ (` omp.distribute ` ) or tasks (` omp.taskloop ` ). The ability to directly nest
248
+ multiple loop wrappers to impact the execution of a single loop nest is used to
249
+ represent composite constructs in a modular way.
250
+
251
+ The ` omp.loop_nest ` operation represents a collapsed rectangular loop nest that
252
+ must always be wrapped by at least one loop wrapper, which defines how it is
253
+ intended to be executed. It serves as a simpler and more restrictive
254
+ representation of OpenMP loops while a more general approach to support
255
+ non-rectangular loop nests, loop transformations and non-perfectly nested loops
256
+ based on a new ` omp.canonical_loop ` definition is developed.
257
+
258
+ The following example shows how a ` parallel {do,for} ` construct would be
259
+ represented:
260
+ ``` mlir
261
+ omp.parallel ... {
262
+ ...
263
+ omp.wsloop ... {
264
+ omp.loop_nest (%i) : index = (%lb) to (%ub) step (%step) {
265
+ %a = load %a[%i] : memref<?xf32>
266
+ %b = load %b[%i] : memref<?xf32>
267
+ %sum = arith.addf %a, %b : f32
268
+ store %sum, %c[%i] : memref<?xf32>
269
+ omp.yield
270
+ }
271
+ omp.terminator
272
+ }
273
+ ...
274
+ omp.terminator
275
+ }
276
+ ```
277
+
278
+ ### Loop Transformations
279
+
280
+ In addition to the worksharing loop-associated constructs described above, the
281
+ OpenMP specification also defines a set of loop transformation constructs. They
282
+ replace the associated loop(s) before worksharing constructs are executed on the
283
+ generated loop(s). Some examples of such constructs are ` tile ` and ` unroll ` .
284
+
285
+ A general approach for representing these types of OpenMP constructs has not yet
286
+ been implemented, but it is closely linked to the ` omp.canonical_loop ` work.
287
+ Nevertheless, loop transformation that the ` collapse ` clause for loop-associated
288
+ worksharing constructs defines can be represented by introducing multiple
289
+ bounds, step and induction variables to the ` omp.loop_nest ` operation.
0 commit comments