Fortran::semantics::SemanticsContext &semanticsContext,
Fortran::lower::StatementContext &stmtCtx,
const Fortran::parser::AccClauseList &accClauseList) {
- mlir::Value ifCond, async;
+ mlir::Value ifCond, async, waitDevnum;
llvm::SmallVector<mlir::Value> attachEntryOperands, createEntryOperands,
- copyEntryOperands, copyoutEntryOperands, dataClauseOperands;
+ copyEntryOperands, copyoutEntryOperands, dataClauseOperands, waitOperands;
- // Async has an optional value but can be present with
+ // Async and wait have 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;
+ bool addWaitAttr = false;
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
// Lower clauses values mapped to operands.
- // Keep track of each group of operands separatly as clauses can appear
+ // Keep track of each group of operands separately as clauses can appear
// more than once.
for (const Fortran::parser::AccClause &clause : accClauseList.v) {
mlir::Location clauseLocation = converter.genLocation(clause.source);
llvm::SmallVector<int32_t> operandSegments;
addOperand(operands, operandSegments, ifCond);
addOperand(operands, operandSegments, async);
+ addOperand(operands, operandSegments, waitDevnum);
+ addOperands(operands, operandSegments, waitOperands);
addOperands(operands, operandSegments, dataClauseOperands);
auto dataOp = createRegionOp<mlir::acc::DataOp, mlir::acc::TerminatorOp>(
builder, currentLocation, operands, operandSegments);
dataOp.setAsyncAttr(addAsyncAttr);
+ dataOp.setAsyncAttr(addWaitAttr);
auto insPt = builder.saveInsertionPoint();
builder.setInsertionPointAfter(dataOp);
let arguments = (ins Optional<I1>:$ifCond,
Optional<IntOrIndex>:$async,
UnitAttr:$asyncAttr,
+ Optional<IntOrIndex>:$waitDevnum,
+ Variadic<IntOrIndex>:$waitOperands,
+ UnitAttr:$waitAttr,
Variadic<OpenACC_PointerLikeTypeInterface>:$dataClauseOperands,
OptionalAttr<DefaultValueAttr>:$defaultAttr);
`if` `(` $ifCond `)`
| `async` `(` $async `:` type($async) `)`
| `dataOperands` `(` $dataClauseOperands `:` type($dataClauseOperands) `)`
+ | `wait_devnum` `(` $waitDevnum `:` type($waitDevnum) `)`
+ | `wait` `(` $waitOperands `:` type($waitOperands) `)`
)
$region attr-dict-with-keyword
}];
acc.data async(%a1 : i64) {
} attributes { defaultAttr = #acc<defaultvalue none>, async }
+ acc.data {
+ } attributes { defaultAttr = #acc<defaultvalue none>, wait }
+
+ %w1 = arith.constant 1 : i64
+ acc.data wait(%w1 : i64) {
+ } attributes { defaultAttr = #acc<defaultvalue none>, wait }
+
+ %wd1 = arith.constant 1 : i64
+ acc.data wait_devnum(%wd1 : i64) wait(%w1 : i64) {
+ } attributes { defaultAttr = #acc<defaultvalue none>, wait }
+
return
}
// CHECK: acc.data async(%{{.*}} : i64) {
// CHECK-NEXT: } attributes {async, defaultAttr = #acc<defaultvalue none>}
+// CHECK: acc.data {
+// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>, wait}
+
+// CHECK: acc.data wait(%{{.*}} : i64) {
+// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>, wait}
+
+// CHECK: acc.data wait_devnum(%{{.*}} : i64) wait(%{{.*}} : i64) {
+// CHECK-NEXT: } attributes {defaultAttr = #acc<defaultvalue none>, wait}
+
// -----
func.func @testupdateop(%a: memref<f32>, %b: memref<f32>, %c: memref<f32>) -> () {