diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td index 41cec89fdf598..3ad8e4f9ccbeb 100644 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -2127,6 +2127,11 @@ def OpenACC_LoopOp : OpenACC_Op<"loop", /// Used to retrieve the block inside the op's region. Block &getBody() { return getLoopRegions().front()->front(); } + /// Used to determine if this operation is merely a container for a loop + /// operation instead of being loop-like itself. + bool isLoopLike() { return !getLowerbound().empty(); } + bool isContainerLike() { return !isLoopLike(); } + /// Return true if the op has the auto attribute for the /// mlir::acc::DeviceType::None device_type. bool hasAuto(); @@ -2197,7 +2202,7 @@ def OpenACC_LoopOp : OpenACC_Op<"loop", let hasCustomAssemblyFormat = 1; let assemblyFormat = [{ - custom($combined) + ( `combined` `(` custom($combined)^ `)` )? oilist( `gang` `` custom($gangOperands, type($gangOperands), $gangOperandsArgType, $gangOperandsDeviceType, diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp index c4cc560e42f6a..a7b01abe34e03 100644 --- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp +++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp @@ -1686,25 +1686,19 @@ static void printDeviceTypeOperandsWithKeywordOnly( static ParseResult parseCombinedConstructsLoop(mlir::OpAsmParser &parser, mlir::acc::CombinedConstructsTypeAttr &attr) { - if (succeeded(parser.parseOptionalKeyword("combined"))) { - if (parser.parseLParen()) - return failure(); - if (succeeded(parser.parseOptionalKeyword("kernels"))) { - attr = mlir::acc::CombinedConstructsTypeAttr::get( - parser.getContext(), mlir::acc::CombinedConstructsType::KernelsLoop); - } else if (succeeded(parser.parseOptionalKeyword("parallel"))) { - attr = mlir::acc::CombinedConstructsTypeAttr::get( - parser.getContext(), mlir::acc::CombinedConstructsType::ParallelLoop); - } else if (succeeded(parser.parseOptionalKeyword("serial"))) { - attr = mlir::acc::CombinedConstructsTypeAttr::get( - parser.getContext(), mlir::acc::CombinedConstructsType::SerialLoop); - } else { - parser.emitError(parser.getCurrentLocation(), - "expected compute construct name"); - return failure(); - } - if (parser.parseRParen()) - return failure(); + if (succeeded(parser.parseOptionalKeyword("kernels"))) { + attr = mlir::acc::CombinedConstructsTypeAttr::get( + parser.getContext(), mlir::acc::CombinedConstructsType::KernelsLoop); + } else if (succeeded(parser.parseOptionalKeyword("parallel"))) { + attr = mlir::acc::CombinedConstructsTypeAttr::get( + parser.getContext(), mlir::acc::CombinedConstructsType::ParallelLoop); + } else if (succeeded(parser.parseOptionalKeyword("serial"))) { + attr = mlir::acc::CombinedConstructsTypeAttr::get( + parser.getContext(), mlir::acc::CombinedConstructsType::SerialLoop); + } else { + parser.emitError(parser.getCurrentLocation(), + "expected compute construct name"); + return failure(); } return success(); } @@ -1715,13 +1709,13 @@ printCombinedConstructsLoop(mlir::OpAsmPrinter &p, mlir::Operation *op, if (attr) { switch (attr.getValue()) { case mlir::acc::CombinedConstructsType::KernelsLoop: - p << "combined(kernels)"; + p << "kernels"; break; case mlir::acc::CombinedConstructsType::ParallelLoop: - p << "combined(parallel)"; + p << "parallel"; break; case mlir::acc::CombinedConstructsType::SerialLoop: - p << "combined(serial)"; + p << "serial"; break; }; } @@ -2304,6 +2298,14 @@ LogicalResult checkDeviceTypes(mlir::ArrayAttr deviceTypes) { } LogicalResult acc::LoopOp::verify() { + if (getUpperbound().size() != getStep().size()) + return emitError() << "number of upperbounds expected to be the same as " + "number of steps"; + + if (getUpperbound().size() != getLowerbound().size()) + return emitError() << "number of upperbounds expected to be the same as " + "number of lowerbounds"; + if (!getUpperbound().empty() && getInclusiveUpperbound() && (getUpperbound().size() != getInclusiveUpperbound()->size())) return emitError() << "inclusiveUpperbound size is expected to be the same" @@ -2421,6 +2423,15 @@ LogicalResult acc::LoopOp::verify() { if (getRegion().empty()) return emitError("expected non-empty body."); + // When it is container-like - it is expected to hold a loop-like operation. + // TODO: Get the collapse attribute into account. + if (isContainerLike()) { + // TODO: Ensure there is a single loop-like operation at any one level. + auto loopLikeOps = getRegion().getOps(); + if (loopLikeOps.empty()) + return emitError("expected to hold a loop-like operation."); + } + return success(); }