[Mlir-commits] [mlir] [openacc][openmp] Add dialect representation for acc atomic operations (PR #65493)

Slava Zakharin llvmlistbot at llvm.org
Wed Sep 6 08:25:50 PDT 2023


================
@@ -0,0 +1,321 @@
+//===- DirectiveAtomicInterfaces.td - atomic interfaces ----*- 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines the operation interface for atomic operations used in OpenACC and 
+// OpenMP.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OPENACC_MP_COMMON_INTERFACES_ATOMICINTERFACES
+#define OPENACC_MP_COMMON_INTERFACES_ATOMICINTERFACES
+
+include "mlir/IR/OpBase.td"
+include "mlir/Interfaces/ControlFlowInterfaces.td"
+
+def AtomicReadOpInterface : OpInterface<"AtomicReadOpInterface"> {
+  let description = [{
+    This interface is used for OpenACC/OpenMP dialect operation that performs an
+    atomic read.
+
+    The interface terminology uses `x` and `v` like the directive
+    specifications:
+      `v = x;`
+    `x` is the address from where the value is atomically read.
+    `v` is the address where the value is stored after reading.
+  }];
+  let cppNamespace = "::mlir::accomp";
+
+  let methods = [
+    InterfaceMethod<[{
+        Common verifier for operation that implements atomic read interface.
+      }],
+      /*retTy=*/"::mlir::LogicalResult",
+      /*methodName=*/"verifyCommon",
+      /*args=*/(ins),
+      /*methodBody=*/"",
+      /*defaultImplementation=*/[{
+        if ($_op.getX() == $_op.getV()) {
+          return $_op.emitError(
+            "read and write must not be to the same location for atomic reads");
+        }
+        return mlir::success();
+      }]
+    >,
+    InterfaceMethod<[{
+        Obtains `x` which is the address from where the value is atomically
+        read.
+      }],
+      /*retTy=*/"::mlir::Value",
+      /*methodName=*/"getX",
+      /*args=*/(ins)
+    >,
+    InterfaceMethod<[{
+        Obtains `v` which is the address where the value is stored after
+        reading.
+      }],
+      /*retTy=*/"::mlir::Value",
+      /*methodName=*/"getV",
+      /*args=*/(ins)
+    >,
+  ];
+}
+
+def AtomicWriteOpInterface : OpInterface<"AtomicWriteOpInterface"> {
+  let description = [{
+    This interface is used for OpenACC/OpenMP dialect operation that performs an
+    atomic write.
+
+    The interface terminology uses `x` and `expr` like the directive
+    specifications:
+      `x = expr;`
+    `x` is the address to where the `expr` is atomically written.
+  }];
+  let cppNamespace = "::mlir::accomp";
+
+  let methods = [
+    InterfaceMethod<[{
+        Common verifier for operation that implements atomic write interface.
+      }],
+      /*retTy=*/"::mlir::LogicalResult",
+      /*methodName=*/"verifyCommon",
+      /*args=*/(ins),
+      /*methodBody=*/"",
+      /*defaultImplementation=*/[{
+        mlir::Type elementType = $_op.getX().getType().getElementType();
+        if (elementType && elementType != $_op.getExpr().getType())
+          return $_op.emitError("address must dereference to value type");
+        return mlir::success();
+      }]
+    >,
+    InterfaceMethod<[{
+        Obtains `x` which is the address to which the value is atomically
+        written to.
+      }],
+      /*retTy=*/"::mlir::Value",
+      /*methodName=*/"getX",
+      /*args=*/(ins)
+    >,
+    InterfaceMethod<[{
+        Obtains `expr` which corresponds to the expression whose value is
+        written to `x`.
+      }],
+      /*retTy=*/"::mlir::Value",
+      /*methodName=*/"getExpr",
+      /*args=*/(ins)
+    >,
+  ];
+}
+
+def AtomicUpdateOpInterface : OpInterface<"AtomicUpdateOpInterface"> {
+  let description = [{
+    This interface is used for OpenACC/OpenMP dialect operation that performs an
+    atomic update.
+
+    The interface terminology uses `x` to specify the address where a value
+    is atomically written/read.
+    
+    Since atomic update expression comes in many forms, this interface requires
+    that the operation uses a region with a single argument to capture the
+    expression.
+
+    The region describes how to update the value of `x`. It takes the value at
+    `x` as an input and must yield the updated value. Only the update to `x` is
+    atomic. Generally the region must have only one instruction, but can
+    potentially have more than one instructions too. The update is sematically
+    similar to a compare-exchange loop based atomic update.
+  }];
+  let cppNamespace = "::mlir::accomp";
+
+  let methods = [
+    InterfaceMethod<[{
+        Obtains `x` which is the address to which the value is atomically
+        written to / read from.
+      }],
+      /*retTy=*/"::mlir::Value",
+      /*methodName=*/"getX",
+      /*args=*/(ins)
+    >,
+    InterfaceMethod<[{
+        Returns true if the new value is same as old value and the operation is
----------------
vzakhari wrote:

The comment seems unrelated to the method.

https://github.com/llvm/llvm-project/pull/65493


More information about the Mlir-commits mailing list