[Mlir-commits] [mlir] 4e190c5 - [mlir][NFC] Update Toy operations to use `hasVerifier` instead of `verifier`

River Riddle llvmlistbot at llvm.org
Wed Feb 2 13:35:36 PST 2022


Author: River Riddle
Date: 2022-02-02T13:34:28-08:00
New Revision: 4e190c58de7b52a0d6b2052a96c6f5933cb50b47

URL: https://github.com/llvm/llvm-project/commit/4e190c58de7b52a0d6b2052a96c6f5933cb50b47
DIFF: https://github.com/llvm/llvm-project/commit/4e190c58de7b52a0d6b2052a96c6f5933cb50b47.diff

LOG: [mlir][NFC] Update Toy operations to use `hasVerifier` instead of `verifier`

The verifier field is deprecated, and slated for removal.

Differential Revision: https://reviews.llvm.org/D118816

Added: 
    

Modified: 
    mlir/docs/Tutorials/Toy/Ch-2.md
    mlir/examples/toy/Ch2/include/toy/Ops.td
    mlir/examples/toy/Ch2/mlir/Dialect.cpp
    mlir/examples/toy/Ch3/include/toy/Ops.td
    mlir/examples/toy/Ch3/mlir/Dialect.cpp
    mlir/examples/toy/Ch4/include/toy/Ops.td
    mlir/examples/toy/Ch4/mlir/Dialect.cpp
    mlir/examples/toy/Ch5/include/toy/Ops.td
    mlir/examples/toy/Ch5/mlir/Dialect.cpp
    mlir/examples/toy/Ch6/include/toy/Ops.td
    mlir/examples/toy/Ch6/mlir/Dialect.cpp
    mlir/examples/toy/Ch7/include/toy/Ops.td
    mlir/examples/toy/Ch7/mlir/Dialect.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/docs/Tutorials/Toy/Ch-2.md b/mlir/docs/Tutorials/Toy/Ch-2.md
index 88fd604e28d4a..648bfbd896c56 100644
--- a/mlir/docs/Tutorials/Toy/Ch-2.md
+++ b/mlir/docs/Tutorials/Toy/Ch-2.md
@@ -280,7 +280,7 @@ class ConstantOp : public mlir::Op<
   /// traits provide.  Here we will ensure that the specific invariants of the
   /// constant operation are upheld, for example the result type must be
   /// of TensorType and matches the type of the constant `value`.
-  LogicalResult verify();
+  LogicalResult verifyInvariants();
 
   /// Provide an interface to build this operation from a set of input values.
   /// This interface is used by the `builder` classes to allow for easily
@@ -495,11 +495,12 @@ def ConstantOp : Toy_Op<"constant"> {
   // F64Tensor corresponds to a 64-bit floating-point TensorType.
   let results = (outs F64Tensor);
 
-  // Add additional verification logic to the constant operation. Here we invoke
-  // a static `verify` method in a C++ source file. This codeblock is executed
-  // inside of ConstantOp::verify, so we can use `this` to refer to the current
-  // operation instance.
-  let verifier = [{ return ::verify(*this); }];
+  // Add additional verification logic to the constant operation. Setting this bit
+  // to `1` will generate a `::mlir::LogicalResult verify()` declaration on the
+  // operation class that is called after ODS constructs have been verified, for
+  // example the types of arguments and results. We implement additional verification
+  // in the definition of this `verify` method in the C++ source file. 
+  let hasVerifier = 1;
 }
 ```
 

diff  --git a/mlir/examples/toy/Ch2/include/toy/Ops.td b/mlir/examples/toy/Ch2/include/toy/Ops.td
index eaec24c3ae5bb..eebe7ea65fc91 100644
--- a/mlir/examples/toy/Ch2/include/toy/Ops.td
+++ b/mlir/examples/toy/Ch2/include/toy/Ops.td
@@ -76,8 +76,8 @@ def ConstantOp : Toy_Op<"constant", [NoSideEffect]> {
     OpBuilder<(ins "double":$value)>
   ];
 
-  // Invoke a static verify method to verify this constant operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def AddOp : Toy_Op<"add"> {
@@ -224,7 +224,7 @@ def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
   }];
 
   // Invoke a static verify method to verify this return operation.
-  let verifier = [{ return ::verify(*this); }];
+  let hasVerifier = 1;
 }
 
 def TransposeOp : Toy_Op<"transpose"> {
@@ -243,7 +243,7 @@ def TransposeOp : Toy_Op<"transpose"> {
   ];
 
   // Invoke a static verify method to verify this transpose operation.
-  let verifier = [{ return ::verify(*this); }];
+  let hasVerifier = 1;
 }
 
 #endif // TOY_OPS

diff  --git a/mlir/examples/toy/Ch2/mlir/Dialect.cpp b/mlir/examples/toy/Ch2/mlir/Dialect.cpp
index 278c857ea4681..159b55d1bc82b 100644
--- a/mlir/examples/toy/Ch2/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch2/mlir/Dialect.cpp
@@ -126,29 +126,28 @@ static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
   printer << op.value();
 }
 
-/// Verifier for the constant operation. This corresponds to the `::verify(...)`
-/// in the op definition.
-static mlir::LogicalResult verify(ConstantOp op) {
+/// Verifier for the constant operation. This corresponds to the
+/// `let hasVerifier = 1` in the op definition.
+mlir::LogicalResult ConstantOp::verify() {
   // If the return type of the constant is not an unranked tensor, the shape
   // must match the shape of the attribute holding the data.
-  auto resultType = op.getResult().getType().dyn_cast<mlir::RankedTensorType>();
+  auto resultType = getResult().getType().dyn_cast<mlir::RankedTensorType>();
   if (!resultType)
     return success();
 
   // Check that the rank of the attribute type matches the rank of the constant
   // result type.
-  auto attrType = op.value().getType().cast<mlir::TensorType>();
+  auto attrType = value().getType().cast<mlir::TensorType>();
   if (attrType.getRank() != resultType.getRank()) {
-    return op.emitOpError(
-               "return type must match the one of the attached value "
-               "attribute: ")
+    return emitOpError("return type must match the one of the attached value "
+                       "attribute: ")
            << attrType.getRank() << " != " << resultType.getRank();
   }
 
   // Check that each of the dimensions match between the two types.
   for (int dim = 0, dimE = attrType.getRank(); dim < dimE; ++dim) {
     if (attrType.getShape()[dim] != resultType.getShape()[dim]) {
-      return op.emitOpError(
+      return emitOpError(
                  "return type shape mismatches its attribute at dimension ")
              << dim << ": " << attrType.getShape()[dim]
              << " != " << resultType.getShape()[dim];
@@ -190,28 +189,27 @@ void MulOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
 //===----------------------------------------------------------------------===//
 // ReturnOp
 
-static mlir::LogicalResult verify(ReturnOp op) {
+mlir::LogicalResult ReturnOp::verify() {
   // We know that the parent operation is a function, because of the 'HasParent'
   // trait attached to the operation definition.
-  auto function = cast<FuncOp>(op->getParentOp());
+  auto function = cast<FuncOp>((*this)->getParentOp());
 
   /// ReturnOps can only have a single optional operand.
-  if (op.getNumOperands() > 1)
-    return op.emitOpError() << "expects at most 1 return operand";
+  if (getNumOperands() > 1)
+    return emitOpError() << "expects at most 1 return operand";
 
   // The operand number and types must match the function signature.
   const auto &results = function.getType().getResults();
-  if (op.getNumOperands() != results.size())
-    return op.emitOpError()
-           << "does not return the same number of values ("
-           << op.getNumOperands() << ") as the enclosing function ("
-           << results.size() << ")";
+  if (getNumOperands() != results.size())
+    return emitOpError() << "does not return the same number of values ("
+                         << getNumOperands() << ") as the enclosing function ("
+                         << results.size() << ")";
 
   // If the operation does not have an input, we are done.
-  if (!op.hasOperand())
+  if (!hasOperand())
     return mlir::success();
 
-  auto inputType = *op.operand_type_begin();
+  auto inputType = *operand_type_begin();
   auto resultType = results.front();
 
   // Check that the result type of the function matches the operand type.
@@ -219,9 +217,9 @@ static mlir::LogicalResult verify(ReturnOp op) {
       resultType.isa<mlir::UnrankedTensorType>())
     return mlir::success();
 
-  return op.emitError() << "type of return operand (" << inputType
-                        << ") doesn't match function result type ("
-                        << resultType << ")";
+  return emitError() << "type of return operand (" << inputType
+                     << ") doesn't match function result type (" << resultType
+                     << ")";
 }
 
 //===----------------------------------------------------------------------===//
@@ -233,16 +231,16 @@ void TransposeOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
   state.addOperands(value);
 }
 
-static mlir::LogicalResult verify(TransposeOp op) {
-  auto inputType = op.getOperand().getType().dyn_cast<RankedTensorType>();
-  auto resultType = op.getType().dyn_cast<RankedTensorType>();
+mlir::LogicalResult TransposeOp::verify() {
+  auto inputType = getOperand().getType().dyn_cast<RankedTensorType>();
+  auto resultType = getType().dyn_cast<RankedTensorType>();
   if (!inputType || !resultType)
     return mlir::success();
 
   auto inputShape = inputType.getShape();
   if (!std::equal(inputShape.begin(), inputShape.end(),
                   resultType.getShape().rbegin())) {
-    return op.emitError()
+    return emitError()
            << "expected result shape to be a transpose of the input";
   }
   return mlir::success();

diff  --git a/mlir/examples/toy/Ch3/include/toy/Ops.td b/mlir/examples/toy/Ch3/include/toy/Ops.td
index e1b957d4b7d9c..fc59739a25a07 100644
--- a/mlir/examples/toy/Ch3/include/toy/Ops.td
+++ b/mlir/examples/toy/Ch3/include/toy/Ops.td
@@ -75,8 +75,8 @@ def ConstantOp : Toy_Op<"constant", [NoSideEffect]> {
     OpBuilder<(ins "double":$value)>
   ];
 
-  // Invoke a static verify method to verify this constant operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def AddOp : Toy_Op<"add", [NoSideEffect]> {
@@ -225,8 +225,8 @@ def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
     bool hasOperand() { return getNumOperands() != 0; }
   }];
 
-  // Invoke a static verify method to verify this return operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def TransposeOp : Toy_Op<"transpose", [NoSideEffect]> {
@@ -247,8 +247,8 @@ def TransposeOp : Toy_Op<"transpose", [NoSideEffect]> {
     OpBuilder<(ins "Value":$input)>
   ];
 
-  // Invoke a static verify method to verify this transpose operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 #endif // TOY_OPS

diff  --git a/mlir/examples/toy/Ch3/mlir/Dialect.cpp b/mlir/examples/toy/Ch3/mlir/Dialect.cpp
index 278c857ea4681..159b55d1bc82b 100644
--- a/mlir/examples/toy/Ch3/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch3/mlir/Dialect.cpp
@@ -126,29 +126,28 @@ static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
   printer << op.value();
 }
 
-/// Verifier for the constant operation. This corresponds to the `::verify(...)`
-/// in the op definition.
-static mlir::LogicalResult verify(ConstantOp op) {
+/// Verifier for the constant operation. This corresponds to the
+/// `let hasVerifier = 1` in the op definition.
+mlir::LogicalResult ConstantOp::verify() {
   // If the return type of the constant is not an unranked tensor, the shape
   // must match the shape of the attribute holding the data.
-  auto resultType = op.getResult().getType().dyn_cast<mlir::RankedTensorType>();
+  auto resultType = getResult().getType().dyn_cast<mlir::RankedTensorType>();
   if (!resultType)
     return success();
 
   // Check that the rank of the attribute type matches the rank of the constant
   // result type.
-  auto attrType = op.value().getType().cast<mlir::TensorType>();
+  auto attrType = value().getType().cast<mlir::TensorType>();
   if (attrType.getRank() != resultType.getRank()) {
-    return op.emitOpError(
-               "return type must match the one of the attached value "
-               "attribute: ")
+    return emitOpError("return type must match the one of the attached value "
+                       "attribute: ")
            << attrType.getRank() << " != " << resultType.getRank();
   }
 
   // Check that each of the dimensions match between the two types.
   for (int dim = 0, dimE = attrType.getRank(); dim < dimE; ++dim) {
     if (attrType.getShape()[dim] != resultType.getShape()[dim]) {
-      return op.emitOpError(
+      return emitOpError(
                  "return type shape mismatches its attribute at dimension ")
              << dim << ": " << attrType.getShape()[dim]
              << " != " << resultType.getShape()[dim];
@@ -190,28 +189,27 @@ void MulOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
 //===----------------------------------------------------------------------===//
 // ReturnOp
 
-static mlir::LogicalResult verify(ReturnOp op) {
+mlir::LogicalResult ReturnOp::verify() {
   // We know that the parent operation is a function, because of the 'HasParent'
   // trait attached to the operation definition.
-  auto function = cast<FuncOp>(op->getParentOp());
+  auto function = cast<FuncOp>((*this)->getParentOp());
 
   /// ReturnOps can only have a single optional operand.
-  if (op.getNumOperands() > 1)
-    return op.emitOpError() << "expects at most 1 return operand";
+  if (getNumOperands() > 1)
+    return emitOpError() << "expects at most 1 return operand";
 
   // The operand number and types must match the function signature.
   const auto &results = function.getType().getResults();
-  if (op.getNumOperands() != results.size())
-    return op.emitOpError()
-           << "does not return the same number of values ("
-           << op.getNumOperands() << ") as the enclosing function ("
-           << results.size() << ")";
+  if (getNumOperands() != results.size())
+    return emitOpError() << "does not return the same number of values ("
+                         << getNumOperands() << ") as the enclosing function ("
+                         << results.size() << ")";
 
   // If the operation does not have an input, we are done.
-  if (!op.hasOperand())
+  if (!hasOperand())
     return mlir::success();
 
-  auto inputType = *op.operand_type_begin();
+  auto inputType = *operand_type_begin();
   auto resultType = results.front();
 
   // Check that the result type of the function matches the operand type.
@@ -219,9 +217,9 @@ static mlir::LogicalResult verify(ReturnOp op) {
       resultType.isa<mlir::UnrankedTensorType>())
     return mlir::success();
 
-  return op.emitError() << "type of return operand (" << inputType
-                        << ") doesn't match function result type ("
-                        << resultType << ")";
+  return emitError() << "type of return operand (" << inputType
+                     << ") doesn't match function result type (" << resultType
+                     << ")";
 }
 
 //===----------------------------------------------------------------------===//
@@ -233,16 +231,16 @@ void TransposeOp::build(mlir::OpBuilder &builder, mlir::OperationState &state,
   state.addOperands(value);
 }
 
-static mlir::LogicalResult verify(TransposeOp op) {
-  auto inputType = op.getOperand().getType().dyn_cast<RankedTensorType>();
-  auto resultType = op.getType().dyn_cast<RankedTensorType>();
+mlir::LogicalResult TransposeOp::verify() {
+  auto inputType = getOperand().getType().dyn_cast<RankedTensorType>();
+  auto resultType = getType().dyn_cast<RankedTensorType>();
   if (!inputType || !resultType)
     return mlir::success();
 
   auto inputShape = inputType.getShape();
   if (!std::equal(inputShape.begin(), inputShape.end(),
                   resultType.getShape().rbegin())) {
-    return op.emitError()
+    return emitError()
            << "expected result shape to be a transpose of the input";
   }
   return mlir::success();

diff  --git a/mlir/examples/toy/Ch4/include/toy/Ops.td b/mlir/examples/toy/Ch4/include/toy/Ops.td
index 98ad8786fbb3b..13357ff1f4fe8 100644
--- a/mlir/examples/toy/Ch4/include/toy/Ops.td
+++ b/mlir/examples/toy/Ch4/include/toy/Ops.td
@@ -78,8 +78,8 @@ def ConstantOp : Toy_Op<"constant", [NoSideEffect]> {
     OpBuilder<(ins "double":$value)>
   ];
 
-  // Invoke a static verify method to verify this constant operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def AddOp : Toy_Op<"add",
@@ -252,8 +252,8 @@ def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
     bool hasOperand() { return getNumOperands() != 0; }
   }];
 
-  // Invoke a static verify method to verify this return operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def TransposeOp : Toy_Op<"transpose",
@@ -275,8 +275,8 @@ def TransposeOp : Toy_Op<"transpose",
     OpBuilder<(ins "Value":$input)>
   ];
 
-  // Invoke a static verify method to verify this transpose operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 #endif // TOY_OPS

diff  --git a/mlir/examples/toy/Ch4/mlir/Dialect.cpp b/mlir/examples/toy/Ch4/mlir/Dialect.cpp
index 183cd59261da8..b5ef04450aace 100644
--- a/mlir/examples/toy/Ch4/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch4/mlir/Dialect.cpp
@@ -182,29 +182,28 @@ static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
   printer << op.value();
 }
 
-/// Verifier for the constant operation. This corresponds to the `::verify(...)`
-/// in the op definition.
-static mlir::LogicalResult verify(ConstantOp op) {
+/// Verifier for the constant operation. This corresponds to the
+/// `let hasVerifier = 1` in the op definition.
+mlir::LogicalResult ConstantOp::verify() {
   // If the return type of the constant is not an unranked tensor, the shape
   // must match the shape of the attribute holding the data.
-  auto resultType = op.getResult().getType().dyn_cast<mlir::RankedTensorType>();
+  auto resultType = getResult().getType().dyn_cast<mlir::RankedTensorType>();
   if (!resultType)
     return success();
 
   // Check that the rank of the attribute type matches the rank of the constant
   // result type.
-  auto attrType = op.value().getType().cast<mlir::TensorType>();
+  auto attrType = value().getType().cast<mlir::TensorType>();
   if (attrType.getRank() != resultType.getRank()) {
-    return op.emitOpError(
-               "return type must match the one of the attached value "
-               "attribute: ")
+    return emitOpError("return type must match the one of the attached value "
+                       "attribute: ")
            << attrType.getRank() << " != " << resultType.getRank();
   }
 
   // Check that each of the dimensions match between the two types.
   for (int dim = 0, dimE = attrType.getRank(); dim < dimE; ++dim) {
     if (attrType.getShape()[dim] != resultType.getShape()[dim]) {
-      return op.emitOpError(
+      return emitOpError(
                  "return type shape mismatches its attribute at dimension ")
              << dim << ": " << attrType.getShape()[dim]
              << " != " << resultType.getShape()[dim];
@@ -286,28 +285,27 @@ void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
 //===----------------------------------------------------------------------===//
 // ReturnOp
 
-static mlir::LogicalResult verify(ReturnOp op) {
+mlir::LogicalResult ReturnOp::verify() {
   // We know that the parent operation is a function, because of the 'HasParent'
   // trait attached to the operation definition.
-  auto function = cast<FuncOp>(op->getParentOp());
+  auto function = cast<FuncOp>((*this)->getParentOp());
 
   /// ReturnOps can only have a single optional operand.
-  if (op.getNumOperands() > 1)
-    return op.emitOpError() << "expects at most 1 return operand";
+  if (getNumOperands() > 1)
+    return emitOpError() << "expects at most 1 return operand";
 
   // The operand number and types must match the function signature.
   const auto &results = function.getType().getResults();
-  if (op.getNumOperands() != results.size())
-    return op.emitOpError()
-           << "does not return the same number of values ("
-           << op.getNumOperands() << ") as the enclosing function ("
-           << results.size() << ")";
+  if (getNumOperands() != results.size())
+    return emitOpError() << "does not return the same number of values ("
+                         << getNumOperands() << ") as the enclosing function ("
+                         << results.size() << ")";
 
   // If the operation does not have an input, we are done.
-  if (!op.hasOperand())
+  if (!hasOperand())
     return mlir::success();
 
-  auto inputType = *op.operand_type_begin();
+  auto inputType = *operand_type_begin();
   auto resultType = results.front();
 
   // Check that the result type of the function matches the operand type.
@@ -315,9 +313,9 @@ static mlir::LogicalResult verify(ReturnOp op) {
       resultType.isa<mlir::UnrankedTensorType>())
     return mlir::success();
 
-  return op.emitError() << "type of return operand (" << inputType
-                        << ") doesn't match function result type ("
-                        << resultType << ")";
+  return emitError() << "type of return operand (" << inputType
+                     << ") doesn't match function result type (" << resultType
+                     << ")";
 }
 
 //===----------------------------------------------------------------------===//
@@ -335,16 +333,16 @@ void TransposeOp::inferShapes() {
   getResult().setType(RankedTensorType::get(dims, arrayTy.getElementType()));
 }
 
-static mlir::LogicalResult verify(TransposeOp op) {
-  auto inputType = op.getOperand().getType().dyn_cast<RankedTensorType>();
-  auto resultType = op.getType().dyn_cast<RankedTensorType>();
+mlir::LogicalResult TransposeOp::verify() {
+  auto inputType = getOperand().getType().dyn_cast<RankedTensorType>();
+  auto resultType = getType().dyn_cast<RankedTensorType>();
   if (!inputType || !resultType)
     return mlir::success();
 
   auto inputShape = inputType.getShape();
   if (!std::equal(inputShape.begin(), inputShape.end(),
                   resultType.getShape().rbegin())) {
-    return op.emitError()
+    return emitError()
            << "expected result shape to be a transpose of the input";
   }
   return mlir::success();

diff  --git a/mlir/examples/toy/Ch5/include/toy/Ops.td b/mlir/examples/toy/Ch5/include/toy/Ops.td
index ea7689cf8acc1..22f96abeb02c3 100644
--- a/mlir/examples/toy/Ch5/include/toy/Ops.td
+++ b/mlir/examples/toy/Ch5/include/toy/Ops.td
@@ -78,8 +78,8 @@ def ConstantOp : Toy_Op<"constant", [NoSideEffect]> {
     OpBuilder<(ins "double":$value)>
   ];
 
-  // Invoke a static verify method to verify this constant operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def AddOp : Toy_Op<"add",
@@ -253,8 +253,8 @@ def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
     bool hasOperand() { return getNumOperands() != 0; }
   }];
 
-  // Invoke a static verify method to verify this return operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def TransposeOp : Toy_Op<"transpose",
@@ -276,8 +276,8 @@ def TransposeOp : Toy_Op<"transpose",
     OpBuilder<(ins "Value":$input)>
   ];
 
-  // Invoke a static verify method to verify this transpose operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 #endif // TOY_OPS

diff  --git a/mlir/examples/toy/Ch5/mlir/Dialect.cpp b/mlir/examples/toy/Ch5/mlir/Dialect.cpp
index f4ded4956c978..bf1d2a581d037 100644
--- a/mlir/examples/toy/Ch5/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch5/mlir/Dialect.cpp
@@ -182,29 +182,28 @@ static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
   printer << op.value();
 }
 
-/// Verifier for the constant operation. This corresponds to the `::verify(...)`
-/// in the op definition.
-static mlir::LogicalResult verify(ConstantOp op) {
+/// Verifier for the constant operation. This corresponds to the
+/// `let hasVerifier = 1` in the op definition.
+mlir::LogicalResult ConstantOp::verify() {
   // If the return type of the constant is not an unranked tensor, the shape
   // must match the shape of the attribute holding the data.
-  auto resultType = op.getResult().getType().dyn_cast<mlir::RankedTensorType>();
+  auto resultType = getResult().getType().dyn_cast<mlir::RankedTensorType>();
   if (!resultType)
     return success();
 
   // Check that the rank of the attribute type matches the rank of the constant
   // result type.
-  auto attrType = op.value().getType().cast<mlir::TensorType>();
+  auto attrType = value().getType().cast<mlir::TensorType>();
   if (attrType.getRank() != resultType.getRank()) {
-    return op.emitOpError(
-               "return type must match the one of the attached value "
-               "attribute: ")
+    return emitOpError("return type must match the one of the attached value "
+                       "attribute: ")
            << attrType.getRank() << " != " << resultType.getRank();
   }
 
   // Check that each of the dimensions match between the two types.
   for (int dim = 0, dimE = attrType.getRank(); dim < dimE; ++dim) {
     if (attrType.getShape()[dim] != resultType.getShape()[dim]) {
-      return op.emitOpError(
+      return emitOpError(
                  "return type shape mismatches its attribute at dimension ")
              << dim << ": " << attrType.getShape()[dim]
              << " != " << resultType.getShape()[dim];
@@ -286,28 +285,27 @@ void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
 //===----------------------------------------------------------------------===//
 // ReturnOp
 
-static mlir::LogicalResult verify(ReturnOp op) {
+mlir::LogicalResult ReturnOp::verify() {
   // We know that the parent operation is a function, because of the 'HasParent'
   // trait attached to the operation definition.
-  auto function = cast<FuncOp>(op->getParentOp());
+  auto function = cast<FuncOp>((*this)->getParentOp());
 
   /// ReturnOps can only have a single optional operand.
-  if (op.getNumOperands() > 1)
-    return op.emitOpError() << "expects at most 1 return operand";
+  if (getNumOperands() > 1)
+    return emitOpError() << "expects at most 1 return operand";
 
   // The operand number and types must match the function signature.
   const auto &results = function.getType().getResults();
-  if (op.getNumOperands() != results.size())
-    return op.emitOpError()
-           << "does not return the same number of values ("
-           << op.getNumOperands() << ") as the enclosing function ("
-           << results.size() << ")";
+  if (getNumOperands() != results.size())
+    return emitOpError() << "does not return the same number of values ("
+                         << getNumOperands() << ") as the enclosing function ("
+                         << results.size() << ")";
 
   // If the operation does not have an input, we are done.
-  if (!op.hasOperand())
+  if (!hasOperand())
     return mlir::success();
 
-  auto inputType = *op.operand_type_begin();
+  auto inputType = *operand_type_begin();
   auto resultType = results.front();
 
   // Check that the result type of the function matches the operand type.
@@ -315,9 +313,9 @@ static mlir::LogicalResult verify(ReturnOp op) {
       resultType.isa<mlir::UnrankedTensorType>())
     return mlir::success();
 
-  return op.emitError() << "type of return operand (" << inputType
-                        << ") doesn't match function result type ("
-                        << resultType << ")";
+  return emitError() << "type of return operand (" << inputType
+                     << ") doesn't match function result type (" << resultType
+                     << ")";
 }
 
 //===----------------------------------------------------------------------===//
@@ -335,16 +333,16 @@ void TransposeOp::inferShapes() {
   getResult().setType(RankedTensorType::get(dims, arrayTy.getElementType()));
 }
 
-static mlir::LogicalResult verify(TransposeOp op) {
-  auto inputType = op.getOperand().getType().dyn_cast<RankedTensorType>();
-  auto resultType = op.getType().dyn_cast<RankedTensorType>();
+mlir::LogicalResult TransposeOp::verify() {
+  auto inputType = getOperand().getType().dyn_cast<RankedTensorType>();
+  auto resultType = getType().dyn_cast<RankedTensorType>();
   if (!inputType || !resultType)
     return mlir::success();
 
   auto inputShape = inputType.getShape();
   if (!std::equal(inputShape.begin(), inputShape.end(),
                   resultType.getShape().rbegin())) {
-    return op.emitError()
+    return emitError()
            << "expected result shape to be a transpose of the input";
   }
   return mlir::success();

diff  --git a/mlir/examples/toy/Ch6/include/toy/Ops.td b/mlir/examples/toy/Ch6/include/toy/Ops.td
index 9d4c512036ae0..355c39bfce2f5 100644
--- a/mlir/examples/toy/Ch6/include/toy/Ops.td
+++ b/mlir/examples/toy/Ch6/include/toy/Ops.td
@@ -78,8 +78,8 @@ def ConstantOp : Toy_Op<"constant", [NoSideEffect]> {
     OpBuilder<(ins "double":$value)>
   ];
 
-  // Invoke a static verify method to verify this constant operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def AddOp : Toy_Op<"add",
@@ -253,8 +253,8 @@ def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
     bool hasOperand() { return getNumOperands() != 0; }
   }];
 
-  // Invoke a static verify method to verify this return operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def TransposeOp : Toy_Op<"transpose",
@@ -276,8 +276,8 @@ def TransposeOp : Toy_Op<"transpose",
     OpBuilder<(ins "Value":$input)>
   ];
 
-  // Invoke a static verify method to verify this transpose operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 #endif // TOY_OPS

diff  --git a/mlir/examples/toy/Ch6/mlir/Dialect.cpp b/mlir/examples/toy/Ch6/mlir/Dialect.cpp
index f4ded4956c978..bf1d2a581d037 100644
--- a/mlir/examples/toy/Ch6/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch6/mlir/Dialect.cpp
@@ -182,29 +182,28 @@ static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
   printer << op.value();
 }
 
-/// Verifier for the constant operation. This corresponds to the `::verify(...)`
-/// in the op definition.
-static mlir::LogicalResult verify(ConstantOp op) {
+/// Verifier for the constant operation. This corresponds to the
+/// `let hasVerifier = 1` in the op definition.
+mlir::LogicalResult ConstantOp::verify() {
   // If the return type of the constant is not an unranked tensor, the shape
   // must match the shape of the attribute holding the data.
-  auto resultType = op.getResult().getType().dyn_cast<mlir::RankedTensorType>();
+  auto resultType = getResult().getType().dyn_cast<mlir::RankedTensorType>();
   if (!resultType)
     return success();
 
   // Check that the rank of the attribute type matches the rank of the constant
   // result type.
-  auto attrType = op.value().getType().cast<mlir::TensorType>();
+  auto attrType = value().getType().cast<mlir::TensorType>();
   if (attrType.getRank() != resultType.getRank()) {
-    return op.emitOpError(
-               "return type must match the one of the attached value "
-               "attribute: ")
+    return emitOpError("return type must match the one of the attached value "
+                       "attribute: ")
            << attrType.getRank() << " != " << resultType.getRank();
   }
 
   // Check that each of the dimensions match between the two types.
   for (int dim = 0, dimE = attrType.getRank(); dim < dimE; ++dim) {
     if (attrType.getShape()[dim] != resultType.getShape()[dim]) {
-      return op.emitOpError(
+      return emitOpError(
                  "return type shape mismatches its attribute at dimension ")
              << dim << ": " << attrType.getShape()[dim]
              << " != " << resultType.getShape()[dim];
@@ -286,28 +285,27 @@ void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
 //===----------------------------------------------------------------------===//
 // ReturnOp
 
-static mlir::LogicalResult verify(ReturnOp op) {
+mlir::LogicalResult ReturnOp::verify() {
   // We know that the parent operation is a function, because of the 'HasParent'
   // trait attached to the operation definition.
-  auto function = cast<FuncOp>(op->getParentOp());
+  auto function = cast<FuncOp>((*this)->getParentOp());
 
   /// ReturnOps can only have a single optional operand.
-  if (op.getNumOperands() > 1)
-    return op.emitOpError() << "expects at most 1 return operand";
+  if (getNumOperands() > 1)
+    return emitOpError() << "expects at most 1 return operand";
 
   // The operand number and types must match the function signature.
   const auto &results = function.getType().getResults();
-  if (op.getNumOperands() != results.size())
-    return op.emitOpError()
-           << "does not return the same number of values ("
-           << op.getNumOperands() << ") as the enclosing function ("
-           << results.size() << ")";
+  if (getNumOperands() != results.size())
+    return emitOpError() << "does not return the same number of values ("
+                         << getNumOperands() << ") as the enclosing function ("
+                         << results.size() << ")";
 
   // If the operation does not have an input, we are done.
-  if (!op.hasOperand())
+  if (!hasOperand())
     return mlir::success();
 
-  auto inputType = *op.operand_type_begin();
+  auto inputType = *operand_type_begin();
   auto resultType = results.front();
 
   // Check that the result type of the function matches the operand type.
@@ -315,9 +313,9 @@ static mlir::LogicalResult verify(ReturnOp op) {
       resultType.isa<mlir::UnrankedTensorType>())
     return mlir::success();
 
-  return op.emitError() << "type of return operand (" << inputType
-                        << ") doesn't match function result type ("
-                        << resultType << ")";
+  return emitError() << "type of return operand (" << inputType
+                     << ") doesn't match function result type (" << resultType
+                     << ")";
 }
 
 //===----------------------------------------------------------------------===//
@@ -335,16 +333,16 @@ void TransposeOp::inferShapes() {
   getResult().setType(RankedTensorType::get(dims, arrayTy.getElementType()));
 }
 
-static mlir::LogicalResult verify(TransposeOp op) {
-  auto inputType = op.getOperand().getType().dyn_cast<RankedTensorType>();
-  auto resultType = op.getType().dyn_cast<RankedTensorType>();
+mlir::LogicalResult TransposeOp::verify() {
+  auto inputType = getOperand().getType().dyn_cast<RankedTensorType>();
+  auto resultType = getType().dyn_cast<RankedTensorType>();
   if (!inputType || !resultType)
     return mlir::success();
 
   auto inputShape = inputType.getShape();
   if (!std::equal(inputShape.begin(), inputShape.end(),
                   resultType.getShape().rbegin())) {
-    return op.emitError()
+    return emitError()
            << "expected result shape to be a transpose of the input";
   }
   return mlir::success();

diff  --git a/mlir/examples/toy/Ch7/include/toy/Ops.td b/mlir/examples/toy/Ch7/include/toy/Ops.td
index 4f89ed0742e8f..d17e0944a8196 100644
--- a/mlir/examples/toy/Ch7/include/toy/Ops.td
+++ b/mlir/examples/toy/Ch7/include/toy/Ops.td
@@ -94,8 +94,8 @@ def ConstantOp : Toy_Op<"constant",
     OpBuilder<(ins "double":$value)>
   ];
 
-  // Invoke a static verify method to verify this constant operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 
   // Set the folder bit so that we can implement constant folders.
   let hasFolder = 1;
@@ -273,8 +273,8 @@ def ReturnOp : Toy_Op<"return", [NoSideEffect, HasParent<"FuncOp">,
     bool hasOperand() { return getNumOperands() != 0; }
   }];
 
-  // Invoke a static verify method to verify this return operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 def StructAccessOp : Toy_Op<"struct_access", [NoSideEffect]> {
@@ -295,7 +295,8 @@ def StructAccessOp : Toy_Op<"struct_access", [NoSideEffect]> {
     OpBuilder<(ins "Value":$input, "size_t":$index)>
   ];
 
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 
   // Set the folder bit so that we can fold constant accesses.
   let hasFolder = 1;
@@ -320,7 +321,8 @@ def StructConstantOp : Toy_Op<"struct_constant", [ConstantLike, NoSideEffect]> {
 
   let assemblyFormat = "$value attr-dict `:` type($output)";
 
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
   let hasFolder = 1;
 }
 
@@ -343,8 +345,8 @@ def TransposeOp : Toy_Op<"transpose",
     OpBuilder<(ins "Value":$input)>
   ];
 
-  // Invoke a static verify method to verify this transpose operation.
-  let verifier = [{ return ::verify(*this); }];
+  // Indicate that additional verification for this operation is necessary.
+  let hasVerifier = 1;
 }
 
 #endif // TOY_OPS

diff  --git a/mlir/examples/toy/Ch7/mlir/Dialect.cpp b/mlir/examples/toy/Ch7/mlir/Dialect.cpp
index 0bf5f7593758b..3974c111e16a0 100644
--- a/mlir/examples/toy/Ch7/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch7/mlir/Dialect.cpp
@@ -227,12 +227,12 @@ static mlir::LogicalResult verifyConstantForType(mlir::Type type,
 
 /// Verifier for the constant operation. This corresponds to the `::verify(...)`
 /// in the op definition.
-static mlir::LogicalResult verify(ConstantOp op) {
-  return verifyConstantForType(op.getResult().getType(), op.value(), op);
+mlir::LogicalResult ConstantOp::verify() {
+  return verifyConstantForType(getResult().getType(), value(), *this);
 }
 
-static mlir::LogicalResult verify(StructConstantOp op) {
-  return verifyConstantForType(op.getResult().getType(), op.value(), op);
+mlir::LogicalResult StructConstantOp::verify() {
+  return verifyConstantForType(getResult().getType(), value(), *this);
 }
 
 /// Infer the output shape of the ConstantOp, this is required by the shape
@@ -312,28 +312,27 @@ void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
 //===----------------------------------------------------------------------===//
 // ReturnOp
 
-static mlir::LogicalResult verify(ReturnOp op) {
+mlir::LogicalResult ReturnOp::verify() {
   // We know that the parent operation is a function, because of the 'HasParent'
   // trait attached to the operation definition.
-  auto function = cast<FuncOp>(op->getParentOp());
+  auto function = cast<FuncOp>((*this)->getParentOp());
 
   /// ReturnOps can only have a single optional operand.
-  if (op.getNumOperands() > 1)
-    return op.emitOpError() << "expects at most 1 return operand";
+  if (getNumOperands() > 1)
+    return emitOpError() << "expects at most 1 return operand";
 
   // The operand number and types must match the function signature.
   const auto &results = function.getType().getResults();
-  if (op.getNumOperands() != results.size())
-    return op.emitOpError()
-           << "does not return the same number of values ("
-           << op.getNumOperands() << ") as the enclosing function ("
-           << results.size() << ")";
+  if (getNumOperands() != results.size())
+    return emitOpError() << "does not return the same number of values ("
+                         << getNumOperands() << ") as the enclosing function ("
+                         << results.size() << ")";
 
   // If the operation does not have an input, we are done.
-  if (!op.hasOperand())
+  if (!hasOperand())
     return mlir::success();
 
-  auto inputType = *op.operand_type_begin();
+  auto inputType = *operand_type_begin();
   auto resultType = results.front();
 
   // Check that the result type of the function matches the operand type.
@@ -341,9 +340,9 @@ static mlir::LogicalResult verify(ReturnOp op) {
       resultType.isa<mlir::UnrankedTensorType>())
     return mlir::success();
 
-  return op.emitError() << "type of return operand (" << inputType
-                        << ") doesn't match function result type ("
-                        << resultType << ")";
+  return emitError() << "type of return operand (" << inputType
+                     << ") doesn't match function result type (" << resultType
+                     << ")";
 }
 
 //===----------------------------------------------------------------------===//
@@ -360,16 +359,16 @@ void StructAccessOp::build(mlir::OpBuilder &b, mlir::OperationState &state,
   build(b, state, resultType, input, b.getI64IntegerAttr(index));
 }
 
-static mlir::LogicalResult verify(StructAccessOp op) {
-  StructType structTy = op.input().getType().cast<StructType>();
-  size_t index = op.index();
-  if (index >= structTy.getNumElementTypes())
-    return op.emitOpError()
+mlir::LogicalResult StructAccessOp::verify() {
+  StructType structTy = input().getType().cast<StructType>();
+  size_t indexValue = index();
+  if (indexValue >= structTy.getNumElementTypes())
+    return emitOpError()
            << "index should be within the range of the input struct type";
-  mlir::Type resultType = op.getResult().getType();
-  if (resultType != structTy.getElementTypes()[index])
-    return op.emitOpError() << "must have the same result type as the struct "
-                               "element referred to by the index";
+  mlir::Type resultType = getResult().getType();
+  if (resultType != structTy.getElementTypes()[indexValue])
+    return emitOpError() << "must have the same result type as the struct "
+                            "element referred to by the index";
   return mlir::success();
 }
 
@@ -388,16 +387,16 @@ void TransposeOp::inferShapes() {
   getResult().setType(RankedTensorType::get(dims, arrayTy.getElementType()));
 }
 
-static mlir::LogicalResult verify(TransposeOp op) {
-  auto inputType = op.getOperand().getType().dyn_cast<RankedTensorType>();
-  auto resultType = op.getType().dyn_cast<RankedTensorType>();
+mlir::LogicalResult TransposeOp::verify() {
+  auto inputType = getOperand().getType().dyn_cast<RankedTensorType>();
+  auto resultType = getType().dyn_cast<RankedTensorType>();
   if (!inputType || !resultType)
     return mlir::success();
 
   auto inputShape = inputType.getShape();
   if (!std::equal(inputShape.begin(), inputShape.end(),
                   resultType.getShape().rbegin())) {
-    return op.emitError()
+    return emitError()
            << "expected result shape to be a transpose of the input";
   }
   return mlir::success();


        


More information about the Mlir-commits mailing list