diff --git a/mlir/docs/Dialects/OpenMPDialect/_index.md b/mlir/docs/Dialects/OpenMPDialect/_index.md index 88437b8cf828c..b4e359284edae 100644 --- a/mlir/docs/Dialects/OpenMPDialect/_index.md +++ b/mlir/docs/Dialects/OpenMPDialect/_index.md @@ -132,7 +132,8 @@ and optional list of `traits`, a list of `clauses` where all the applicable would have to be defined in the operation's body are the `summary` and `description`. For the latter, only the operation itself would have to be defined, and the description for its clause-inherited arguments is appended -through the inherited `clausesDescription` property. +through the inherited `clausesDescription` property. By convention, the list of +clauses for an operation must be specified in alphabetical order. If the operation is intended to have a single region, this is better achieved by setting the `singleRegion=true` template argument of `OpenMP_Op` rather manually @@ -285,7 +286,76 @@ argument's type: specific `mlir::Attribute` subclass) will be used instead. - Other attribute types will be represented with their `storageType`. - It will create `Operands` structure for each operation, which is an -empty structure subclassing all operand structures defined for the corresponding `OpenMP_Op`'s clauses. +empty structure subclassing all operand structures defined for the corresponding +`OpenMP_Op`'s clauses. + +### Entry Block Argument-Defining Clauses + +In their MLIR representation, certain OpenMP clauses introduce a mapping between +values defined outside the operation they are applied to and entry block +arguments for the region of that MLIR operation. This enables, for example, the +introduction of private copies of the same underlying variable defined outside +the MLIR operation the clause is attached to. Currently, clauses with this +property can be classified into three main categories: + - Map-like clauses: `map`, `use_device_addr` and `use_device_ptr`. + - Reduction-like clauses: `in_reduction`, `reduction` and `task_reduction`. + - Privatization clauses: `private`. + +All three kinds of entry block argument-defining clauses use a similar custom +assembly format representation, only differing based on the different pieces of +information attached to each kind. Below, one example of each is shown: + +```mlir +omp.target map_entries(%x -> %x.m, %y -> %y.m : !llvm.ptr, !llvm.ptr) { + // Use %x.m, %y.m in place of %x and %y... +} + +omp.wsloop reduction(@add.i32 %x -> %x.r, byref @add.f32 %y -> %y.r : !llvm.ptr, !llvm.ptr) { + // Use %x.r, %y.r in place of %x and %y... +} + +omp.parallel private(@x.privatizer %x -> %x.p, @y.privatizer %y -> %y.p : !llvm.ptr, !llvm.ptr) { + // Use %x.p, %y.p in place of %x and %y... +} +``` + +As a consequence of parsing and printing the operation's first region entry +block argument names together with the custom assembly format of these clauses, +entry block arguments (i.e. the `^bb0(...):` line) must not be explicitly +defined for these operations. Additionally, it is not possible to implement this +feature while allowing each clause to be independently parsed and printed, +because they need to be printed/parsed together with the corresponding +operation's first region. They must have a well-defined ordering in which +multiple of these clauses are specified for a given operation, as well. + +The parsing/printing of these clauses together with the region provides the +ability to define entry block arguments directly after the `->`. Forcing a +specific ordering between these clauses makes the block argument ordering +well-defined, which is the property used to easily match each clause with the +entry block arguments defined by it. + +Custom printers and parsers for operation regions based on the entry block +argument-defining clauses they take are implemented based on the +`{parse,print}BlockArgRegion` functions, which take care of the sorting and +formatting of each kind of clause, minimizing code duplication resulting from +this approach. One example of the custom assembly format of an operation taking +the `private` and `reduction` clauses is the following: + +```tablegen +let assemblyFormat = clausesAssemblyFormat # [{ + custom($region, $private_vars, type($private_vars), + $private_syms, $reduction_vars, type($reduction_vars), $reduction_byref, + $reduction_syms) attr-dict +}]; +``` + +The `BlockArgOpenMPOpInterface` has been introduced to simplify the addition and +handling of these kinds of clauses. It holds `numBlockArgs()` +functions that by default return 0, to be overriden by each clause through the +`extraClassDeclaration` property. Based on these functions and the expected +alphabetical sorting between entry block argument-defining clauses, it +implements `getBlockArgs()` functions that are the intended method +of accessing clause-defined block arguments. ## Loop-Associated Directives