The parser/printer fields are deprecated and in the process of being removed.
Here we have stripped much of the format down to the bare essentials, and it has
become much more readable. To provide a custom assembly format, an operation can
-either override the `parser` and `printer` fields for a C++ format, or the
+either override the `hasCustomAssemblyFormat` field for a C++ format, or the
`assemblyFormat` field for the declarative format. Let's look at the C++ variant
first, as this is what the declarative format maps to internally.
def PrintOp : Toy_Op<"print"> {
let arguments = (ins F64Tensor:$input);
- // Divert the printer and parser to static functions in our .cpp
- // file that correspond to 'print' and 'printPrintOp'. 'printer' and 'parser'
- // here correspond to an instance of a 'OpAsmParser' and 'OpAsmPrinter'. More
- // details on these classes is shown below.
- let printer = [{ return ::print(printer, *this); }];
- let parser = [{ return ::parse$cppClass(parser, result); }];
+ // Divert the printer and parser to `parse` and `print` methods on our operation,
+ // to be implemented in the .cpp file. More details on these methods is shown below.
+ let hasCustomAssemblyFormat = 1;
}
```
```c++
/// The 'OpAsmPrinter' class is a stream that will allows for formatting
/// strings, attributes, operands, types, etc.
-static void print(mlir::OpAsmPrinter &printer, PrintOp op) {
+void PrintOp::print(mlir::OpAsmPrinter &printer) {
printer << "toy.print " << op.input();
printer.printOptionalAttrDict(op.getAttrs());
printer << " : " << op.input().getType();
/// or `false` on success. This allows for easily chaining together a set of
/// parser rules. These rules are used to populate an `mlir::OperationState`
/// similarly to the `build` methods described above.
-static mlir::ParseResult parsePrintOp(mlir::OpAsmParser &parser,
- mlir::OperationState &result) {
+mlir::ParseResult PrintOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
// Parse the input operand, the attribute dictionary, and the type of the
// input.
mlir::OpAsmParser::OperandType inputOperand;
// The constant operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseConstantOp(parser, result); }];
- let printer = [{ return ::print(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Add custom build methods for the constant operation. These method populates
// the `state` that MLIR uses to create operations, i.e. these are used when
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building an AddOp with from the two input operands.
let builders = [
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building a MulOp with from the two input operands.
let builders = [
/// or `false` on success. This allows for easily chaining together a set of
/// parser rules. These rules are used to populate an `mlir::OperationState`
/// similarly to the `build` methods described above.
-static mlir::ParseResult parseConstantOp(mlir::OpAsmParser &parser,
- mlir::OperationState &result) {
+mlir::ParseResult ConstantOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
mlir::DenseElementsAttr value;
if (parser.parseOptionalAttrDict(result.attributes) ||
parser.parseAttribute(value, "value", result.attributes))
/// The 'OpAsmPrinter' class is a stream that allows for formatting
/// strings, attributes, operands, types, etc.
-static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
+void ConstantOp::print(mlir::OpAsmPrinter &printer) {
printer << " ";
- printer.printOptionalAttrDict(op->getAttrs(), /*elidedAttrs=*/{"value"});
- printer << op.value();
+ printer.printOptionalAttrDict((*this)->getAttrs(), /*elidedAttrs=*/{"value"});
+ printer << value();
}
/// Verifier for the constant operation. This corresponds to the
state.addOperands({lhs, rhs});
}
+mlir::ParseResult AddOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void AddOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
//===----------------------------------------------------------------------===//
// GenericCallOp
state.addOperands({lhs, rhs});
}
+mlir::ParseResult MulOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void MulOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
//===----------------------------------------------------------------------===//
// ReturnOp
// The constant operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseConstantOp(parser, result); }];
- let printer = [{ return ::print(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Add custom build methods for the constant operation. These method populates
// the `state` that MLIR uses to create operations, i.e. these are used when
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building an AddOp with from the two input operands.
let builders = [
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building a MulOp with from the two input operands.
let builders = [
/// or `false` on success. This allows for easily chaining together a set of
/// parser rules. These rules are used to populate an `mlir::OperationState`
/// similarly to the `build` methods described above.
-static mlir::ParseResult parseConstantOp(mlir::OpAsmParser &parser,
- mlir::OperationState &result) {
+mlir::ParseResult ConstantOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
mlir::DenseElementsAttr value;
if (parser.parseOptionalAttrDict(result.attributes) ||
parser.parseAttribute(value, "value", result.attributes))
/// The 'OpAsmPrinter' class is a stream that allows for formatting
/// strings, attributes, operands, types, etc.
-static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
+void ConstantOp::print(mlir::OpAsmPrinter &printer) {
printer << " ";
- printer.printOptionalAttrDict(op->getAttrs(), /*elidedAttrs=*/{"value"});
- printer << op.value();
+ printer.printOptionalAttrDict((*this)->getAttrs(), /*elidedAttrs=*/{"value"});
+ printer << value();
}
/// Verifier for the constant operation. This corresponds to the
state.addOperands({lhs, rhs});
}
+mlir::ParseResult AddOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void AddOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
//===----------------------------------------------------------------------===//
// GenericCallOp
state.addOperands({lhs, rhs});
}
+mlir::ParseResult MulOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void MulOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
//===----------------------------------------------------------------------===//
// ReturnOp
// The constant operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseConstantOp(parser, result); }];
- let printer = [{ return ::print(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Add custom build methods for the constant operation. These method populates
// the `state` that MLIR uses to create operations, i.e. these are used when
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building an AddOp with from the two input operands.
let builders = [
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building a MulOp with from the two input operands.
let builders = [
/// or `false` on success. This allows for easily chaining together a set of
/// parser rules. These rules are used to populate an `mlir::OperationState`
/// similarly to the `build` methods described above.
-static mlir::ParseResult parseConstantOp(mlir::OpAsmParser &parser,
- mlir::OperationState &result) {
+mlir::ParseResult ConstantOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
mlir::DenseElementsAttr value;
if (parser.parseOptionalAttrDict(result.attributes) ||
parser.parseAttribute(value, "value", result.attributes))
/// The 'OpAsmPrinter' class is a stream that allows for formatting
/// strings, attributes, operands, types, etc.
-static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
+void ConstantOp::print(mlir::OpAsmPrinter &printer) {
printer << " ";
- printer.printOptionalAttrDict(op->getAttrs(), /*elidedAttrs=*/{"value"});
- printer << op.value();
+ printer.printOptionalAttrDict((*this)->getAttrs(), /*elidedAttrs=*/{"value"});
+ printer << value();
}
/// Verifier for the constant operation. This corresponds to the
state.addOperands({lhs, rhs});
}
+mlir::ParseResult AddOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void AddOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
/// Infer the output shape of the AddOp, this is required by the shape inference
/// interface.
void AddOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
state.addOperands({lhs, rhs});
}
+mlir::ParseResult MulOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void MulOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
/// Infer the output shape of the MulOp, this is required by the shape inference
/// interface.
void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
// The constant operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseConstantOp(parser, result); }];
- let printer = [{ return ::print(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Add custom build methods for the constant operation. These method populates
// the `state` that MLIR uses to create operations, i.e. these are used when
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building an AddOp with from the two input operands.
let builders = [
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building a MulOp with from the two input operands.
let builders = [
/// or `false` on success. This allows for easily chaining together a set of
/// parser rules. These rules are used to populate an `mlir::OperationState`
/// similarly to the `build` methods described above.
-static mlir::ParseResult parseConstantOp(mlir::OpAsmParser &parser,
- mlir::OperationState &result) {
+mlir::ParseResult ConstantOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
mlir::DenseElementsAttr value;
if (parser.parseOptionalAttrDict(result.attributes) ||
parser.parseAttribute(value, "value", result.attributes))
/// The 'OpAsmPrinter' class is a stream that allows for formatting
/// strings, attributes, operands, types, etc.
-static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
+void ConstantOp::print(mlir::OpAsmPrinter &printer) {
printer << " ";
- printer.printOptionalAttrDict(op->getAttrs(), /*elidedAttrs=*/{"value"});
- printer << op.value();
+ printer.printOptionalAttrDict((*this)->getAttrs(), /*elidedAttrs=*/{"value"});
+ printer << value();
}
/// Verifier for the constant operation. This corresponds to the
state.addOperands({lhs, rhs});
}
+mlir::ParseResult AddOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void AddOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
/// Infer the output shape of the AddOp, this is required by the shape inference
/// interface.
void AddOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
state.addOperands({lhs, rhs});
}
+mlir::ParseResult MulOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void MulOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
/// Infer the output shape of the MulOp, this is required by the shape inference
/// interface.
void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
// The constant operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseConstantOp(parser, result); }];
- let printer = [{ return ::print(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Add custom build methods for the constant operation. These method populates
// the `state` that MLIR uses to create operations, i.e. these are used when
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building an AddOp with from the two input operands.
let builders = [
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building a MulOp with from the two input operands.
let builders = [
/// or `false` on success. This allows for easily chaining together a set of
/// parser rules. These rules are used to populate an `mlir::OperationState`
/// similarly to the `build` methods described above.
-static mlir::ParseResult parseConstantOp(mlir::OpAsmParser &parser,
- mlir::OperationState &result) {
+mlir::ParseResult ConstantOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
mlir::DenseElementsAttr value;
if (parser.parseOptionalAttrDict(result.attributes) ||
parser.parseAttribute(value, "value", result.attributes))
/// The 'OpAsmPrinter' class is a stream that allows for formatting
/// strings, attributes, operands, types, etc.
-static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
+void ConstantOp::print(mlir::OpAsmPrinter &printer) {
printer << " ";
- printer.printOptionalAttrDict(op->getAttrs(), /*elidedAttrs=*/{"value"});
- printer << op.value();
+ printer.printOptionalAttrDict((*this)->getAttrs(), /*elidedAttrs=*/{"value"});
+ printer << value();
}
/// Verifier for the constant operation. This corresponds to the
state.addOperands({lhs, rhs});
}
+mlir::ParseResult AddOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void AddOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
/// Infer the output shape of the AddOp, this is required by the shape inference
/// interface.
void AddOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
state.addOperands({lhs, rhs});
}
+mlir::ParseResult MulOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void MulOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
/// Infer the output shape of the MulOp, this is required by the shape inference
/// interface.
void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
// The constant operation returns a single value of TensorType.
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseConstantOp(parser, result); }];
- let printer = [{ return ::print(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Add custom build methods for the constant operation. These method populates
// the `state` that MLIR uses to create operations, i.e. these are used when
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building an AddOp with from the two input operands.
let builders = [
let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs);
let results = (outs F64Tensor);
- // Specify a parser and printer method.
- let parser = [{ return ::parseBinaryOp(parser, result); }];
- let printer = [{ return ::printBinaryOp(p, *this); }];
+ // Indicate that the operation has a custom parser and printer method.
+ let hasCustomAssemblyFormat = 1;
// Allow building a MulOp with from the two input operands.
let builders = [
/// or `false` on success. This allows for easily chaining together a set of
/// parser rules. These rules are used to populate an `mlir::OperationState`
/// similarly to the `build` methods described above.
-static mlir::ParseResult parseConstantOp(mlir::OpAsmParser &parser,
- mlir::OperationState &result) {
+mlir::ParseResult ConstantOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
mlir::DenseElementsAttr value;
if (parser.parseOptionalAttrDict(result.attributes) ||
parser.parseAttribute(value, "value", result.attributes))
/// The 'OpAsmPrinter' class is a stream that allows for formatting
/// strings, attributes, operands, types, etc.
-static void print(mlir::OpAsmPrinter &printer, ConstantOp op) {
+void ConstantOp::print(mlir::OpAsmPrinter &printer) {
printer << " ";
- printer.printOptionalAttrDict(op->getAttrs(), /*elidedAttrs=*/{"value"});
- printer << op.value();
+ printer.printOptionalAttrDict((*this)->getAttrs(), /*elidedAttrs=*/{"value"});
+ printer << value();
}
/// Verify that the given attribute value is valid for the given type.
state.addOperands({lhs, rhs});
}
+mlir::ParseResult AddOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void AddOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
/// Infer the output shape of the AddOp, this is required by the shape inference
/// interface.
void AddOp::inferShapes() { getResult().setType(getOperand(0).getType()); }
state.addOperands({lhs, rhs});
}
+mlir::ParseResult MulOp::parse(mlir::OpAsmParser &parser,
+ mlir::OperationState &result) {
+ return parseBinaryOp(parser, result);
+}
+
+void MulOp::print(mlir::OpAsmPrinter &p) { printBinaryOp(p, *this); }
+
/// Infer the output shape of the MulOp, this is required by the shape inference
/// interface.
void MulOp::inferShapes() { getResult().setType(getOperand(0).getType()); }