Skip to content

[MLIR][OpenMP] Add OpenMP_Clause tablegen definitions #92521

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 1, 2024

Conversation

skatrak
Copy link
Member

@skatrak skatrak commented May 17, 2024

This patch adds a new tablegen file for the OpenMP dialect containing the list of clauses currently supported.

@llvmbot
Copy link
Member

llvmbot commented May 17, 2024

@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-mlir-openmp

Author: Sergio Afonso (skatrak)

Changes

This patch adds a new tablegen file for the OpenMP dialect containing the list of clauses currently supported.


Patch is 44.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92521.diff

1 Files Affected:

  • (added) mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td (+1183)
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
new file mode 100644
index 0000000000000..8b3a53a5842f3
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -0,0 +1,1183 @@
+//=== OpenMPClauses.td - OpenMP dialect clause definitions -*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains clause definitions for the OpenMP dialect.
+//
+// For each "Xyz" clause, there is an "OpenMP_XyzClauseSkip" class and an
+// "OpenMP_XyzClause" definition. The latter is an instantiation of the former
+// where all "skip" template parameters are set to `false` and should be the
+// preferred variant to used whenever possible when defining `OpenMP_Op`
+// instances.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OPENMP_CLAUSES
+#define OPENMP_CLAUSES
+
+include "mlir/Dialect/OpenMP/OpenMPOpBase.td"
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.11] `aligned` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_AlignedClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$aligned_vars,
+    OptionalAttr<I64ArrayAttr>:$alignment_values
+  );
+
+  let assemblyFormat = [{
+    `aligned` `(` custom<AlignedClause>($aligned_vars, type($aligned_vars),
+                                        $alignment_values) `)`
+  }];
+
+  let description = [{
+    The `alignment_values` attribute additionally specifies alignment of each
+    corresponding aligned operand. Note that `aligned_vars` and
+    `alignment_values` should contain the same number of elements.
+  }];
+}
+
+def OpenMP_AlignedClause : OpenMP_AlignedClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [6.6] `allocate` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_AllocateClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<AnyType>:$allocate_vars,
+    Variadic<AnyType>:$allocators_vars
+  );
+
+  let assemblyFormat = [{
+    `allocate` `(`
+      custom<AllocateAndAllocator>($allocate_vars, type($allocate_vars),
+                                   $allocators_vars, type($allocators_vars)) `)`
+  }];
+
+  let description = [{
+    The `allocators_vars` and `allocate_vars` parameters are a variadic list of
+    values that specify the memory allocator to be used to obtain storage for
+    private values.
+  }];
+}
+
+def OpenMP_AllocateClause : OpenMP_AllocateClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [16.1, 16.2] `cancel-directive-name` clause set
+//===----------------------------------------------------------------------===//
+
+class OpenMP_CancelDirectiveNameClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/true, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    CancellationConstructTypeAttr:$cancellation_construct_type_val
+  );
+
+  let assemblyFormat = [{
+    `cancellation_construct_type` `(`
+      custom<ClauseAttr>($cancellation_construct_type_val) `)`
+  }];
+
+  // TODO: Add description.
+}
+
+def OpenMP_CancelDirectiveNameClause : OpenMP_CancelDirectiveNameClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [4.4.3] `collapse` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_CollapseClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let traits = [
+    AllTypesMatch<["lowerBound", "upperBound", "step"]>
+  ];
+
+  let arguments = (ins
+    Variadic<IntLikeType>:$lowerBound,
+    Variadic<IntLikeType>:$upperBound,
+    Variadic<IntLikeType>:$step
+  );
+
+  let extraClassDeclaration = [{
+    /// Returns the number of loops in the loop nest.
+    unsigned getNumLoops() { return getLowerBound().size(); }
+  }];
+
+  // Description and formatting integrated in the `omp.loop_nest` operation,
+  // which is the only one currently accepting this clause.
+}
+
+def OpenMP_CollapseClause : OpenMP_CollapseClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.7.2] `copyprivate` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_CopyprivateClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$copyprivate_vars,
+    OptionalAttr<SymbolRefArrayAttr>:$copyprivate_funcs
+  );
+
+  let assemblyFormat = [{
+    `copyprivate` `(`
+      custom<CopyPrivateVarList>($copyprivate_vars, type($copyprivate_vars),
+                                 $copyprivate_funcs) `)`
+  }];
+
+  let description = [{
+    If `copyprivate` variables and functions are specified, then each thread
+    variable is updated with the variable value of the thread that executed
+    the single region, using the specified copy functions.
+  }];
+}
+
+def OpenMP_CopyprivateClause : OpenMP_CopyprivateClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [15.2] `critical` `name` argument
+//===----------------------------------------------------------------------===//
+
+class OpenMP_CriticalNameClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/true, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    SymbolNameAttr:$sym_name
+  );
+
+  let assemblyFormat = "$sym_name";
+
+  let description = [{
+    The `sym_name` can be used in `omp.critical` constructs in the dialect.
+  }];
+}
+
+def OpenMP_CriticalNameClause : OpenMP_CriticalNameClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [15.9.5] `depend` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DependClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    OptionalAttr<TaskDependArrayAttr>:$depends,
+    Variadic<OpenMP_PointerLikeType>:$depend_vars
+  );
+
+  let assemblyFormat = [{
+    `depend` `(`
+      custom<DependVarList>($depend_vars, type($depend_vars), $depends) `)`
+  }];
+
+  let description = [{
+    The `depends` and `depend_vars` arguments are variadic lists of values that
+    specify the dependencies of this particular task in relation to other tasks.
+  }];
+}
+
+def OpenMP_DependClause : OpenMP_DependClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [13.2] `device` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DeviceClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Optional<AnyInteger>:$device
+  );
+
+  let assemblyFormat = [{
+    `device` `(` $device `:` type($device) `)`
+  }];
+
+  let description = [{
+    The optional `device` parameter specifies the device number for the target
+    region.
+  }];
+}
+
+def OpenMP_DeviceClause : OpenMP_DeviceClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [11.6.1] `dist_schedule` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DistScheduleClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    UnitAttr:$dist_schedule_static,
+    Optional<IntLikeType>:$chunk_size
+  );
+
+  let assemblyFormat = [{
+    `dist_schedule_static` $dist_schedule_static
+    | `chunk_size` `(` $chunk_size `:` type($chunk_size) `)`
+  }];
+
+  let description = [{
+    The `dist_schedule_static` attribute specifies the schedule for this loop,
+    determining how the loop is distributed across the various teams. The
+    optional `chunk_size` associated with this determines further controls this
+    distribution.
+  }];
+}
+
+def OpenMP_DistScheduleClause : OpenMP_DistScheduleClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [15.9.6] `doacross` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DoacrossClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/true, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    OptionalAttr<ClauseDependAttr>:$depend_type_val,
+    ConfinedAttr<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$num_loops_val,
+    Variadic<AnyType>:$depend_vec_vars
+  );
+
+  let assemblyFormat = [{
+    ( `depend_type` `` $depend_type_val^ )?
+    ( `depend_vec` `(` $depend_vec_vars^ `:` type($depend_vec_vars) `)` )?
+  }];
+
+  let description = [{
+    The `depend_type_val` attribute refers to either the DEPEND(SOURCE) clause
+    or the DEPEND(SINK: vec) clause.
+
+    The `num_loops_val` attribute specifies the number of loops in the doacross
+    nest.
+
+    The `depend_vec_vars` is a variadic list of operands that specifies the
+    index of the loop iterator in the doacross nest for the DEPEND(SOURCE)
+    clause or the index of the element of "vec" for the DEPEND(SINK: vec)
+    clause. It contains the operands in multiple "vec" when multiple
+    DEPEND(SINK: vec) clauses exist in one ORDERED directive.
+  }];
+}
+
+def OpenMP_DoacrossClause : OpenMP_DoacrossClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [12.3] `final` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_FinalClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Optional<I1>:$final_expr
+  );
+
+  let assemblyFormat = [{
+    `final` `(` $final_expr `)`
+  }];
+
+  let description = [{
+    When a `final` clause is present and the `final` clause expression evaluates
+    to `true`, the generated tasks will be final tasks. All task constructs
+    encountered during execution of a final task will generate final and
+    included tasks. The use of a variable in a `final` clause expression causes
+    an implicit reference to the variable in all enclosing constructs.
+  }];
+}
+
+def OpenMP_FinalClause : OpenMP_FinalClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [12.6.1] `grainsize` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_GrainsizeClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Optional<IntLikeType>:$grain_size
+  );
+
+  let assemblyFormat = [{
+    `grain_size` `(` $grain_size `:` type($grain_size) `)`
+  }];
+
+  let description = [{
+    If a `grainsize` clause is present, the number of logical loop iterations
+    assigned to each generated task is greater than or equal to the minimum of
+    the value of the grain-size expression and the number of logical loop
+    iterations, but less than two times the value of the grain-size expression.
+  }];
+}
+
+def OpenMP_GrainsizeClause : OpenMP_GrainsizeClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.4.9] `has_device_addr` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_HasDeviceAddrClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$has_device_addr
+  );
+
+  let assemblyFormat = [{
+    `has_device_addr` `(` $has_device_addr `:` type($has_device_addr) `)`
+  }];
+
+  let description = [{
+    The optional `has_device_addr` indicates that list items already have device
+    addresses, so they may be directly accessed from the target device. This
+    includes array sections.
+  }];
+}
+
+def OpenMP_HasDeviceAddrClause : OpenMP_HasDeviceAddrClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [15.1.2] `hint` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_HintClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    DefaultValuedOptionalAttr<I64Attr, "0">:$hint_val
+  );
+
+  let assemblyFormat = [{
+    `hint` `(` custom<SynchronizationHint>($hint_val) `)`
+  }];
+
+  let description = [{
+    `hint` is the value of hint (as specified in the hint clause). It is a
+    compile time constant. As the name suggests, this is just a hint for
+    optimization.
+  }];
+}
+
+def OpenMP_HintClause : OpenMP_HintClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [3.4] `if` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_IfClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Optional<I1>:$if_expr
+  );
+
+  let assemblyFormat = [{
+    `if` `(` $if_expr `)`
+  }];
+
+  // Description varies depending on the operation.
+}
+
+def OpenMP_IfClause : OpenMP_IfClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.5.10] `in_reduction` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_InReductionClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let traits = [
+    ReductionClauseInterface
+  ];
+
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$in_reduction_vars,
+    OptionalAttr<SymbolRefArrayAttr>:$in_reductions
+  );
+
+  let assemblyFormat = [{
+    `in_reduction` `(`
+      custom<ReductionVarList>($in_reduction_vars, type($in_reduction_vars),
+                               $in_reductions) `)`
+  }];
+
+  let extraClassDeclaration = [{
+    /// Returns the reduction variables.
+    SmallVector<Value> getReductionVars() {
+      return SmallVector<Value>(getInReductionVars().begin(),
+                                getInReductionVars().end());
+    }
+  }];
+
+  // Description varies depending on the operation.
+}
+
+def OpenMP_InReductionClause : OpenMP_InReductionClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.4.7] `is_device_ptr` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_IsDevicePtrClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$is_device_ptr
+  );
+
+  let assemblyFormat = [{
+    `is_device_ptr` `(` $is_device_ptr `:` type($is_device_ptr) `)`
+  }];
+
+  let description = [{
+    The optional `is_device_ptr` indicates list items are device pointers.
+  }];
+}
+
+def OpenMP_IsDevicePtrClause : OpenMP_IsDevicePtrClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.4.6] `linear` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_LinearClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<AnyType>:$linear_vars,
+    Variadic<I32>:$linear_step_vars
+  );
+
+  let assemblyFormat = [{
+    `linear` `(`
+      custom<LinearClause>($linear_vars, type($linear_vars),
+                           $linear_step_vars) `)`
+  }];
+
+  let description = [{
+    The `linear_step_vars` operand additionally specifies the step for each
+    associated linear operand. Note that the `linear_vars` and
+    `linear_step_vars` variadic lists should contain the same number of
+    elements.
+  }];
+}
+
+def OpenMP_LinearClause : OpenMP_LinearClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.8.3] `map` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_MapClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat =...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented May 17, 2024

@llvm/pr-subscribers-mlir

Author: Sergio Afonso (skatrak)

Changes

This patch adds a new tablegen file for the OpenMP dialect containing the list of clauses currently supported.


Patch is 44.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92521.diff

1 Files Affected:

  • (added) mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td (+1183)
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
new file mode 100644
index 0000000000000..8b3a53a5842f3
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -0,0 +1,1183 @@
+//=== OpenMPClauses.td - OpenMP dialect clause definitions -*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains clause definitions for the OpenMP dialect.
+//
+// For each "Xyz" clause, there is an "OpenMP_XyzClauseSkip" class and an
+// "OpenMP_XyzClause" definition. The latter is an instantiation of the former
+// where all "skip" template parameters are set to `false` and should be the
+// preferred variant to used whenever possible when defining `OpenMP_Op`
+// instances.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OPENMP_CLAUSES
+#define OPENMP_CLAUSES
+
+include "mlir/Dialect/OpenMP/OpenMPOpBase.td"
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.11] `aligned` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_AlignedClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$aligned_vars,
+    OptionalAttr<I64ArrayAttr>:$alignment_values
+  );
+
+  let assemblyFormat = [{
+    `aligned` `(` custom<AlignedClause>($aligned_vars, type($aligned_vars),
+                                        $alignment_values) `)`
+  }];
+
+  let description = [{
+    The `alignment_values` attribute additionally specifies alignment of each
+    corresponding aligned operand. Note that `aligned_vars` and
+    `alignment_values` should contain the same number of elements.
+  }];
+}
+
+def OpenMP_AlignedClause : OpenMP_AlignedClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [6.6] `allocate` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_AllocateClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<AnyType>:$allocate_vars,
+    Variadic<AnyType>:$allocators_vars
+  );
+
+  let assemblyFormat = [{
+    `allocate` `(`
+      custom<AllocateAndAllocator>($allocate_vars, type($allocate_vars),
+                                   $allocators_vars, type($allocators_vars)) `)`
+  }];
+
+  let description = [{
+    The `allocators_vars` and `allocate_vars` parameters are a variadic list of
+    values that specify the memory allocator to be used to obtain storage for
+    private values.
+  }];
+}
+
+def OpenMP_AllocateClause : OpenMP_AllocateClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [16.1, 16.2] `cancel-directive-name` clause set
+//===----------------------------------------------------------------------===//
+
+class OpenMP_CancelDirectiveNameClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/true, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    CancellationConstructTypeAttr:$cancellation_construct_type_val
+  );
+
+  let assemblyFormat = [{
+    `cancellation_construct_type` `(`
+      custom<ClauseAttr>($cancellation_construct_type_val) `)`
+  }];
+
+  // TODO: Add description.
+}
+
+def OpenMP_CancelDirectiveNameClause : OpenMP_CancelDirectiveNameClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [4.4.3] `collapse` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_CollapseClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let traits = [
+    AllTypesMatch<["lowerBound", "upperBound", "step"]>
+  ];
+
+  let arguments = (ins
+    Variadic<IntLikeType>:$lowerBound,
+    Variadic<IntLikeType>:$upperBound,
+    Variadic<IntLikeType>:$step
+  );
+
+  let extraClassDeclaration = [{
+    /// Returns the number of loops in the loop nest.
+    unsigned getNumLoops() { return getLowerBound().size(); }
+  }];
+
+  // Description and formatting integrated in the `omp.loop_nest` operation,
+  // which is the only one currently accepting this clause.
+}
+
+def OpenMP_CollapseClause : OpenMP_CollapseClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.7.2] `copyprivate` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_CopyprivateClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$copyprivate_vars,
+    OptionalAttr<SymbolRefArrayAttr>:$copyprivate_funcs
+  );
+
+  let assemblyFormat = [{
+    `copyprivate` `(`
+      custom<CopyPrivateVarList>($copyprivate_vars, type($copyprivate_vars),
+                                 $copyprivate_funcs) `)`
+  }];
+
+  let description = [{
+    If `copyprivate` variables and functions are specified, then each thread
+    variable is updated with the variable value of the thread that executed
+    the single region, using the specified copy functions.
+  }];
+}
+
+def OpenMP_CopyprivateClause : OpenMP_CopyprivateClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [15.2] `critical` `name` argument
+//===----------------------------------------------------------------------===//
+
+class OpenMP_CriticalNameClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/true, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    SymbolNameAttr:$sym_name
+  );
+
+  let assemblyFormat = "$sym_name";
+
+  let description = [{
+    The `sym_name` can be used in `omp.critical` constructs in the dialect.
+  }];
+}
+
+def OpenMP_CriticalNameClause : OpenMP_CriticalNameClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [15.9.5] `depend` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DependClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    OptionalAttr<TaskDependArrayAttr>:$depends,
+    Variadic<OpenMP_PointerLikeType>:$depend_vars
+  );
+
+  let assemblyFormat = [{
+    `depend` `(`
+      custom<DependVarList>($depend_vars, type($depend_vars), $depends) `)`
+  }];
+
+  let description = [{
+    The `depends` and `depend_vars` arguments are variadic lists of values that
+    specify the dependencies of this particular task in relation to other tasks.
+  }];
+}
+
+def OpenMP_DependClause : OpenMP_DependClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [13.2] `device` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DeviceClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Optional<AnyInteger>:$device
+  );
+
+  let assemblyFormat = [{
+    `device` `(` $device `:` type($device) `)`
+  }];
+
+  let description = [{
+    The optional `device` parameter specifies the device number for the target
+    region.
+  }];
+}
+
+def OpenMP_DeviceClause : OpenMP_DeviceClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [11.6.1] `dist_schedule` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DistScheduleClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    UnitAttr:$dist_schedule_static,
+    Optional<IntLikeType>:$chunk_size
+  );
+
+  let assemblyFormat = [{
+    `dist_schedule_static` $dist_schedule_static
+    | `chunk_size` `(` $chunk_size `:` type($chunk_size) `)`
+  }];
+
+  let description = [{
+    The `dist_schedule_static` attribute specifies the schedule for this loop,
+    determining how the loop is distributed across the various teams. The
+    optional `chunk_size` associated with this determines further controls this
+    distribution.
+  }];
+}
+
+def OpenMP_DistScheduleClause : OpenMP_DistScheduleClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [15.9.6] `doacross` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_DoacrossClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/true, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    OptionalAttr<ClauseDependAttr>:$depend_type_val,
+    ConfinedAttr<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$num_loops_val,
+    Variadic<AnyType>:$depend_vec_vars
+  );
+
+  let assemblyFormat = [{
+    ( `depend_type` `` $depend_type_val^ )?
+    ( `depend_vec` `(` $depend_vec_vars^ `:` type($depend_vec_vars) `)` )?
+  }];
+
+  let description = [{
+    The `depend_type_val` attribute refers to either the DEPEND(SOURCE) clause
+    or the DEPEND(SINK: vec) clause.
+
+    The `num_loops_val` attribute specifies the number of loops in the doacross
+    nest.
+
+    The `depend_vec_vars` is a variadic list of operands that specifies the
+    index of the loop iterator in the doacross nest for the DEPEND(SOURCE)
+    clause or the index of the element of "vec" for the DEPEND(SINK: vec)
+    clause. It contains the operands in multiple "vec" when multiple
+    DEPEND(SINK: vec) clauses exist in one ORDERED directive.
+  }];
+}
+
+def OpenMP_DoacrossClause : OpenMP_DoacrossClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [12.3] `final` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_FinalClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Optional<I1>:$final_expr
+  );
+
+  let assemblyFormat = [{
+    `final` `(` $final_expr `)`
+  }];
+
+  let description = [{
+    When a `final` clause is present and the `final` clause expression evaluates
+    to `true`, the generated tasks will be final tasks. All task constructs
+    encountered during execution of a final task will generate final and
+    included tasks. The use of a variable in a `final` clause expression causes
+    an implicit reference to the variable in all enclosing constructs.
+  }];
+}
+
+def OpenMP_FinalClause : OpenMP_FinalClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [12.6.1] `grainsize` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_GrainsizeClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Optional<IntLikeType>:$grain_size
+  );
+
+  let assemblyFormat = [{
+    `grain_size` `(` $grain_size `:` type($grain_size) `)`
+  }];
+
+  let description = [{
+    If a `grainsize` clause is present, the number of logical loop iterations
+    assigned to each generated task is greater than or equal to the minimum of
+    the value of the grain-size expression and the number of logical loop
+    iterations, but less than two times the value of the grain-size expression.
+  }];
+}
+
+def OpenMP_GrainsizeClause : OpenMP_GrainsizeClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.4.9] `has_device_addr` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_HasDeviceAddrClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$has_device_addr
+  );
+
+  let assemblyFormat = [{
+    `has_device_addr` `(` $has_device_addr `:` type($has_device_addr) `)`
+  }];
+
+  let description = [{
+    The optional `has_device_addr` indicates that list items already have device
+    addresses, so they may be directly accessed from the target device. This
+    includes array sections.
+  }];
+}
+
+def OpenMP_HasDeviceAddrClause : OpenMP_HasDeviceAddrClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [15.1.2] `hint` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_HintClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    DefaultValuedOptionalAttr<I64Attr, "0">:$hint_val
+  );
+
+  let assemblyFormat = [{
+    `hint` `(` custom<SynchronizationHint>($hint_val) `)`
+  }];
+
+  let description = [{
+    `hint` is the value of hint (as specified in the hint clause). It is a
+    compile time constant. As the name suggests, this is just a hint for
+    optimization.
+  }];
+}
+
+def OpenMP_HintClause : OpenMP_HintClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [3.4] `if` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_IfClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Optional<I1>:$if_expr
+  );
+
+  let assemblyFormat = [{
+    `if` `(` $if_expr `)`
+  }];
+
+  // Description varies depending on the operation.
+}
+
+def OpenMP_IfClause : OpenMP_IfClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.5.10] `in_reduction` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_InReductionClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let traits = [
+    ReductionClauseInterface
+  ];
+
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$in_reduction_vars,
+    OptionalAttr<SymbolRefArrayAttr>:$in_reductions
+  );
+
+  let assemblyFormat = [{
+    `in_reduction` `(`
+      custom<ReductionVarList>($in_reduction_vars, type($in_reduction_vars),
+                               $in_reductions) `)`
+  }];
+
+  let extraClassDeclaration = [{
+    /// Returns the reduction variables.
+    SmallVector<Value> getReductionVars() {
+      return SmallVector<Value>(getInReductionVars().begin(),
+                                getInReductionVars().end());
+    }
+  }];
+
+  // Description varies depending on the operation.
+}
+
+def OpenMP_InReductionClause : OpenMP_InReductionClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.4.7] `is_device_ptr` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_IsDevicePtrClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<OpenMP_PointerLikeType>:$is_device_ptr
+  );
+
+  let assemblyFormat = [{
+    `is_device_ptr` `(` $is_device_ptr `:` type($is_device_ptr) `)`
+  }];
+
+  let description = [{
+    The optional `is_device_ptr` indicates list items are device pointers.
+  }];
+}
+
+def OpenMP_IsDevicePtrClause : OpenMP_IsDevicePtrClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.4.6] `linear` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_LinearClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat = false,
+    bit description = false, bit extraClassDeclaration = false
+  > : OpenMP_Clause</*isRequired=*/false, traits, arguments, assemblyFormat,
+                    description, extraClassDeclaration> {
+  let arguments = (ins
+    Variadic<AnyType>:$linear_vars,
+    Variadic<I32>:$linear_step_vars
+  );
+
+  let assemblyFormat = [{
+    `linear` `(`
+      custom<LinearClause>($linear_vars, type($linear_vars),
+                           $linear_step_vars) `)`
+  }];
+
+  let description = [{
+    The `linear_step_vars` operand additionally specifies the step for each
+    associated linear operand. Note that the `linear_vars` and
+    `linear_step_vars` variadic lists should contain the same number of
+    elements.
+  }];
+}
+
+def OpenMP_LinearClause : OpenMP_LinearClauseSkip<>;
+
+//===----------------------------------------------------------------------===//
+// V5.2: [5.8.3] `map` clause
+//===----------------------------------------------------------------------===//
+
+class OpenMP_MapClauseSkip<
+    bit traits = false, bit arguments = false, bit assemblyFormat =...
[truncated]

@skatrak skatrak force-pushed the users/skatrak/mlir-clauses-02-base branch from fec244f to 7800cd0 Compare May 20, 2024 13:40
@skatrak skatrak force-pushed the users/skatrak/mlir-clauses-03-clausedefs branch from e1aa6cb to 7466061 Compare May 20, 2024 13:40
Copy link
Contributor

@tblah tblah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the refactoring.

@skatrak skatrak force-pushed the users/skatrak/mlir-clauses-02-base branch from 95f1a81 to 5c766ac Compare June 12, 2024 11:41
Base automatically changed from users/skatrak/mlir-clauses-02-base to main June 12, 2024 12:26
@skatrak skatrak force-pushed the users/skatrak/mlir-clauses-03-clausedefs branch from 7466061 to 1496299 Compare June 12, 2024 13:17
Copy link
Contributor

@bhandarkar-pranav bhandarkar-pranav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - just a couple style questions

@skatrak
Copy link
Member Author

skatrak commented Jun 13, 2024

Thank you @bhandarkar-pranav for taking a look! Since both of your comments are related, I'll try to explain the reasoning here. Hopefully it makes sense to you.

Basically the idea is that we want to have defs for each clause that do not skip anything, which will be the main ones used while defining operations, but we also want the ability to skip parts of them in a very small amount of edge cases. That's what the separation is for, which I think we are both onboard with.

Then there is the definition of the OpenMP_XyzClauseSkip classes, which is the one that seems to be causing the confusion. How these are supposed to be read is "An Xyz clause skipping the following fields: ...". So, when we do def OpenMP_XyzClause : OpenMP_XyzClauseSkip<> we're saying: "Define an Xyz clause skipping none of the fields". I think this is more readable especially when actually skipping fields while defining operations. For example:

def TaskloopOp : OpenMP_Op<"taskloop", traits = [ ... ],
    clauses = [ OpenMP_ReductionClauseSkip<extraClassDeclaration = true, ...> ]> { ... }

In that case, we're saying that the omp.taskloop operation takes a reduction clause but we want to skip the extraClassDeclaration field (and possibly others) inherited from it.

I think keeping the "skip" prefix on the template parameters would make things redundant (e.g. OpenMP_XyzClauseSkip<skipDescription = true>). Alternatively, we could make the base class use the regular clause name: OpenMP_XyzClause<skipDescription = true>, which was my first idea. The disadvantage of this is that then we'd have two options that in my opinion would be worse because they make the much more common case more verbose:

  • Renaming the definition that includes every field into something like OpenMP_XyzClause{Base,Default,NoSkip}.
  • Instantiating the template directly in the clause list every time: traits = [ OpenMP_Xyz1Clause<>, OpenMP_Xyz2Clause<skipDescription = true> ]

In the end, I thought that traits = [ OpenMP_Xyz1Clause, OpenMP_Xyz2ClauseSkip<description = true> ] was the most readable alternative of the options I considered.

@bhandarkar-pranav
Copy link
Contributor

Thank you @bhandarkar-pranav for taking a look! Since both of your comments are related, I'll try to explain the reasoning here. Hopefully it makes sense to you.

Basically the idea is that we want to have defs for each clause that do not skip anything, which will be the main ones used while defining operations, but we also want the ability to skip parts of them in a very small amount of edge cases. That's what the separation is for, which I think we are both onboard with.

Then there is the definition of the OpenMP_XyzClauseSkip classes, which is the one that seems to be causing the confusion. How these are supposed to be read is "An Xyz clause skipping the following fields: ...". So, when we do def OpenMP_XyzClause : OpenMP_XyzClauseSkip<> we're saying: "Define an Xyz clause skipping none of the fields". I think this is more readable especially when actually skipping fields while defining operations. For example:

def TaskloopOp : OpenMP_Op<"taskloop", traits = [ ... ],
    clauses = [ OpenMP_ReductionClauseSkip<extraClassDeclaration = true, ...> ]> { ... }

In that case, we're saying that the omp.taskloop operation takes a reduction clause but we want to skip the extraClassDeclaration field (and possibly others) inherited from it.

I think keeping the "skip" prefix on the template parameters would make things redundant (e.g. OpenMP_XyzClauseSkip<skipDescription = true>). Alternatively, we could make the base class use the regular clause name: OpenMP_XyzClause<skipDescription = true>, which was my first idea. The disadvantage of this is that then we'd have two options that in my opinion would be worse because they make the much more common case more verbose:

  • Renaming the definition that includes every field into something like OpenMP_XyzClause{Base,Default,NoSkip}.
  • Instantiating the template directly in the clause list every time: traits = [ OpenMP_Xyz1Clause<>, OpenMP_Xyz2Clause<skipDescription = true> ]

In the end, I thought that traits = [ OpenMP_Xyz1Clause, OpenMP_Xyz2ClauseSkip<description = true> ] was the most readable alternative of the options I considered.

Thank you, this makes sense.

Copy link
Contributor

@mjklemm mjklemm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@skatrak skatrak force-pushed the users/skatrak/mlir-clauses-03-clausedefs branch from 1496299 to 0e0d66e Compare June 28, 2024 14:55
This patch adds a new tablegen file for the OpenMP dialect containing the list
of clauses currently supported.
@skatrak skatrak force-pushed the users/skatrak/mlir-clauses-03-clausedefs branch from 0e0d66e to bd17957 Compare July 1, 2024 09:26
@skatrak skatrak merged commit 3e168f5 into main Jul 1, 2024
7 checks passed
@skatrak skatrak deleted the users/skatrak/mlir-clauses-03-clausedefs branch July 1, 2024 10:06
lravenclaw pushed a commit to lravenclaw/llvm-project that referenced this pull request Jul 3, 2024
This patch adds a new tablegen file for the OpenMP dialect containing
the list of clauses currently supported.
kbluck pushed a commit to kbluck/llvm-project that referenced this pull request Jul 6, 2024
This patch adds a new tablegen file for the OpenMP dialect containing
the list of clauses currently supported.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants