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 @@ -318,6 +318,36 @@ 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 + }]; +} + //===----------------------------------------------------------------------===// // 2.14.4. Update Directive //===----------------------------------------------------------------------===// 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 @@ -648,6 +648,19 @@ return success(); } +//===----------------------------------------------------------------------===// +// InitOp +//===----------------------------------------------------------------------===// + +static LogicalResult verify(acc::InitOp initOp) { + Operation *currOp = initOp; + while ((currOp = currOp->getParentOp())) { + if (isa(currOp) || isa(currOp)) + return initOp.emitOpError("cannot be nested in a compute operation"); + } + return success(); +} + //===----------------------------------------------------------------------===// // UpdateOp //===----------------------------------------------------------------------===// 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 @@ -111,3 +111,19 @@ %cst = constant 1 : index // expected-error@+1 {{async attribute cannot appear with asyncOperand}} acc.wait async(%cst: index) attributes {async} + +// ----- + +acc.parallel { +// expected-error@+1 {{'acc.init' op cannot be nested in a compute operation}} + acc.init + acc.yield +} + +// ----- + +acc.loop { +// expected-error@+1 {{'acc.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 @@ -592,3 +592,31 @@ // CHECK: acc.wait attributes {async} // CHECK: acc.wait([[I64VALUE]] : i64) async([[IDXVALUE]] : index) wait_devnum([[I32VALUE]] : i32) // CHECK: acc.wait if([[IFCOND]]) + +// ----- + +%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]])