patterns.add<LegalizeDataOpForLLVMTranslation<acc::DataOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::EnterDataOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::ExitDataOp>>(converter);
+ patterns.add<LegalizeDataOpForLLVMTranslation<acc::ParallelOp>>(converter);
patterns.add<LegalizeDataOpForLLVMTranslation<acc::UpdateOp>>(converter);
}
allDataOperandsAreConverted(op.detachOperands());
});
+ target.addDynamicallyLegalOp<acc::ParallelOp>(
+ [allDataOperandsAreConverted](acc::ParallelOp op) {
+ return allDataOperandsAreConverted(op.reductionOperands()) &&
+ 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()) &&
+ allDataOperandsAreConverted(op.gangPrivateOperands()) &&
+ allDataOperandsAreConverted(op.gangFirstPrivateOperands());
+ });
+
target.addDynamicallyLegalOp<acc::UpdateOp>(
[allDataOperandsAreConverted](acc::UpdateOp op) {
return allDataOperandsAreConverted(op.hostOperands()) &&
op->getAttrs(), ParallelOp::getOperandSegmentSizeAttr());
}
+unsigned ParallelOp::getNumDataOperands() {
+ return reductionOperands().size() + copyOperands().size() +
+ copyinOperands().size() + copyinReadonlyOperands().size() +
+ copyoutOperands().size() + copyoutZeroOperands().size() +
+ createOperands().size() + createZeroOperands().size() +
+ noCreateOperands().size() + presentOperands().size() +
+ devicePtrOperands().size() + attachOperands().size() +
+ gangPrivateOperands().size() + gangFirstPrivateOperands().size();
+}
+
+Value ParallelOp::getDataOperand(unsigned i) {
+ unsigned numOptional = async() ? 1 : 0;
+ numOptional += numGangs() ? 1 : 0;
+ numOptional += numWorkers() ? 1 : 0;
+ numOptional += vectorLength() ? 1 : 0;
+ numOptional += ifCond() ? 1 : 0;
+ numOptional += selfCond() ? 1 : 0;
+ return getOperand(waitOperands().size() + numOptional + i);
+}
+
//===----------------------------------------------------------------------===//
// LoopOp
//===----------------------------------------------------------------------===//
}
// 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)>)
+
+// -----
+
+func @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
+ acc.parallel copy(%b : memref<10xf32>) copyout(%a : memref<10xf32>) {
+ }
+ return
+}
+
+// CHECK: acc.parallel 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 @testparallelop(%a: !llvm.ptr<f32>, %b: memref<10xf32>, %c: !llvm.ptr<f32>) -> () {
+ acc.parallel copyin(%b : memref<10xf32>) deviceptr(%c: !llvm.ptr<f32>) attach(%a : !llvm.ptr<f32>) {
+ }
+ return
+}
+
+// CHECK: acc.parallel 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 @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
+ %ifCond = constant true
+ acc.parallel if(%ifCond) copyin_readonly(%b : memref<10xf32>) copyout_zero(%a : memref<10xf32>) {
+ }
+ return
+}
+
+// CHECK: acc.parallel 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 @testparallelop(%a: !llvm.ptr<f32>, %b: memref<10xf32>, %c: !llvm.ptr<f32>) -> () {
+ acc.parallel create(%b : memref<10xf32>) create_zero(%c: !llvm.ptr<f32>) no_create(%a : !llvm.ptr<f32>) {
+ }
+ return
+}
+
+// CHECK: acc.parallel 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 @testparallelop(%a: memref<10xf32>, %b: memref<10xf32>) -> () {
+ acc.parallel present(%a: memref<10xf32>, %b: memref<10xf32>) {
+ }
+ return
+}
+
+// CHECK: acc.parallel 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)>)
+
+// -----
+
+func @testparallelop(%i: i64, %a: memref<10xf32>, %b: memref<10xf32>) -> () {
+ acc.parallel num_gangs(%i: i64) present(%a: memref<10xf32>, %b: memref<10xf32>) {
+ } attributes {async}
+ return
+}
+
+// CHECK: acc.parallel num_gangs(%{{.*}}: i64) 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)>)
+// CHECK-NEXT: } attributes {async}