diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -230,6 +230,15 @@ let summary = "Represents private semantics for acc private clause."; } +//===----------------------------------------------------------------------===// +// 2.5.14 firstprivate clause +//===----------------------------------------------------------------------===// +def OpenACC_FirstprivateOp : OpenACC_DataEntryOp<"firstprivate", + "mlir::acc::DataClause::acc_firstprivate"> { + let summary = "Represents firstprivate semantic for the acc firstprivate " + "clause."; +} + //===----------------------------------------------------------------------===// // 2.7.4 deviceptr clause //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -71,6 +71,16 @@ return success(); } +//===----------------------------------------------------------------------===// +// FirstprivateOp +//===----------------------------------------------------------------------===// +LogicalResult acc::FirstprivateOp::verify() { + if (getDataClause() != acc::DataClause::acc_firstprivate) + return emitError("data clause associated with firstprivate operation must " + "match its intent"); + return success(); +} + //===----------------------------------------------------------------------===// // DevicePtrOp //===----------------------------------------------------------------------===// diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir --- a/mlir/test/Dialect/OpenACC/ops.mlir +++ b/mlir/test/Dialect/OpenACC/ops.mlir @@ -584,7 +584,8 @@ } acc.serial wait(%i64value, %i32value, %idxValue : i64, i32, index) { } - acc.serial private(@privatization_memref_10_f32 -> %a : memref<10xf32>, @privatization_memref_10_10_f32 -> %c : memref<10x10xf32>) firstprivate(@firstprivatization_memref_10xf32 -> %b: memref<10xf32>) { + %firstprivate = acc.firstprivate varPtr(%b : memref<10xf32>) -> memref<10xf32> + acc.serial private(@privatization_memref_10_f32 -> %a : memref<10xf32>, @privatization_memref_10_10_f32 -> %c : memref<10x10xf32>) firstprivate(@firstprivatization_memref_10xf32 -> %firstprivate : memref<10xf32>) { } acc.serial { } attributes {defaultAttr = #acc} @@ -620,7 +621,8 @@ // CHECK-NEXT: } // CHECK: acc.serial wait([[I64VALUE]], [[I32VALUE]], [[IDXVALUE]] : i64, i32, index) { // CHECK-NEXT: } -// CHECK: acc.serial firstprivate(@firstprivatization_memref_10xf32 -> [[ARGB]] : memref<10xf32>) private(@privatization_memref_10_f32 -> [[ARGA]] : memref<10xf32>, @privatization_memref_10_10_f32 -> [[ARGC]] : memref<10x10xf32>) { +// CHECK: %[[FIRSTP:.*]] = acc.firstprivate varPtr([[ARGB]] : memref<10xf32>) -> memref<10xf32> +// CHECK: acc.serial firstprivate(@firstprivatization_memref_10xf32 -> %[[FIRSTP]] : memref<10xf32>) private(@privatization_memref_10_f32 -> [[ARGA]] : memref<10xf32>, @privatization_memref_10_10_f32 -> [[ARGC]] : memref<10x10xf32>) { // CHECK-NEXT: } // CHECK: acc.serial { // CHECK-NEXT: } attributes {defaultAttr = #acc}