[Mlir-commits] [mlir] [openacc][openmp] Add dialect representation for acc atomic operations (PR #65493)
Razvan Lupusoru
llvmlistbot at llvm.org
Wed Sep 6 09:06:01 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
----------------
razvanlupusoru wrote:
Great catch.
https://github.com/llvm/llvm-project/pull/65493
More information about the Mlir-commits
mailing list