[mlir][openacc] Conversion of data operands in acc.data to LLVM IR dialect
authorValentin Clement <clementval@gmail.com>
Fri, 4 Jun 2021 14:25:50 +0000 (10:25 -0400)
committerclementval <clementval@gmail.com>
Fri, 4 Jun 2021 14:26:22 +0000 (10:26 -0400)
Convert data operands from the acc.data operation using the same conversion pattern than D102170.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D103332

mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td
mlir/lib/Conversion/OpenACCToLLVM/OpenACCToLLVM.cpp
mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
mlir/test/Conversion/OpenACCToLLVM/convert-data-operands-to-llvmir.mlir [moved from mlir/test/Conversion/OpenACCToLLVM/convert-standalone-data-to-llvmir.mlir with 70% similarity]

index 74f53c5..2685cdc 100644 (file)
@@ -186,6 +186,14 @@ def OpenACC_DataOp : OpenACC_Op<"data",
 
   let regions = (region AnyRegion:$region);
 
+  let extraClassDeclaration = [{
+    /// The number of data operands.
+    unsigned getNumDataOperands();
+
+    /// The i-th data operand passed.
+    Value getDataOperand(unsigned i);
+  }];
+
   let assemblyFormat = [{
     ( `if` `(` $ifCond^ `)` )?
     ( `copy` `(` $copyOperands^ `:` type($copyOperands) `)` )?
index bc60b52..eb34b0e 100644 (file)
@@ -137,6 +137,7 @@ class LegalizeDataOpForLLVMTranslation : public ConvertOpToLLVMPattern<Op> {
 
 void mlir::populateOpenACCToLLVMConversionPatterns(
     LLVMTypeConverter &converter, OwningRewritePatternList &patterns) {
+  patterns.add<LegalizeDataOpForLLVMTranslation<acc::DataOp>>(converter);
   patterns.add<LegalizeDataOpForLLVMTranslation<acc::EnterDataOp>>(converter);
   patterns.add<LegalizeDataOpForLLVMTranslation<acc::ExitDataOp>>(converter);
   patterns.add<LegalizeDataOpForLLVMTranslation<acc::UpdateOp>>(converter);
@@ -170,6 +171,21 @@ void ConvertOpenACCToLLVMPass::runOnOperation() {
     return true;
   };
 
+  target.addDynamicallyLegalOp<acc::DataOp>(
+      [allDataOperandsAreConverted](acc::DataOp op) {
+        return allDataOperandsAreConverted(op.copyOperands()) &&
+               allDataOperandsAreConverted(op.copyinOperands()) &&
+               allDataOperandsAreConverted(op.copyinReadonlyOperands()) &&
+               allDataOperandsAreConverted(op.copyoutOperands()) &&
+               allDataOperandsAreConverted(op.copyoutZeroOperands()) &&
+               allDataOperandsAreConverted(op.createOperands()) &&
+               allDataOperandsAreConverted(op.createZeroOperands()) &&
+               allDataOperandsAreConverted(op.noCreateOperands()) &&
+               allDataOperandsAreConverted(op.presentOperands()) &&
+               allDataOperandsAreConverted(op.deviceptrOperands()) &&
+               allDataOperandsAreConverted(op.attachOperands());
+      });
+
   target.addDynamicallyLegalOp<acc::EnterDataOp>(
       [allDataOperandsAreConverted](acc::EnterDataOp op) {
         return allDataOperandsAreConverted(op.copyinOperands()) &&
index 33d6c23..974e67f 100644 (file)
@@ -652,6 +652,20 @@ static LogicalResult verify(acc::DataOp dataOp) {
   return success();
 }
 
+unsigned DataOp::getNumDataOperands() {
+  return copyOperands().size() + copyinOperands().size() +
+         copyinReadonlyOperands().size() + copyoutOperands().size() +
+         copyoutZeroOperands().size() + createOperands().size() +
+         createZeroOperands().size() + noCreateOperands().size() +
+         presentOperands().size() + deviceptrOperands().size() +
+         attachOperands().size();
+}
+
+Value DataOp::getDataOperand(unsigned i) {
+  unsigned numOptional = ifCond() ? 1 : 0;
+  return getOperand(numOptional + i);
+}
+
 //===----------------------------------------------------------------------===//
 // ExitDataOp
 //===----------------------------------------------------------------------===//
@@ -108,3 +108,54 @@ func @testupdateop(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
 }
 
 // CHECK: acc.update if(%{{.*}}) host(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) device(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
+
+// -----
+
+func @testdataregion(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
+  acc.data copy(%b : memref<10xf32>) copyout(%a : memref<10xf32>) {
+  }
+  return
+}
+
+// CHECK: acc.data copy(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) copyout(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
+
+// -----
+
+func @testdataregion(%a: !llvm.ptr<f32>, %b: memref<10xf32>, %c: !llvm.ptr<f32>) -> () {
+  acc.data copyin(%b : memref<10xf32>) deviceptr(%c: !llvm.ptr<f32>) attach(%a : !llvm.ptr<f32>) {
+  }
+  return
+}
+
+// CHECK: acc.data copyin(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) deviceptr(%{{.*}} : !llvm.ptr<f32>) attach(%{{.*}} : !llvm.ptr<f32>)
+
+// -----
+
+func @testdataregion(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
+  %ifCond = constant true
+  acc.data if(%ifCond) copyin_readonly(%b : memref<10xf32>) copyout_zero(%a : memref<10xf32>) {
+  }
+  return
+}
+
+// CHECK: acc.data if(%{{.*}}) copyin_readonly(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) copyout_zero(%{{.*}} : !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)
+
+// -----
+
+func @testdataregion(%a: !llvm.ptr<f32>, %b: memref<10xf32>, %c: !llvm.ptr<f32>) -> () {
+  acc.data create(%b : memref<10xf32>) create_zero(%c: !llvm.ptr<f32>) no_create(%a : !llvm.ptr<f32>) {
+  }
+  return
+}
+
+// CHECK: acc.data create(%{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>) create_zero(%{{.*}} : !llvm.ptr<f32>) no_create(%{{.*}} : !llvm.ptr<f32>)
+
+// -----
+
+func @testdataregion(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
+  acc.data present(%a, %b : memref<10xf32>, memref<10xf32>) {
+  }
+  return
+}
+
+// CHECK: acc.data present(%{{.*}}, %{{.*}} : !llvm.struct<"openacc_data", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>, !llvm.struct<"openacc_data.1", (struct<(ptr<f32>, ptr<f32>, i64, array<1 x i64>, array<1 x i64>)>, ptr<f32>, i64)>)