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 @@ -37,7 +37,6 @@ Op { let printer = [{ return ::print(p, *this); }]; - let verifier = [{ return ::verify(*this); }]; let parser = [{ return ::parse$cppClass(parser, result); }]; } @@ -153,8 +152,6 @@ /// The i-th data operand passed. Value getDataOperand(unsigned i); }]; - - let verifier = ?; } //===----------------------------------------------------------------------===// @@ -225,6 +222,7 @@ ( `attach` `(` $attachOperands^ `:` type($attachOperands) `)` )? $region attr-dict-with-keyword }]; + let hasVerifier = 1; } def OpenACC_TerminatorOp : OpenACC_Op<"terminator", [Terminator]> { @@ -237,8 +235,6 @@ to the enclosing op. }]; - let verifier = ?; - let assemblyFormat = "attr-dict"; } @@ -292,6 +288,7 @@ }]; let hasCanonicalizer = 1; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -342,6 +339,7 @@ }]; let hasCanonicalizer = 1; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -406,8 +404,7 @@ static StringRef getPrivateKeyword() { return "private"; } static StringRef getReductionKeyword() { return "reduction"; } }]; - - let verifier = [{ return ::verifyLoopOp(*this); }]; + let hasVerifier = 1; } // Yield operation for the acc.loop and acc.parallel operations. @@ -425,8 +422,6 @@ let builders = [OpBuilder<(ins), [{ /* nothing to do */ }]>]; - let verifier = ?; - let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?"; } @@ -458,6 +453,7 @@ ( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )? ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword }]; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -488,6 +484,7 @@ ( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )? ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword }]; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -542,6 +539,7 @@ }]; let hasCanonicalizer = 1; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -575,6 +573,7 @@ ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? ( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword }]; + let hasVerifier = 1; } #endif // OPENACC_OPS diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -128,7 +128,7 @@ ]; let parser = [{ return parseParallelOp(parser, result); }]; let printer = [{ return printParallelOp(p, *this); }]; - let verifier = [{ return ::verifyParallelOp(*this); }]; + let hasVerifier = 1; } def TerminatorOp : OpenMP_Op<"terminator", [Terminator]> { @@ -217,7 +217,7 @@ let parser = [{ return parseSectionsOp(parser, result); }]; let printer = [{ return printSectionsOp(p, *this); }]; - let verifier = [{ return verifySectionsOp(*this); }]; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -336,7 +336,7 @@ }]; let parser = [{ return parseWsLoopOp(parser, result); }]; let printer = [{ return printWsLoopOp(p, *this); }]; - let verifier = [{ return ::verifyWsLoopOp(*this); }]; + let hasVerifier = 1; } def YieldOp : OpenMP_Op<"yield", @@ -457,8 +457,7 @@ let assemblyFormat = [{ $sym_name custom($hint) attr-dict }]; - - let verifier = "return verifyCriticalDeclareOp(*this);"; + let hasVerifier = 1; } @@ -476,8 +475,7 @@ let assemblyFormat = [{ (`(` $name^ `)`)? $region attr-dict }]; - - let verifier = "return ::verifyCriticalOp(*this);"; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -540,8 +538,7 @@ ( `depend_vec` `(` $depend_vec_vars^ `:` type($depend_vec_vars) `)` )? attr-dict }]; - - let verifier = "return ::verifyOrderedOp(*this);"; + let hasVerifier = 1; } def OrderedRegionOp : OpenMP_Op<"ordered_region"> { @@ -561,8 +558,7 @@ let regions = (region AnyRegion:$region); let assemblyFormat = [{ ( `simd` $simd^ )? $region attr-dict}]; - - let verifier = "return ::verifyOrderedRegionOp(*this);"; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -614,7 +610,7 @@ OptionalAttr:$memory_order); let parser = [{ return parseAtomicReadOp(parser, result); }]; let printer = [{ return printAtomicReadOp(p, *this); }]; - let verifier = [{ return verifyAtomicReadOp(*this); }]; + let hasVerifier = 1; } def AtomicWriteOp : OpenMP_Op<"atomic.write"> { @@ -643,7 +639,7 @@ OptionalAttr:$memory_order); let parser = [{ return parseAtomicWriteOp(parser, result); }]; let printer = [{ return printAtomicWriteOp(p, *this); }]; - let verifier = [{ return verifyAtomicWriteOp(*this); }]; + let hasVerifier = 1; } // TODO: autogenerate from OMP.td in future if possible. @@ -708,7 +704,7 @@ OptionalAttr:$memory_order); let parser = [{ return parseAtomicUpdateOp(parser, result); }]; let printer = [{ return printAtomicUpdateOp(p, *this); }]; - let verifier = [{ return verifyAtomicUpdateOp(*this); }]; + let hasVerifier = 1; } def AtomicCaptureOp : OpenMP_Op<"atomic.capture", @@ -752,7 +748,7 @@ let regions = (region SizedRegion<1>:$region); let parser = [{ return parseAtomicCaptureOp(parser, result); }]; let printer = [{ return printAtomicCaptureOp(p, *this); }]; - let verifier = [{ return verifyAtomicCaptureOp(*this); }]; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -789,7 +785,6 @@ let regions = (region AnyRegion:$initializerRegion, AnyRegion:$reductionRegion, AnyRegion:$atomicReductionRegion); - let verifier = "return ::verifyReductionDeclareOp(*this);"; let assemblyFormat = "$sym_name `:` $type attr-dict-with-keyword " "`init` $initializerRegion " @@ -804,6 +799,7 @@ return atomicReductionRegion().front().getArgument(0).getType(); } }]; + let hasVerifier = 1; } //===----------------------------------------------------------------------===// @@ -826,7 +822,7 @@ let arguments= (ins AnyType:$operand, OpenMP_PointerLikeType:$accumulator); let assemblyFormat = "$operand `,` $accumulator attr-dict `:` type($accumulator)"; - let verifier = "return ::verifyReductionOp(*this);"; + let hasVerifier = 1; } #endif // OPENMP_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 @@ -668,28 +668,22 @@ LoopOp::getOperandSegmentSizeAttr()}); } -static LogicalResult verifyLoopOp(acc::LoopOp loopOp) { +LogicalResult acc::LoopOp::verify() { // auto, independent and seq attribute are mutually exclusive. - if ((loopOp.auto_() && (loopOp.independent() || loopOp.seq())) || - (loopOp.independent() && loopOp.seq())) { - loopOp.emitError("only one of " + acc::LoopOp::getAutoAttrName() + ", " + + if ((auto_() && (independent() || seq())) || (independent() && seq())) { + return emitError("only one of " + acc::LoopOp::getAutoAttrName() + ", " + acc::LoopOp::getIndependentAttrName() + ", " + acc::LoopOp::getSeqAttrName() + " can be present at the same time"); - return failure(); } // Gang, worker and vector are incompatible with seq. - if (loopOp.seq() && loopOp.exec_mapping() != OpenACCExecMapping::NONE) { - loopOp.emitError("gang, worker or vector cannot appear with the seq attr"); - return failure(); - } + if (seq() && exec_mapping() != OpenACCExecMapping::NONE) + return emitError("gang, worker or vector cannot appear with the seq attr"); // Check non-empty body(). - if (loopOp.region().empty()) { - loopOp.emitError("expected non-empty body."); - return failure(); - } + if (region().empty()) + return emitError("expected non-empty body."); return success(); } @@ -698,13 +692,13 @@ // DataOp //===----------------------------------------------------------------------===// -static LogicalResult verify(acc::DataOp dataOp) { +LogicalResult acc::DataOp::verify() { // 2.6.5. Data Construct restriction // At least one copy, copyin, copyout, create, no_create, present, deviceptr, // attach, or default clause must appear on a data construct. - if (dataOp.getOperands().empty() && !dataOp.defaultAttr()) - return dataOp.emitError("at least one operand or the default attribute " - "must appear on the data operation"); + if (getOperands().empty() && !defaultAttr()) + return emitError("at least one operand or the default attribute " + "must appear on the data operation"); return success(); } @@ -726,28 +720,28 @@ // ExitDataOp //===----------------------------------------------------------------------===// -static LogicalResult verify(acc::ExitDataOp op) { +LogicalResult acc::ExitDataOp::verify() { // 2.6.6. Data Exit Directive restriction // At least one copyout, delete, or detach clause must appear on an exit data // directive. - if (op.copyoutOperands().empty() && op.deleteOperands().empty() && - op.detachOperands().empty()) - return op.emitError( + if (copyoutOperands().empty() && deleteOperands().empty() && + detachOperands().empty()) + return emitError( "at least one operand in copyout, delete or detach must appear on the " "exit data operation"); // The async attribute represent the async clause without value. Therefore the // attribute and operand cannot appear at the same time. - if (op.asyncOperand() && op.async()) - return op.emitError("async attribute cannot appear with asyncOperand"); + if (asyncOperand() && async()) + return emitError("async attribute cannot appear with asyncOperand"); // The wait attribute represent the wait clause without values. Therefore the // attribute and operands cannot appear at the same time. - if (!op.waitOperands().empty() && op.wait()) - return op.emitError("wait attribute cannot appear with waitOperands"); + if (!waitOperands().empty() && wait()) + return emitError("wait attribute cannot appear with waitOperands"); - if (op.waitDevnum() && op.waitOperands().empty()) - return op.emitError("wait_devnum cannot appear without waitOperands"); + if (waitDevnum() && waitOperands().empty()) + return emitError("wait_devnum cannot appear without waitOperands"); return success(); } @@ -773,28 +767,28 @@ // EnterDataOp //===----------------------------------------------------------------------===// -static LogicalResult verify(acc::EnterDataOp op) { +LogicalResult acc::EnterDataOp::verify() { // 2.6.6. Data Enter Directive restriction // At least one copyin, create, or attach clause must appear on an enter data // directive. - if (op.copyinOperands().empty() && op.createOperands().empty() && - op.createZeroOperands().empty() && op.attachOperands().empty()) - return op.emitError( + if (copyinOperands().empty() && createOperands().empty() && + createZeroOperands().empty() && attachOperands().empty()) + return emitError( "at least one operand in copyin, create, " "create_zero or attach must appear on the enter data operation"); // The async attribute represent the async clause without value. Therefore the // attribute and operand cannot appear at the same time. - if (op.asyncOperand() && op.async()) - return op.emitError("async attribute cannot appear with asyncOperand"); + if (asyncOperand() && async()) + return emitError("async attribute cannot appear with asyncOperand"); // The wait attribute represent the wait clause without values. Therefore the // attribute and operands cannot appear at the same time. - if (!op.waitOperands().empty() && op.wait()) - return op.emitError("wait attribute cannot appear with waitOperands"); + if (!waitOperands().empty() && wait()) + return emitError("wait attribute cannot appear with waitOperands"); - if (op.waitDevnum() && op.waitOperands().empty()) - return op.emitError("wait_devnum cannot appear without waitOperands"); + if (waitDevnum() && waitOperands().empty()) + return emitError("wait_devnum cannot appear without waitOperands"); return success(); } @@ -820,12 +814,11 @@ // InitOp //===----------------------------------------------------------------------===// -static LogicalResult verify(acc::InitOp initOp) { - Operation *currOp = initOp; - while ((currOp = currOp->getParentOp())) { +LogicalResult acc::InitOp::verify() { + Operation *currOp = *this; + while ((currOp = currOp->getParentOp())) if (isComputeOperation(currOp)) - return initOp.emitOpError("cannot be nested in a compute operation"); - } + return emitOpError("cannot be nested in a compute operation"); return success(); } @@ -833,12 +826,11 @@ // ShutdownOp //===----------------------------------------------------------------------===// -static LogicalResult verify(acc::ShutdownOp op) { - Operation *currOp = op; - while ((currOp = currOp->getParentOp())) { +LogicalResult acc::ShutdownOp::verify() { + Operation *currOp = *this; + while ((currOp = currOp->getParentOp())) if (isComputeOperation(currOp)) - return op.emitOpError("cannot be nested in a compute operation"); - } + return emitOpError("cannot be nested in a compute operation"); return success(); } @@ -846,25 +838,24 @@ // UpdateOp //===----------------------------------------------------------------------===// -static LogicalResult verify(acc::UpdateOp updateOp) { +LogicalResult acc::UpdateOp::verify() { // At least one of host or device should have a value. - if (updateOp.hostOperands().empty() && updateOp.deviceOperands().empty()) - return updateOp.emitError("at least one value must be present in" - " hostOperands or deviceOperands"); + if (hostOperands().empty() && deviceOperands().empty()) + return emitError( + "at least one value must be present in hostOperands or deviceOperands"); // The async attribute represent the async clause without value. Therefore the // attribute and operand cannot appear at the same time. - if (updateOp.asyncOperand() && updateOp.async()) - return updateOp.emitError("async attribute cannot appear with " - " asyncOperand"); + if (asyncOperand() && async()) + return emitError("async attribute cannot appear with asyncOperand"); // The wait attribute represent the wait clause without values. Therefore the // attribute and operands cannot appear at the same time. - if (!updateOp.waitOperands().empty() && updateOp.wait()) - return updateOp.emitError("wait attribute cannot appear with waitOperands"); + if (!waitOperands().empty() && wait()) + return emitError("wait attribute cannot appear with waitOperands"); - if (updateOp.waitDevnum() && updateOp.waitOperands().empty()) - return updateOp.emitError("wait_devnum cannot appear without waitOperands"); + if (waitDevnum() && waitOperands().empty()) + return emitError("wait_devnum cannot appear without waitOperands"); return success(); } @@ -890,14 +881,14 @@ // WaitOp //===----------------------------------------------------------------------===// -static LogicalResult verify(acc::WaitOp waitOp) { +LogicalResult acc::WaitOp::verify() { // The async attribute represent the async clause without value. Therefore the // attribute and operand cannot appear at the same time. - if (waitOp.asyncOperand() && waitOp.async()) - return waitOp.emitError("async attribute cannot appear with asyncOperand"); + if (asyncOperand() && async()) + return emitError("async attribute cannot appear with asyncOperand"); - if (waitOp.waitDevnum() && waitOp.waitOperands().empty()) - return waitOp.emitError("wait_devnum cannot appear without waitOperands"); + if (waitDevnum() && waitOperands().empty()) + return emitError("wait_devnum cannot appear without waitOperands"); return success(); } diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -165,9 +165,9 @@ } } -static LogicalResult verifyParallelOp(ParallelOp op) { - if (op.allocate_vars().size() != op.allocators_vars().size()) - return op.emitError( +LogicalResult ParallelOp::verify() { + if (allocate_vars().size() != allocators_vars().size()) + return emitError( "expected equal sizes for allocate and allocator variables"); return success(); } @@ -1072,31 +1072,31 @@ p.printRegion(op.region()); } -static LogicalResult verifySectionsOp(SectionsOp op) { - +LogicalResult SectionsOp::verify() { // A list item may not appear in more than one clause on the same directive, // except that it may be specified in both firstprivate and lastprivate // clauses. - for (auto var : op.private_vars()) { - if (llvm::is_contained(op.firstprivate_vars(), var)) - return op.emitOpError() + for (auto var : private_vars()) { + if (llvm::is_contained(firstprivate_vars(), var)) + return emitOpError() << "operand used in both private and firstprivate clauses"; - if (llvm::is_contained(op.lastprivate_vars(), var)) - return op.emitOpError() + if (llvm::is_contained(lastprivate_vars(), var)) + return emitOpError() << "operand used in both private and lastprivate clauses"; } - if (op.allocate_vars().size() != op.allocators_vars().size()) - return op.emitError( + if (allocate_vars().size() != allocators_vars().size()) + return emitError( "expected equal sizes for allocate and allocator variables"); - for (auto &inst : *op.region().begin()) { - if (!(isa(inst) || isa(inst))) - op.emitOpError() - << "expected omp.section op or terminator op inside region"; + for (auto &inst : *region().begin()) { + if (!(isa(inst) || isa(inst))) { + return emitOpError() + << "expected omp.section op or terminator op inside region"; + } } - return verifyReductionVarList(op, op.reductions(), op.reduction_vars()); + return verifyReductionVarList(*this, reductions(), reduction_vars()); } /// Parses an OpenMP Workshare Loop operation @@ -1224,65 +1224,65 @@ printer.printRegion(region); } -static LogicalResult verifyReductionDeclareOp(ReductionDeclareOp op) { - if (op.initializerRegion().empty()) - return op.emitOpError() << "expects non-empty initializer region"; - Block &initializerEntryBlock = op.initializerRegion().front(); +LogicalResult ReductionDeclareOp::verify() { + if (initializerRegion().empty()) + return emitOpError() << "expects non-empty initializer region"; + Block &initializerEntryBlock = initializerRegion().front(); if (initializerEntryBlock.getNumArguments() != 1 || - initializerEntryBlock.getArgument(0).getType() != op.type()) { - return op.emitOpError() << "expects initializer region with one argument " - "of the reduction type"; + initializerEntryBlock.getArgument(0).getType() != type()) { + return emitOpError() << "expects initializer region with one argument " + "of the reduction type"; } - for (YieldOp yieldOp : op.initializerRegion().getOps()) { + for (YieldOp yieldOp : initializerRegion().getOps()) { if (yieldOp.results().size() != 1 || - yieldOp.results().getTypes()[0] != op.type()) - return op.emitOpError() << "expects initializer region to yield a value " - "of the reduction type"; + yieldOp.results().getTypes()[0] != type()) + return emitOpError() << "expects initializer region to yield a value " + "of the reduction type"; } - if (op.reductionRegion().empty()) - return op.emitOpError() << "expects non-empty reduction region"; - Block &reductionEntryBlock = op.reductionRegion().front(); + if (reductionRegion().empty()) + return emitOpError() << "expects non-empty reduction region"; + Block &reductionEntryBlock = reductionRegion().front(); if (reductionEntryBlock.getNumArguments() != 2 || reductionEntryBlock.getArgumentTypes()[0] != reductionEntryBlock.getArgumentTypes()[1] || - reductionEntryBlock.getArgumentTypes()[0] != op.type()) - return op.emitOpError() << "expects reduction region with two arguments of " - "the reduction type"; - for (YieldOp yieldOp : op.reductionRegion().getOps()) { + reductionEntryBlock.getArgumentTypes()[0] != type()) + return emitOpError() << "expects reduction region with two arguments of " + "the reduction type"; + for (YieldOp yieldOp : reductionRegion().getOps()) { if (yieldOp.results().size() != 1 || - yieldOp.results().getTypes()[0] != op.type()) - return op.emitOpError() << "expects reduction region to yield a value " - "of the reduction type"; + yieldOp.results().getTypes()[0] != type()) + return emitOpError() << "expects reduction region to yield a value " + "of the reduction type"; } - if (op.atomicReductionRegion().empty()) + if (atomicReductionRegion().empty()) return success(); - Block &atomicReductionEntryBlock = op.atomicReductionRegion().front(); + Block &atomicReductionEntryBlock = atomicReductionRegion().front(); if (atomicReductionEntryBlock.getNumArguments() != 2 || atomicReductionEntryBlock.getArgumentTypes()[0] != atomicReductionEntryBlock.getArgumentTypes()[1]) - return op.emitOpError() << "expects atomic reduction region with two " - "arguments of the same type"; + return emitOpError() << "expects atomic reduction region with two " + "arguments of the same type"; auto ptrType = atomicReductionEntryBlock.getArgumentTypes()[0] .dyn_cast(); - if (!ptrType || ptrType.getElementType() != op.type()) - return op.emitOpError() << "expects atomic reduction region arguments to " - "be accumulators containing the reduction type"; + if (!ptrType || ptrType.getElementType() != type()) + return emitOpError() << "expects atomic reduction region arguments to " + "be accumulators containing the reduction type"; return success(); } -static LogicalResult verifyReductionOp(ReductionOp op) { +LogicalResult ReductionOp::verify() { // TODO: generalize this to an op interface when there is more than one op // that supports reductions. - auto container = op->getParentOfType(); + auto container = (*this)->getParentOfType(); for (unsigned i = 0, e = container.getNumReductionVars(); i < e; ++i) - if (container.reduction_vars()[i] == op.accumulator()) + if (container.reduction_vars()[i] == accumulator()) return success(); - return op.emitOpError() << "the accumulator is not used by the parent"; + return emitOpError() << "the accumulator is not used by the parent"; } //===----------------------------------------------------------------------===// @@ -1368,27 +1368,26 @@ } } -static LogicalResult verifyWsLoopOp(WsLoopOp op) { - return verifyReductionVarList(op, op.reductions(), op.reduction_vars()); +LogicalResult WsLoopOp::verify() { + return verifyReductionVarList(*this, reductions(), reduction_vars()); } //===----------------------------------------------------------------------===// // Verifier for critical construct (2.17.1) //===----------------------------------------------------------------------===// -static LogicalResult verifyCriticalDeclareOp(CriticalDeclareOp op) { - return verifySynchronizationHint(op, op.hint()); +LogicalResult CriticalDeclareOp::verify() { + return verifySynchronizationHint(*this, hint()); } -static LogicalResult verifyCriticalOp(CriticalOp op) { - - if (op.nameAttr()) { - auto symbolRef = op.nameAttr().cast(); - auto decl = - SymbolTable::lookupNearestSymbolFrom(op, symbolRef); +LogicalResult CriticalOp::verify() { + if (nameAttr()) { + SymbolRefAttr symbolRef = nameAttr(); + auto decl = SymbolTable::lookupNearestSymbolFrom( + *this, symbolRef); if (!decl) { - return op.emitOpError() << "expected symbol reference " << symbolRef - << " to point to a critical declaration"; + return emitOpError() << "expected symbol reference " << symbolRef + << " to point to a critical declaration"; } } @@ -1399,34 +1398,34 @@ // Verifier for ordered construct //===----------------------------------------------------------------------===// -static LogicalResult verifyOrderedOp(OrderedOp op) { - auto container = op->getParentOfType(); +LogicalResult OrderedOp::verify() { + auto container = (*this)->getParentOfType(); if (!container || !container.ordered_valAttr() || container.ordered_valAttr().getInt() == 0) - return op.emitOpError() << "ordered depend directive must be closely " - << "nested inside a worksharing-loop with ordered " - << "clause with parameter present"; + return emitOpError() << "ordered depend directive must be closely " + << "nested inside a worksharing-loop with ordered " + << "clause with parameter present"; if (container.ordered_valAttr().getInt() != - (int64_t)op.num_loops_val().getValue()) - return op.emitOpError() << "number of variables in depend clause does not " - << "match number of iteration variables in the " - << "doacross loop"; + (int64_t)num_loops_val().getValue()) + return emitOpError() << "number of variables in depend clause does not " + << "match number of iteration variables in the " + << "doacross loop"; return success(); } -static LogicalResult verifyOrderedRegionOp(OrderedRegionOp op) { +LogicalResult OrderedRegionOp::verify() { // TODO: The code generation for ordered simd directive is not supported yet. - if (op.simd()) + if (simd()) return failure(); - if (auto container = op->getParentOfType()) { + if (auto container = (*this)->getParentOfType()) { if (!container.ordered_valAttr() || container.ordered_valAttr().getInt() != 0) - return op.emitOpError() << "ordered region must be closely nested inside " - << "a worksharing-loop region with an ordered " - << "clause without parameter present"; + return emitOpError() << "ordered region must be closely nested inside " + << "a worksharing-loop region with an ordered " + << "clause without parameter present"; } return success(); @@ -1468,18 +1467,18 @@ } /// Verifier for AtomicReadOp -static LogicalResult verifyAtomicReadOp(AtomicReadOp op) { - if (auto mo = op.memory_order()) { +LogicalResult AtomicReadOp::verify() { + if (auto mo = memory_order()) { if (*mo == ClauseMemoryOrderKind::acq_rel || *mo == ClauseMemoryOrderKind::release) { - return op.emitError( + return emitError( "memory-order must not be acq_rel or release for atomic reads"); } } - if (op.x() == op.v()) - return op.emitError( + if (x() == v()) + return emitError( "read and write must not be to the same location for atomic reads"); - return verifySynchronizationHint(op, op.hint()); + return verifySynchronizationHint(*this, hint()); } //===----------------------------------------------------------------------===// @@ -1521,15 +1520,15 @@ } /// Verifier for AtomicWriteOp -static LogicalResult verifyAtomicWriteOp(AtomicWriteOp op) { - if (auto mo = op.memory_order()) { +LogicalResult AtomicWriteOp::verify() { + if (auto mo = memory_order()) { if (*mo == ClauseMemoryOrderKind::acq_rel || *mo == ClauseMemoryOrderKind::acquire) { - return op.emitError( + return emitError( "memory-order must not be acq_rel or acquire for atomic writes"); } } - return verifySynchronizationHint(op, op.hint()); + return verifySynchronizationHint(*this, hint()); } //===----------------------------------------------------------------------===// @@ -1601,11 +1600,11 @@ } /// Verifier for AtomicUpdateOp -static LogicalResult verifyAtomicUpdateOp(AtomicUpdateOp op) { - if (auto mo = op.memory_order()) { +LogicalResult AtomicUpdateOp::verify() { + if (auto mo = memory_order()) { if (*mo == ClauseMemoryOrderKind::acq_rel || *mo == ClauseMemoryOrderKind::acquire) { - return op.emitError( + return emitError( "memory-order must not be acq_rel or acquire for atomic updates"); } } @@ -1637,10 +1636,10 @@ } /// Verifier for AtomicCaptureOp -static LogicalResult verifyAtomicCaptureOp(AtomicCaptureOp op) { - Block::OpListType &ops = op.region().front().getOperations(); +LogicalResult AtomicCaptureOp::verify() { + Block::OpListType &ops = region().front().getOperations(); if (ops.size() != 3) - return emitError(op.getLoc()) + return emitError() << "expected three operations in omp.atomic.capture region (one " "terminator, and two atomic ops)"; auto &firstOp = ops.front(); @@ -1654,21 +1653,21 @@ if (!((firstUpdateStmt && secondReadStmt) || (firstReadStmt && secondUpdateStmt) || (firstReadStmt && secondWriteStmt))) - return emitError(ops.front().getLoc()) + return ops.front().emitError() << "invalid sequence of operations in the capture region"; if (firstUpdateStmt && secondReadStmt && firstUpdateStmt.x() != secondReadStmt.x()) - return emitError(firstUpdateStmt.getLoc()) + return firstUpdateStmt.emitError() << "updated variable in omp.atomic.update must be captured in " "second operation"; if (firstReadStmt && secondUpdateStmt && firstReadStmt.x() != secondUpdateStmt.x()) - return emitError(firstReadStmt.getLoc()) + return firstReadStmt.emitError() << "captured variable in omp.atomic.read must be updated in second " "operation"; if (firstReadStmt && secondWriteStmt && firstReadStmt.x() != secondWriteStmt.address()) - return emitError(firstReadStmt.getLoc()) + return firstReadStmt.emitError() << "captured variable in omp.atomic.read must be updated in " "second operation"; return success(); 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 @@ -90,7 +90,7 @@ %cst = arith.constant 1 : index %value = memref.alloc() : memref<10xf32> -// expected-error@+1 {{async attribute cannot appear with asyncOperand}} +// expected-error@+1 {{async attribute cannot appear with asyncOperand}} acc.update async(%cst: index) host(%value: memref<10xf32>) attributes {async} // -----