Skip to content

[mlir][acc] Simplify data entry/exit operation builders #114880

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
Nov 5, 2024

Conversation

razvanlupusoru
Copy link
Contributor

Add new builders to DataBoundsOp, data entry ops, and data exit ops to simplify their construction since many of their inputs are optional. Additionally, small refactoring was needed for data exit ops to reduce duplication. Unit tests were added to exercise the new builders.

Add new builders to DataBoundsOp, data entry ops, and data exit ops
to simplify their construction since many of their inputs are optional.
Additionally, small refactoring was needed for data exit ops to
reduce duplication. Unit tests were added to exercise the new builders.
@llvmbot
Copy link
Member

llvmbot commented Nov 4, 2024

@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-openacc

@llvm/pr-subscribers-mlir-openacc

Author: Razvan Lupusoru (razvanlupusoru)

Changes

Add new builders to DataBoundsOp, data entry ops, and data exit ops to simplify their construction since many of their inputs are optional. Additionally, small refactoring was needed for data exit ops to reduce duplication. Unit tests were added to exercise the new builders.


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

2 Files Affected:

  • (modified) mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td (+138-58)
  • (modified) mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp (+170-2)
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
index e305e2fbde5b17..aaf8feb29401c6 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
@@ -347,6 +347,24 @@ def OpenACC_DataBoundsOp : OpenACC_Op<"bounds",
   }];
 
   let hasVerifier = 1;
+
+  let builders = [
+    OpBuilder<(ins "::mlir::Value":$extent), [{
+        build($_builder, $_state,
+          ::mlir::acc::DataBoundsType::get($_builder.getContext()),
+          /*lowerbound=*/{}, /*upperbound=*/{}, extent,
+          /*stride=*/{}, /*strideInBytes=*/nullptr, /*startIdx=*/{});
+      }]
+    >,
+    OpBuilder<(ins "::mlir::Value":$lowerbound,
+                   "::mlir::Value":$upperbound), [{
+        build($_builder, $_state,
+          ::mlir::acc::DataBoundsType::get($_builder.getContext()),
+          lowerbound, upperbound, /*extent=*/{},
+          /*stride=*/{}, /*strideInBytes=*/nullptr, /*startIdx=*/{});
+      }]
+    >
+  ];
 }
 
 // Data entry operation does not refer to OpenACC spec terminology, but to
@@ -450,6 +468,33 @@ class OpenACC_DataEntryOp<string mnemonic, string clause, string extraDescriptio
   }];
 
   let hasVerifier = 1;
+
+  let builders = [
+    OpBuilder<(ins "::mlir::Value":$varPtr,
+      "bool":$structured,
+      "bool":$implicit,
+      CArg<"::mlir::ValueRange", "{}">:$bounds), [{
+        build($_builder, $_state, varPtr.getType(), varPtr, /*varPtrPtr=*/{},
+          bounds, /*asyncOperands=*/{}, /*asyncOperandsDeviceType=*/nullptr,
+          /*asyncOnly=*/nullptr, /*dataClause=*/nullptr,
+          /*structured=*/$_builder.getBoolAttr(structured),
+          /*implicit=*/$_builder.getBoolAttr(implicit), /*name=*/nullptr);
+      }]
+    >,
+    OpBuilder<(ins "::mlir::Value":$varPtr,
+      "bool":$structured,
+      "bool":$implicit,
+      "const ::llvm::Twine &":$name,
+      CArg<"::mlir::ValueRange", "{}">:$bounds), [{
+        build($_builder, $_state, varPtr.getType(), varPtr, /*varPtrPtr=*/{},
+          bounds, /*asyncOperands=*/{}, /*asyncOperandsDeviceType=*/nullptr,
+          /*asyncOnly=*/nullptr, /*dataClause=*/nullptr,
+          /*structured=*/$_builder.getBoolAttr(structured),
+          /*implicit=*/$_builder.getBoolAttr(implicit),
+          /*name=*/$_builder.getStringAttr(name));
+      }]
+    >
+  ];
 }
 
 //===----------------------------------------------------------------------===//
@@ -762,23 +807,13 @@ class OpenACC_DataExitOp<string mnemonic, string clause, string extraDescription
   let hasVerifier = 1;
 }
 
-//===----------------------------------------------------------------------===//
-// 2.7.8 copyout clause
-//===----------------------------------------------------------------------===//
-def OpenACC_CopyoutOp : OpenACC_DataExitOp<"copyout",
-    "mlir::acc::DataClause::acc_copyout",
-    "- `varPtr`: The address of variable to copy back to.",
-    [MemoryEffects<[MemRead<OpenACC_RuntimeCounters>,
-                    MemWrite<OpenACC_RuntimeCounters>]>],
-    (ins Arg<OpenACC_PointerLikeTypeInterface,"Address of device variable",[MemRead]>:$accPtr,
-         Arg<OpenACC_PointerLikeTypeInterface,"Address of variable",[MemWrite]>:$varPtr)> {
-  let summary = "Represents acc copyout semantics - reverse of copyin.";
-
-  let extraClassDeclaration = extraClassDeclarationBase # [{
-    /// Check if this is a copyout with zero modifier.
-    bool isCopyoutZero();
-  }];
-
+class OpenACC_DataExitOpWithVarPtr<string mnemonic, string clause> :
+    OpenACC_DataExitOp<mnemonic, clause,
+      "- `varPtr`: The address of variable to copy back to.",
+      [MemoryEffects<[MemRead<OpenACC_RuntimeCounters>,
+                      MemWrite<OpenACC_RuntimeCounters>]>],
+      (ins Arg<OpenACC_PointerLikeTypeInterface,"Address of device variable",[MemRead]>:$accPtr,
+           Arg<OpenACC_PointerLikeTypeInterface,"Address of variable",[MemWrite]>:$varPtr)> {
   let assemblyFormat = [{
     `accPtr` `(` $accPtr `:` type($accPtr) `)`
     (`bounds` `(` $bounds^ `)` )?
@@ -787,20 +822,42 @@ def OpenACC_CopyoutOp : OpenACC_DataExitOp<"copyout",
     `to` `varPtr` `(` $varPtr `:` type($varPtr) `)`
     attr-dict
   }];
+
+  let builders = [
+    OpBuilder<(ins "::mlir::Value":$accPtr,
+      "::mlir::Value":$varPtr,
+      "bool":$structured,
+      "bool":$implicit,
+      CArg<"::mlir::ValueRange", "{}">:$bounds), [{
+        build($_builder, $_state, accPtr, varPtr,
+          bounds, /*asyncOperands=*/{}, /*asyncOperandsDeviceType=*/nullptr,
+          /*asyncOnly=*/nullptr, /*dataClause=*/nullptr,
+          /*structured=*/$_builder.getBoolAttr(structured),
+          /*implicit=*/$_builder.getBoolAttr(implicit), /*name=*/nullptr);
+      }]
+    >,
+    OpBuilder<(ins "::mlir::Value":$accPtr,
+      "::mlir::Value":$varPtr,
+      "bool":$structured,
+      "bool":$implicit,
+      "const ::llvm::Twine &":$name,
+      CArg<"::mlir::ValueRange", "{}">:$bounds), [{
+        build($_builder, $_state, accPtr, varPtr,
+          bounds, /*asyncOperands=*/{}, /*asyncOperandsDeviceType=*/nullptr,
+          /*asyncOnly=*/nullptr, /*dataClause=*/nullptr,
+          /*structured=*/$_builder.getBoolAttr(structured),
+          /*implicit=*/$_builder.getBoolAttr(implicit),
+          /*name=*/$_builder.getStringAttr(name));
+      }]
+    >
+  ];
 }
 
-//===----------------------------------------------------------------------===//
-// 2.7.11 delete clause
-//===----------------------------------------------------------------------===//
-def OpenACC_DeleteOp : OpenACC_DataExitOp<"delete",
-    "mlir::acc::DataClause::acc_delete", "",
-    [MemoryEffects<[MemRead<OpenACC_RuntimeCounters>,
+class OpenACC_DataExitOpNoVarPtr<string mnemonic, string clause> :
+    OpenACC_DataExitOp<mnemonic, clause, "",
+      [MemoryEffects<[MemRead<OpenACC_RuntimeCounters>,
                     MemWrite<OpenACC_RuntimeCounters>]>],
-    (ins Arg<OpenACC_PointerLikeTypeInterface,"Address of device variable",[MemRead]>:$accPtr)> {
-  let summary = "Represents acc delete semantics - reverse of create.";
-
-  let extraClassDeclaration = extraClassDeclarationBase;
-
+      (ins Arg<OpenACC_PointerLikeTypeInterface,"Address of device variable",[MemRead]>:$accPtr)> {
   let assemblyFormat = [{
     `accPtr` `(` $accPtr `:` type($accPtr) `)`
     (`bounds` `(` $bounds^ `)` )?
@@ -808,39 +865,71 @@ def OpenACC_DeleteOp : OpenACC_DataExitOp<"delete",
             type($asyncOperands), $asyncOperandsDeviceType)^ `)`)?
     attr-dict
   }];
+
+  let builders = [
+    OpBuilder<(ins "::mlir::Value":$accPtr,
+      "bool":$structured,
+      "bool":$implicit,
+      CArg<"::mlir::ValueRange", "{}">:$bounds), [{
+        build($_builder, $_state, accPtr,
+          bounds, /*asyncOperands=*/{}, /*asyncOperandsDeviceType=*/nullptr,
+          /*asyncOnly=*/nullptr, /*dataClause=*/nullptr,
+          /*structured=*/$_builder.getBoolAttr(structured),
+          /*implicit=*/$_builder.getBoolAttr(implicit), /*name=*/nullptr);
+      }]
+    >,
+    OpBuilder<(ins "::mlir::Value":$accPtr,
+      "bool":$structured,
+      "bool":$implicit,
+      "const ::llvm::Twine &":$name,
+      CArg<"::mlir::ValueRange", "{}">:$bounds), [{
+        build($_builder, $_state, accPtr,
+          bounds, /*asyncOperands=*/{}, /*asyncOperandsDeviceType=*/nullptr,
+          /*asyncOnly=*/nullptr, /*dataClause=*/nullptr,
+          /*structured=*/$_builder.getBoolAttr(structured),
+          /*implicit=*/$_builder.getBoolAttr(implicit),
+          /*name=*/$_builder.getStringAttr(name));
+      }]
+    >
+  ];
 }
 
 //===----------------------------------------------------------------------===//
-// 2.7.13 detach clause
+// 2.7.8 copyout clause
 //===----------------------------------------------------------------------===//
-def OpenACC_DetachOp : OpenACC_DataExitOp<"detach",
-    "mlir::acc::DataClause::acc_detach", "",
-    [MemoryEffects<[MemRead<OpenACC_RuntimeCounters>,
-                    MemWrite<OpenACC_RuntimeCounters>]>],
-    (ins Arg<OpenACC_PointerLikeTypeInterface,"Address of device variable",[MemRead]>:$accPtr)> {
-  let summary = "Represents acc detach semantics - reverse of attach.";
+def OpenACC_CopyoutOp : OpenACC_DataExitOpWithVarPtr<"copyout",
+    "mlir::acc::DataClause::acc_copyout"> {
+  let summary = "Represents acc copyout semantics - reverse of copyin.";
 
+  let extraClassDeclaration = extraClassDeclarationBase # [{
+    /// Check if this is a copyout with zero modifier.
+    bool isCopyoutZero();
+  }];
+}
+
+//===----------------------------------------------------------------------===//
+// 2.7.11 delete clause
+//===----------------------------------------------------------------------===//
+def OpenACC_DeleteOp : OpenACC_DataExitOpNoVarPtr<"delete",
+    "mlir::acc::DataClause::acc_delete"> {
+  let summary = "Represents acc delete semantics - reverse of create.";
   let extraClassDeclaration = extraClassDeclarationBase;
+}
 
-  let assemblyFormat = [{
-    `accPtr` `(` $accPtr `:` type($accPtr) `)`
-    (`bounds` `(` $bounds^ `)` )?
-    (`async` `(` custom<DeviceTypeOperands>($asyncOperands,
-            type($asyncOperands), $asyncOperandsDeviceType)^ `)`)?
-    attr-dict
-  }];
+//===----------------------------------------------------------------------===//
+// 2.7.13 detach clause
+//===----------------------------------------------------------------------===//
+def OpenACC_DetachOp : OpenACC_DataExitOpNoVarPtr<"detach",
+    "mlir::acc::DataClause::acc_detach"> {
+  let summary = "Represents acc detach semantics - reverse of attach.";
+  let extraClassDeclaration = extraClassDeclarationBase;
 }
 
 //===----------------------------------------------------------------------===//
 // 2.14.4 host clause
 //===----------------------------------------------------------------------===//
-def OpenACC_UpdateHostOp : OpenACC_DataExitOp<"update_host",
-    "mlir::acc::DataClause::acc_update_host",
-    "- `varPtr`: The address of variable to copy back to.",
-    [MemoryEffects<[MemRead<OpenACC_RuntimeCounters>,
-                    MemWrite<OpenACC_RuntimeCounters>]>],
-    (ins Arg<OpenACC_PointerLikeTypeInterface,"Address of device variable",[MemRead]>:$accPtr,
-         Arg<OpenACC_PointerLikeTypeInterface,"Address of variable",[MemWrite]>:$varPtr)> {
+def OpenACC_UpdateHostOp : OpenACC_DataExitOpWithVarPtr<"update_host",
+    "mlir::acc::DataClause::acc_update_host"> {
   let summary = "Represents acc update host semantics.";
   let extraClassDeclaration = extraClassDeclarationBase # [{
     /// Check if this is an acc update self.
@@ -848,15 +937,6 @@ def OpenACC_UpdateHostOp : OpenACC_DataExitOp<"update_host",
       return getDataClause() == acc::DataClause::acc_update_self;
     }
   }];
-
-  let assemblyFormat = [{
-    `accPtr` `(` $accPtr `:` type($accPtr) `)`
-    (`bounds` `(` $bounds^ `)` )?
-    (`async` `(` custom<DeviceTypeOperands>($asyncOperands,
-            type($asyncOperands), $asyncOperandsDeviceType)^ `)`)?
-    `to` `varPtr` `(` $varPtr `:` type($varPtr) `)`
-    attr-dict
-  }];
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp
index 452f39d8cae9f7..fbdada9309d32c 100644
--- a/mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCOpsTest.cpp
@@ -1,4 +1,4 @@
-//===- OpenACCOpsTest.cpp - OpenACC ops extra functiosn Tests -------------===//
+//===- OpenACCOpsTest.cpp - Unit tests for OpenACC ops --------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/MemRef/IR/MemRef.h"
 #include "mlir/Dialect/OpenACC/OpenACC.h"
 #include "mlir/IR/Diagnostics.h"
 #include "mlir/IR/MLIRContext.h"
@@ -23,7 +24,8 @@ using namespace mlir::acc;
 class OpenACCOpsTest : public ::testing::Test {
 protected:
   OpenACCOpsTest() : b(&context), loc(UnknownLoc::get(&context)) {
-    context.loadDialect<acc::OpenACCDialect, arith::ArithDialect>();
+    context.loadDialect<acc::OpenACCDialect, arith::ArithDialect,
+                        memref::MemRefDialect>();
   }
 
   MLIRContext context;
@@ -436,3 +438,169 @@ TEST_F(OpenACCOpsTest, routineOpTest) {
   op->removeBindNameDeviceTypeAttr();
   op->removeBindNameAttr();
 }
+
+template <typename Op>
+void testShortDataEntryOpBuilders(OpBuilder &b, MLIRContext &context,
+                                  Location loc, DataClause dataClause) {
+  auto memrefTy = MemRefType::get({}, b.getI32Type());
+  OwningOpRef<memref::AllocaOp> varPtrOp =
+      b.create<memref::AllocaOp>(loc, memrefTy);
+
+  OwningOpRef<Op> op = b.create<Op>(loc, varPtrOp->getResult(),
+                                    /*structured=*/true, /*implicit=*/true);
+
+  EXPECT_EQ(op->getVarPtr(), varPtrOp->getResult());
+  EXPECT_EQ(op->getType(), memrefTy);
+  EXPECT_EQ(op->getDataClause(), dataClause);
+  EXPECT_TRUE(op->getImplicit());
+  EXPECT_TRUE(op->getStructured());
+  EXPECT_TRUE(op->getBounds().empty());
+  EXPECT_FALSE(op->getVarPtrPtr());
+
+  OwningOpRef<Op> op2 = b.create<Op>(loc, varPtrOp->getResult(),
+                                     /*structured=*/false, /*implicit=*/false);
+  EXPECT_FALSE(op2->getImplicit());
+  EXPECT_FALSE(op2->getStructured());
+
+  OwningOpRef<arith::ConstantIndexOp> extent =
+      b.create<arith::ConstantIndexOp>(loc, 1);
+  OwningOpRef<DataBoundsOp> bounds =
+      b.create<DataBoundsOp>(loc, extent->getResult());
+  OwningOpRef<Op> opWithBounds =
+      b.create<Op>(loc, varPtrOp->getResult(),
+                   /*structured=*/true, /*implicit=*/true, bounds->getResult());
+  EXPECT_FALSE(opWithBounds->getBounds().empty());
+  EXPECT_EQ(opWithBounds->getBounds().back(), bounds->getResult());
+
+  OwningOpRef<Op> opWithName =
+      b.create<Op>(loc, varPtrOp->getResult(),
+                   /*structured=*/true, /*implicit=*/true, "varName");
+  EXPECT_EQ(opWithName->getNameAttr().str(), "varName");
+}
+
+TEST_F(OpenACCOpsTest, shortDataEntryOpBuilder) {
+  testShortDataEntryOpBuilders<PrivateOp>(b, context, loc,
+                                          DataClause::acc_private);
+  testShortDataEntryOpBuilders<FirstprivateOp>(b, context, loc,
+                                               DataClause::acc_firstprivate);
+  testShortDataEntryOpBuilders<ReductionOp>(b, context, loc,
+                                            DataClause::acc_reduction);
+  testShortDataEntryOpBuilders<DevicePtrOp>(b, context, loc,
+                                            DataClause::acc_deviceptr);
+  testShortDataEntryOpBuilders<PresentOp>(b, context, loc,
+                                          DataClause::acc_present);
+  testShortDataEntryOpBuilders<CopyinOp>(b, context, loc,
+                                         DataClause::acc_copyin);
+  testShortDataEntryOpBuilders<CreateOp>(b, context, loc,
+                                         DataClause::acc_create);
+  testShortDataEntryOpBuilders<NoCreateOp>(b, context, loc,
+                                           DataClause::acc_no_create);
+  testShortDataEntryOpBuilders<AttachOp>(b, context, loc,
+                                         DataClause::acc_attach);
+  testShortDataEntryOpBuilders<GetDevicePtrOp>(b, context, loc,
+                                               DataClause::acc_getdeviceptr);
+  testShortDataEntryOpBuilders<UpdateDeviceOp>(b, context, loc,
+                                               DataClause::acc_update_device);
+  testShortDataEntryOpBuilders<UseDeviceOp>(b, context, loc,
+                                            DataClause::acc_use_device);
+  testShortDataEntryOpBuilders<DeclareDeviceResidentOp>(
+      b, context, loc, DataClause::acc_declare_device_resident);
+  testShortDataEntryOpBuilders<DeclareLinkOp>(b, context, loc,
+                                              DataClause::acc_declare_link);
+  testShortDataEntryOpBuilders<CacheOp>(b, context, loc, DataClause::acc_cache);
+}
+
+template <typename Op>
+void testShortDataExitOpBuilders(OpBuilder &b, MLIRContext &context,
+                                 Location loc, DataClause dataClause) {
+  auto memrefTy = MemRefType::get({}, b.getI32Type());
+  OwningOpRef<memref::AllocaOp> varPtrOp =
+      b.create<memref::AllocaOp>(loc, memrefTy);
+  OwningOpRef<GetDevicePtrOp> accPtrOp = b.create<GetDevicePtrOp>(
+      loc, varPtrOp->getResult(), /*structured=*/true, /*implicit=*/true);
+
+  OwningOpRef<Op> op =
+      b.create<Op>(loc, accPtrOp->getResult(), varPtrOp->getResult(),
+                   /*structured=*/true, /*implicit=*/true);
+
+  EXPECT_EQ(op->getVarPtr(), varPtrOp->getResult());
+  EXPECT_EQ(op->getAccPtr(), accPtrOp->getResult());
+  EXPECT_EQ(op->getDataClause(), dataClause);
+  EXPECT_TRUE(op->getImplicit());
+  EXPECT_TRUE(op->getStructured());
+  EXPECT_TRUE(op->getBounds().empty());
+
+  OwningOpRef<Op> op2 =
+      b.create<Op>(loc, accPtrOp->getResult(), varPtrOp->getResult(),
+                   /*structured=*/false, /*implicit=*/false);
+  EXPECT_FALSE(op2->getImplicit());
+  EXPECT_FALSE(op2->getStructured());
+
+  OwningOpRef<arith::ConstantIndexOp> extent =
+      b.create<arith::ConstantIndexOp>(loc, 1);
+  OwningOpRef<DataBoundsOp> bounds =
+      b.create<DataBoundsOp>(loc, extent->getResult());
+  OwningOpRef<Op> opWithBounds =
+      b.create<Op>(loc, accPtrOp->getResult(), varPtrOp->getResult(),
+                   /*structured=*/true, /*implicit=*/true, bounds->getResult());
+  EXPECT_FALSE(opWithBounds->getBounds().empty());
+  EXPECT_EQ(opWithBounds->getBounds().back(), bounds->getResult());
+
+  OwningOpRef<Op> opWithName =
+      b.create<Op>(loc, accPtrOp->getResult(), varPtrOp->getResult(),
+                   /*structured=*/true, /*implicit=*/true, "varName");
+  EXPECT_EQ(opWithName->getNameAttr().str(), "varName");
+}
+
+TEST_F(OpenACCOpsTest, shortDataExitOpBuilder) {
+  testShortDataExitOpBuilders<CopyoutOp>(b, context, loc,
+                                         DataClause::acc_copyout);
+  testShortDataExitOpBuilders<UpdateHostOp>(b, context, loc,
+                                            DataClause::acc_update_host);
+}
+
+template <typename Op>
+void testShortDataExitNoVarPtrOpBuilders(OpBuilder &b, MLIRContext &context,
+                                         Location loc, DataClause dataClause) {
+  auto memrefTy = MemRefType::get({}, b.getI32Type());
+  OwningOpRef<memref::AllocaOp> varPtrOp =
+      b.create<memref::AllocaOp>(loc, memrefTy);
+  OwningOpRef<GetDevicePtrOp> accPtrOp = b.create<GetDevicePtrOp>(
+      loc, varPtrOp->getResult(), /*structured=*/true, /*implicit=*/true);
+
+  OwningOpRef<Op> op = b.create<Op>(loc, accPtrOp->getResult(),
+                                    /*structured=*/true, /*implicit=*/true);
+
+  EXPECT_EQ(op->getAccPtr(), accPtrOp->getResult());
+  EXPECT_EQ(op->getDataClause(), dataClause);
+  EXPECT_TRUE(op->getImplicit());
+  EXPECT_TRUE(op->getStructured());
+  EXPECT_TRUE(op->getBounds().empty());
+
+  OwningOpRef<Op> op2 = b.create<Op>(loc, accPtrOp->getResult(),
+                                     /*structured=*/false, /*implicit=*/false);
+  EXPECT_FALSE(op2->getImplicit());
+  EXPECT_FALSE(op2->getStructured());
+
+  OwningOpRef<arith::ConstantIndexOp> extent =
+      b.create<arith::ConstantIndexOp>(loc, 1);
+  OwningOpRef<DataBoundsOp> bounds =
+      b.create<DataBoundsOp>(loc, extent->getResult());
+  OwningOpRef<Op> opWithBounds =
+      b.create<Op>(loc, accPtrOp->getResult(),
+                   /*structured=*/true, /*implicit=*/true, bounds->getResult());
+  EXPECT_FALSE(opWithBounds->getBounds().empty());
+  EXPECT_EQ(opWithBounds->getBounds().back(), bounds->getResult());
+
+  OwningOpRef<Op> opWithName =
+      b.create<Op>(loc, accPtrOp->getResult(),
+                   /*structured=*/true, /*implicit=*/true, "varName");
+  EXPECT_EQ(opWithName->getNameAttr().str(), "varName");
+}
+
+TEST_F(OpenACCOpsTest, shortDataExitOpNoVarPtrBuilder) {
+  testShortDataExitNoVarPtrOpBuilders<DeleteOp>(b, context, loc,
+                                                DataClause::acc_delete);
+  tes...
[truncated]

Copy link
Contributor

@clementval clementval left a comment

Choose a reason for hiding this comment

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

LGTM. Can we use these in lowering?

@razvanlupusoru
Copy link
Contributor Author

LGTM. Can we use these in lowering?

Potentially yes - but these are less useful in lowering where every argument to the builders is set up. These builders are more useful in passes which will be implemented outside of lowering such as applying "implicit data attributes" as required by OpenACC.

@razvanlupusoru razvanlupusoru merged commit dd2c0b1 into llvm:main Nov 5, 2024
12 checks passed
@clementval
Copy link
Contributor

LGTM. Can we use these in lowering?

Potentially yes - but these are less useful in lowering where every argument to the builders is set up. These builders are more useful in passes which will be implemented outside of lowering such as applying "implicit data attributes" as required by OpenACC.

It would be nice to use it here

op.setStructured(structured);
op.setImplicit(implicit);
. We could simplify the code.

PhilippRados pushed a commit to PhilippRados/llvm-project that referenced this pull request Nov 6, 2024
Add new builders to DataBoundsOp, data entry ops, and data exit ops to
simplify their construction since many of their inputs are optional.
Additionally, small refactoring was needed for data exit ops to reduce
duplication. Unit tests were added to exercise the new builders.
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.

3 participants