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 @@ -315,4 +315,34 @@ let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?"; } +//===----------------------------------------------------------------------===// +// 2.14.1. Init Directive +//===----------------------------------------------------------------------===// + +def OpenACC_InitOp : OpenACC_Op<"init", [AttrSizedOperandSegments]> { + let summary = "init operation"; + + let description = [{ + The "acc.init" operation represents the OpenACC init executable + directive. + + Example: + + ```mlir + acc.init + acc.init device_num(%dev1 : i32) + ``` + }]; + + let arguments = (ins Variadic:$deviceTypeOperands, + Optional:$deviceNumOperand, + Optional:$ifCond); + + let assemblyFormat = [{ + ( `device_type` `(` $deviceTypeOperands^ `:` type($deviceTypeOperands) `)` )? + ( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )? + ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword + }]; +} + #endif // OPENACC_OPS 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 @@ -803,5 +803,20 @@ return success(); } +//===----------------------------------------------------------------------===// +// InitOp +//===----------------------------------------------------------------------===// + +static LogicalResult verify(acc::InitOp initOp) { + Operation *currOp = initOp; + while ((currOp = currOp->getParentOp())) { + if (isa(currOp) || isa(currOp)) { + initOp.emitError("init op cannot be nested in a compute operation"); + return failure(); + } + } + return success(); +} + #define GET_OP_CLASSES #include "mlir/Dialect/OpenACC/OpenACCOps.cpp.inc" diff --git a/mlir/test/Dialect/OpenACC/invalid.mlir b/mlir/test/Dialect/OpenACC/invalid.mlir --- a/mlir/test/Dialect/OpenACC/invalid.mlir +++ b/mlir/test/Dialect/OpenACC/invalid.mlir @@ -68,3 +68,17 @@ } attributes {auto_, seq} // ----- + +acc.parallel { +// expected-error@+1 {{init op cannot be nested in a compute operation}} + acc.init + acc.yield +} + +// ----- + +acc.loop { +// expected-error@+1 {{init op cannot be nested in a compute operation}} + acc.init + acc.yield +} 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 @@ -510,3 +510,31 @@ // CHECK-NEXT: } // CHECK: acc.data present([[ARGA]]: memref<10xf32>) copyin([[ARGB]]: memref<10xf32>) copyout([[ARGC]]: memref<10x10xf32>) { // CHECK-NEXT: } + +// ----- + +%i64Value = constant 1 : i64 +%i32Value = constant 1 : i32 +%i32Value2 = constant 2 : i32 +%idxValue = constant 1 : index +%ifCond = constant true +acc.init +acc.init device_type(%i32Value : i32) +acc.init device_type(%i32Value, %i32Value2 : i32, i32) +acc.init device_num(%i64Value : i64) +acc.init device_num(%i32Value : i32) +acc.init device_num(%idxValue : index) +acc.init if(%ifCond) + +// CHECK: [[I64VALUE:%.*]] = constant 1 : i64 +// CHECK: [[I32VALUE:%.*]] = constant 1 : i32 +// CHECK: [[I32VALUE2:%.*]] = constant 2 : i32 +// CHECK: [[IDXVALUE:%.*]] = constant 1 : index +// CHECK: [[IFCOND:%.*]] = constant true +// CHECK: acc.init +// CHECK: acc.init device_type([[I32VALUE]] : i32) +// CHECK: acc.init device_type([[I32VALUE]], [[I32VALUE2]] : i32, i32) +// CHECK: acc.init device_num([[I64VALUE]] : i64) +// CHECK: acc.init device_num([[I32VALUE]] : i32) +// CHECK: acc.init device_num([[IDXVALUE]] : index) +// CHECK: acc.init if([[IFCOND]])