@@ -285,7 +285,75 @@ argument's type:
285
285
specific ` mlir::Attribute ` subclass) will be used instead.
286
286
- Other attribute types will be represented with their ` storageType ` .
287
287
- It will create ` <Name>Operands ` structure for each operation, which is an
288
- empty structure subclassing all operand structures defined for the corresponding ` OpenMP_Op ` 's clauses.
288
+ empty structure subclassing all operand structures defined for the corresponding
289
+ ` OpenMP_Op ` 's clauses.
290
+
291
+ ### Entry Block Argument-Defining Clauses
292
+
293
+ Certain OpenMP clauses introduce in their MLIR representation mappings between
294
+ outside values and entry block arguments for the region of the MLIR operation
295
+ they are applied to. This enables, for example, the introduction of private
296
+ copies of the same underlying variable. Currently, clauses with this property
297
+ can be classified in three main categories:
298
+ - Map-like clauses: ` map ` , ` use_device_addr ` and ` use_device_ptr ` .
299
+ - Reduction-like clauses: ` in_reduction ` , ` reduction ` and ` task_reduction ` .
300
+ - Privatization clause: ` private ` .
301
+
302
+ All three kinds of entry block argument-defining clauses use a similar custom
303
+ assembly format representation, only differing based on the different pieces of
304
+ information attached to each kind. Below, one example of each is shown:
305
+
306
+ ``` mlir
307
+ omp.target map_entries(%x -> %x.m, %y -> %y.m : !llvm.ptr, !llvm.ptr) {
308
+ // Use %x.m, %y.m in place of %x and %y...
309
+ }
310
+
311
+ omp.wsloop reduction(@add.i32 %x -> %x.r, byref @add.f32 %y -> %y.r : !llvm.ptr, !llvm.ptr) {
312
+ // Use %x.r, %y.r in place of %x and %y...
313
+ }
314
+
315
+ omp.parallel private(@x.privatizer %x -> %x.p, @y.privatizer %y -> %y.p : !llvm.ptr, !llvm.ptr) {
316
+ // Use %x.p, %y.p in place of %x and %y...
317
+ }
318
+ ```
319
+
320
+ As a consequence of parsing and printing the operation's first region entry
321
+ block argument names together with the custom assembly format of these clauses,
322
+ entry block arguments (i.e. the ` ^bb0(...): ` line) must not be explicitly
323
+ defined for these operations. Additionally, it is not possible to implement this
324
+ feature while allowing each clause to be independently parsed and printed,
325
+ because they need to be printed/parsed together with the corresponding
326
+ operation's first region. They must have a well-defined ordering in which
327
+ multiple of these clauses are specified for a given operation, as well.
328
+
329
+ The parsing/printing of these clauses together with the region provides the
330
+ ability to define entry block arguments directly after the ` -> ` . Forcing a
331
+ specific ordering between these clauses makes the block argument ordering
332
+ well-defined, which is the property used to easily match each clause with the
333
+ entry block arguments defined by it.
334
+
335
+ Custom printers and parsers for operation regions based on the entry block
336
+ argument-defining clauses they take are implemented based on the
337
+ ` {parse,print}BlockArgRegion ` functions, which take care of the sorting and
338
+ formatting of each kind of clause, minimizing code duplication resulting from
339
+ this approach. One example of the custom assembly format of an operation taking
340
+ the ` private ` and ` reduction ` clauses is the following:
341
+
342
+ ``` tablegen
343
+ let assemblyFormat = clausesAssemblyFormat # [{
344
+ custom<PrivateReductionRegion>($region, $private_vars, type($private_vars),
345
+ $private_syms, $reduction_vars, type($reduction_vars), $reduction_byref,
346
+ $reduction_syms) attr-dict
347
+ }];
348
+ ```
349
+
350
+ The ` BlockArgOpenMPOpInterface ` has been introduced to simplify the addition and
351
+ handling of these kinds of clauses. It holds ` num<ClauseName>BlockArgs() `
352
+ functions that by default return 0, to be overriden by each clause through the
353
+ ` extraClassDeclaration ` property. Based on these functions and the expected
354
+ alphabetical sorting between entry block argument-defining clauses, it
355
+ implements ` get<ClauseName>BlockArgs() ` functions that are the intended method
356
+ of accessing clause-defined block arguments.
289
357
290
358
## Loop-Associated Directives
291
359
0 commit comments