diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 29f6d8507b73b..2e32abcc42049 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -1353,10 +1353,15 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter, Fortran::semantics::SemanticsContext &semanticsContext, Fortran::lower::StatementContext &stmtCtx, const Fortran::parser::AccClauseList &accClauseList) { - mlir::Value ifCond; + mlir::Value ifCond, async; llvm::SmallVector attachEntryOperands, createEntryOperands, copyEntryOperands, copyoutEntryOperands, dataClauseOperands; + // Async has an optional value but can be present with + // no value as well. When there is no value, the op has an attribute to + // represent the clause. + bool addAsyncAttr = false; + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); // Lower clauses values mapped to operands. @@ -1444,11 +1449,14 @@ static void genACCDataOp(Fortran::lower::AbstractConverter &converter, llvm::SmallVector operands; llvm::SmallVector operandSegments; addOperand(operands, operandSegments, ifCond); + addOperand(operands, operandSegments, async); addOperands(operands, operandSegments, dataClauseOperands); auto dataOp = createRegionOp( builder, currentLocation, operands, operandSegments); + dataOp.setAsyncAttr(addAsyncAttr); + auto insPt = builder.saveInsertionPoint(); builder.setInsertionPointAfter(dataOp); diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td index 076faa76fcd31..5960dfadbc44f 100644 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -865,6 +865,8 @@ def OpenACC_DataOp : OpenACC_Op<"data", let arguments = (ins Optional:$ifCond, + Optional:$async, + UnitAttr:$asyncAttr, Variadic:$dataClauseOperands, OptionalAttr:$defaultAttr); @@ -881,6 +883,7 @@ def OpenACC_DataOp : OpenACC_Op<"data", let assemblyFormat = [{ oilist( `if` `(` $ifCond `)` + | `async` `(` $async `:` type($async) `)` | `dataOperands` `(` $dataClauseOperands `:` type($dataClauseOperands) `)` ) $region attr-dict-with-keyword diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp index 77de45281170e..2ac6899ae7ab8 100644 --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -867,6 +867,7 @@ unsigned DataOp::getNumDataOperands() { return getDataClauseOperands().size(); } Value DataOp::getDataOperand(unsigned i) { unsigned numOptional = getIfCond() ? 1 : 0; + numOptional += getAsync() ? 1 : 0; return getOperand(numOptional + i); } diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir index e07ab8c3d31f2..a1f94323864d6 100644 --- a/mlir/test/Dialect/OpenACC/ops.mlir +++ b/mlir/test/Dialect/OpenACC/ops.mlir @@ -814,6 +814,14 @@ func.func @testdataop(%a: memref, %b: memref, %c: memref) -> () { acc.data { } attributes { defaultAttr = #acc } + + acc.data { + } attributes { defaultAttr = #acc, async } + + %a1 = arith.constant 1 : i64 + acc.data async(%a1 : i64) { + } attributes { defaultAttr = #acc, async } + return } @@ -913,6 +921,12 @@ func.func @testdataop(%a: memref, %b: memref, %c: memref) -> () { // CHECK: acc.data { // CHECK-NEXT: } attributes {defaultAttr = #acc} +// CHECK: acc.data { +// CHECK-NEXT: } attributes {async, defaultAttr = #acc} + +// CHECK: acc.data async(%{{.*}} : i64) { +// CHECK-NEXT: } attributes {async, defaultAttr = #acc} + // ----- func.func @testupdateop(%a: memref, %b: memref, %c: memref) -> () {