forked from OSchip/llvm-project
[mlir][NFC] Update OpenACC/OpenMP operations to use `hasVerifier` instead of `verifier`
The verifier field is deprecated, and slated for removal. Differential Revision: https://reviews.llvm.org/D118825
This commit is contained in:
parent
b98dc0351a
commit
ef72cf4413
|
@ -37,7 +37,6 @@ class OpenACC_Op<string mnemonic, list<Trait> traits = []> :
|
|||
Op<OpenACC_Dialect, mnemonic, traits> {
|
||||
|
||||
let printer = [{ return ::print(p, *this); }];
|
||||
let verifier = [{ return ::verify(*this); }];
|
||||
let parser = [{ return ::parse$cppClass(parser, result); }];
|
||||
}
|
||||
|
||||
|
@ -153,8 +152,6 @@ def OpenACC_ParallelOp : OpenACC_Op<"parallel",
|
|||
/// The i-th data operand passed.
|
||||
Value getDataOperand(unsigned i);
|
||||
}];
|
||||
|
||||
let verifier = ?;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -225,6 +222,7 @@ def OpenACC_DataOp : OpenACC_Op<"data",
|
|||
( `attach` `(` $attachOperands^ `:` type($attachOperands) `)` )?
|
||||
$region attr-dict-with-keyword
|
||||
}];
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
def OpenACC_TerminatorOp : OpenACC_Op<"terminator", [Terminator]> {
|
||||
|
@ -237,8 +235,6 @@ def OpenACC_TerminatorOp : OpenACC_Op<"terminator", [Terminator]> {
|
|||
to the enclosing op.
|
||||
}];
|
||||
|
||||
let verifier = ?;
|
||||
|
||||
let assemblyFormat = "attr-dict";
|
||||
}
|
||||
|
||||
|
@ -292,6 +288,7 @@ def OpenACC_EnterDataOp : OpenACC_Op<"enter_data", [AttrSizedOperandSegments]> {
|
|||
}];
|
||||
|
||||
let hasCanonicalizer = 1;
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -342,6 +339,7 @@ def OpenACC_ExitDataOp : OpenACC_Op<"exit_data", [AttrSizedOperandSegments]> {
|
|||
}];
|
||||
|
||||
let hasCanonicalizer = 1;
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -406,8 +404,7 @@ def OpenACC_LoopOp : OpenACC_Op<"loop",
|
|||
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 @@ def OpenACC_YieldOp : OpenACC_Op<"yield", [Terminator,
|
|||
|
||||
let builders = [OpBuilder<(ins), [{ /* nothing to do */ }]>];
|
||||
|
||||
let verifier = ?;
|
||||
|
||||
let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?";
|
||||
}
|
||||
|
||||
|
@ -458,6 +453,7 @@ def OpenACC_InitOp : OpenACC_Op<"init", [AttrSizedOperandSegments]> {
|
|||
( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )?
|
||||
( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword
|
||||
}];
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -488,6 +484,7 @@ def OpenACC_ShutdownOp : OpenACC_Op<"shutdown", [AttrSizedOperandSegments]> {
|
|||
( `device_num` `(` $deviceNumOperand^ `:` type($deviceNumOperand) `)` )?
|
||||
( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword
|
||||
}];
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -542,6 +539,7 @@ def OpenACC_UpdateOp : OpenACC_Op<"update", [AttrSizedOperandSegments]> {
|
|||
}];
|
||||
|
||||
let hasCanonicalizer = 1;
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -575,6 +573,7 @@ def OpenACC_WaitOp : OpenACC_Op<"wait", [AttrSizedOperandSegments]> {
|
|||
( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )?
|
||||
( `if` `(` $ifCond^ `)` )? attr-dict-with-keyword
|
||||
}];
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
#endif // OPENACC_OPS
|
||||
|
|
|
@ -128,7 +128,7 @@ def ParallelOp : OpenMP_Op<"parallel", [AttrSizedOperandSegments,
|
|||
];
|
||||
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 @@ def SectionsOp : OpenMP_Op<"sections", [AttrSizedOperandSegments]> {
|
|||
|
||||
let parser = [{ return parseSectionsOp(parser, result); }];
|
||||
let printer = [{ return printSectionsOp(p, *this); }];
|
||||
let verifier = [{ return verifySectionsOp(*this); }];
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -336,7 +336,7 @@ def WsLoopOp : OpenMP_Op<"wsloop", [AttrSizedOperandSegments,
|
|||
}];
|
||||
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 @@ def CriticalDeclareOp : OpenMP_Op<"critical.declare", [Symbol]> {
|
|||
let assemblyFormat = [{
|
||||
$sym_name custom<SynchronizationHint>($hint) attr-dict
|
||||
}];
|
||||
|
||||
let verifier = "return verifyCriticalDeclareOp(*this);";
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -476,8 +475,7 @@ def CriticalOp : OpenMP_Op<"critical"> {
|
|||
let assemblyFormat = [{
|
||||
(`(` $name^ `)`)? $region attr-dict
|
||||
}];
|
||||
|
||||
let verifier = "return ::verifyCriticalOp(*this);";
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -540,8 +538,7 @@ def OrderedOp : OpenMP_Op<"ordered"> {
|
|||
( `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 @@ def OrderedRegionOp : OpenMP_Op<"ordered_region"> {
|
|||
let regions = (region AnyRegion:$region);
|
||||
|
||||
let assemblyFormat = [{ ( `simd` $simd^ )? $region attr-dict}];
|
||||
|
||||
let verifier = "return ::verifyOrderedRegionOp(*this);";
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -614,7 +610,7 @@ def AtomicReadOp : OpenMP_Op<"atomic.read"> {
|
|||
OptionalAttr<MemoryOrderKindAttr>:$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 @@ def AtomicWriteOp : OpenMP_Op<"atomic.write"> {
|
|||
OptionalAttr<MemoryOrderKindAttr>:$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 @@ def AtomicUpdateOp : OpenMP_Op<"atomic.update"> {
|
|||
OptionalAttr<MemoryOrderKindAttr>:$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 @@ def AtomicCaptureOp : OpenMP_Op<"atomic.capture",
|
|||
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 @@ def ReductionDeclareOp : OpenMP_Op<"reduction.declare", [Symbol]> {
|
|||
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 @@ def ReductionDeclareOp : OpenMP_Op<"reduction.declare", [Symbol]> {
|
|||
return atomicReductionRegion().front().getArgument(0).getType();
|
||||
}
|
||||
}];
|
||||
let hasVerifier = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -826,7 +822,7 @@ def ReductionOp : OpenMP_Op<"reduction", [
|
|||
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
|
||||
|
|
|
@ -668,28 +668,22 @@ static void print(OpAsmPrinter &printer, LoopOp &op) {
|
|||
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 @@ static LogicalResult verifyLoopOp(acc::LoopOp loopOp) {
|
|||
// 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 @@ Value DataOp::getDataOperand(unsigned i) {
|
|||
// 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 @@ void ExitDataOp::getCanonicalizationPatterns(RewritePatternSet &results,
|
|||
// 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 @@ void EnterDataOp::getCanonicalizationPatterns(RewritePatternSet &results,
|
|||
// 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 @@ static LogicalResult verify(acc::InitOp initOp) {
|
|||
// 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 @@ static LogicalResult verify(acc::ShutdownOp op) {
|
|||
// 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 @@ void UpdateOp::getCanonicalizationPatterns(RewritePatternSet &results,
|
|||
// 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();
|
||||
}
|
||||
|
|
|
@ -165,9 +165,9 @@ static void printAllocateAndAllocator(OpAsmPrinter &p,
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ static void printSectionsOp(OpAsmPrinter &p, SectionsOp op) {
|
|||
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<SectionOp>(inst) || isa<TerminatorOp>(inst)))
|
||||
op.emitOpError()
|
||||
<< "expected omp.section op or terminator op inside region";
|
||||
for (auto &inst : *region().begin()) {
|
||||
if (!(isa<SectionOp>(inst) || isa<TerminatorOp>(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 @@ static void printAtomicReductionRegion(OpAsmPrinter &printer,
|
|||
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<YieldOp>()) {
|
||||
for (YieldOp yieldOp : initializerRegion().getOps<YieldOp>()) {
|
||||
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<YieldOp>()) {
|
||||
reductionEntryBlock.getArgumentTypes()[0] != type())
|
||||
return emitOpError() << "expects reduction region with two arguments of "
|
||||
"the reduction type";
|
||||
for (YieldOp yieldOp : reductionRegion().getOps<YieldOp>()) {
|
||||
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<PointerLikeType>();
|
||||
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<WsLoopOp>();
|
||||
auto container = (*this)->getParentOfType<WsLoopOp>();
|
||||
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 @@ void WsLoopOp::build(OpBuilder &builder, OperationState &result,
|
|||
}
|
||||
}
|
||||
|
||||
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<SymbolRefAttr>();
|
||||
auto decl =
|
||||
SymbolTable::lookupNearestSymbolFrom<CriticalDeclareOp>(op, symbolRef);
|
||||
LogicalResult CriticalOp::verify() {
|
||||
if (nameAttr()) {
|
||||
SymbolRefAttr symbolRef = nameAttr();
|
||||
auto decl = SymbolTable::lookupNearestSymbolFrom<CriticalDeclareOp>(
|
||||
*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 @@ static LogicalResult verifyCriticalOp(CriticalOp op) {
|
|||
// Verifier for ordered construct
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static LogicalResult verifyOrderedOp(OrderedOp op) {
|
||||
auto container = op->getParentOfType<WsLoopOp>();
|
||||
LogicalResult OrderedOp::verify() {
|
||||
auto container = (*this)->getParentOfType<WsLoopOp>();
|
||||
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<WsLoopOp>()) {
|
||||
if (auto container = (*this)->getParentOfType<WsLoopOp>()) {
|
||||
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 @@ static void printAtomicReadOp(OpAsmPrinter &p, AtomicReadOp op) {
|
|||
}
|
||||
|
||||
/// 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 @@ static void printAtomicWriteOp(OpAsmPrinter &p, AtomicWriteOp op) {
|
|||
}
|
||||
|
||||
/// 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 @@ static void printAtomicUpdateOp(OpAsmPrinter &p, AtomicUpdateOp op) {
|
|||
}
|
||||
|
||||
/// 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 @@ static void printAtomicCaptureOp(OpAsmPrinter &p, AtomicCaptureOp op) {
|
|||
}
|
||||
|
||||
/// 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 @@ static LogicalResult verifyAtomicCaptureOp(AtomicCaptureOp op) {
|
|||
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();
|
||||
|
|
|
@ -90,7 +90,7 @@ acc.update wait_devnum(%cst: index) host(%value: memref<10xf32>)
|
|||
|
||||
%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}
|
||||
|
||||
// -----
|
||||
|
|
Loading…
Reference in New Issue