Right now constraint/predicate traits/etc. use their "description" field as a one line human readable string. This breaks the current convention, by which a "description" may be multi-line. This revision renames the "description" field in these cases to "summary" which matches what the string is actually used as. This also unbreaks the use of TypeDefs(and eventually AttrDefs) in conjunction with existing type constraint facilities like `Optional`.
Differential Revision: https://reviews.llvm.org/D94133
defining operations and data types in a table-driven manner. This is achieved
via [TableGen][TableGen], which is both a generic language and its tooling to
maintain records of domain-specific information. Facts regarding an operation
-are specified concisely into a TableGen record, which will be expanded into
-an equivalent `mlir::Op` C++ template specialization at compiler build time.
+are specified concisely into a TableGen record, which will be expanded into an
+equivalent `mlir::Op` C++ template specialization at compiler build time.
This manual explains in detail all the available mechanisms for defining
operations in such a table-driven manner. It aims to be a specification instead
-of a tutorial. Please refer to [Quickstart tutorial to adding MLIR graph
-rewrite](Tutorials/QuickstartRewrites.md) for the latter.
+of a tutorial. Please refer to
+[Quickstart tutorial to adding MLIR graph rewrite](Tutorials/QuickstartRewrites.md)
+for the latter.
-In addition to detailing each mechanism, this manual also tries to capture
-best practices. They are rendered as quoted bullet points.
+In addition to detailing each mechanism, this manual also tries to capture best
+practices. They are rendered as quoted bullet points.
## Motivation
problem, e.g., repetitive string comparisons during optimization and analysis
passes, unintuitive accessor methods (e.g., generic/error prone `getOperand(3)`
vs self-documenting `getStride()`) with more generic return types, verbose and
-generic constructors without default arguments, verbose textual IR dump, and
-so on. Furthermore, operation verification is:
+generic constructors without default arguments, verbose textual IR dump, and so
+on. Furthermore, operation verification is:
-1. best case: a central string-to-verification-function map,
-1. middle case: duplication of verification across the code base, or
-1. worst case: no verification functions.
+1. best case: a central string-to-verification-function map,
+1. middle case: duplication of verification across the code base, or
+1. worst case: no verification functions.
The fix is to support defining ops in a table-driven manner. Then for each
dialect, we can have a central place that contains everything you need to know
Compared to the C++ template, this table-driven approach has several benefits
including but not limited to:
-* **Single source of truth**: We strive to encode all facts regarding an
- operation into the record, so that readers don't need to jump among code
- snippets to fully understand an operation.
-* **Removing boilerplate**: We can automatically generate
- operand/attribute/result getter methods, operation build methods, operation
- verify methods, and many more utilities from the record. This greatly reduces
- the boilerplate needed for defining a new op.
-* **Facilitating auto-generation**: The usage of these operation information
- records are by no means limited to op definition itself. We can use them to
- drive the auto-generation of many other components, like computation graph
- serialization.
+* **Single source of truth**: We strive to encode all facts regarding an
+ operation into the record, so that readers don't need to jump among code
+ snippets to fully understand an operation.
+* **Removing boilerplate**: We can automatically generate
+ operand/attribute/result getter methods, operation build methods, operation
+ verify methods, and many more utilities from the record. This greatly
+ reduces the boilerplate needed for defining a new op.
+* **Facilitating auto-generation**: The usage of these operation information
+ records are by no means limited to op definition itself. We can use them to
+ drive the auto-generation of many other components, like computation graph
+ serialization.
## TableGen Syntax
}
```
-In the following we describe all the fields needed. Please see the definition
-of the `Op` class for the complete list of fields supported.
+In the following we describe all the fields needed. Please see the definition of
+the `Op` class for the complete list of fields supported.
### Operation name
`description` should be written in Markdown syntax.
-Placing the documentation at the beginning is recommended since
-it helps in understanding the operation.
+Placing the documentation at the beginning is recommended since it helps in
+understanding the operation.
-> * Place documentation at the beginning of the operation definition
-> * The summary should be short and concise. It should be a one-liner without
-> trailing punctuation. Put expanded explanation in description.
+> * Place documentation at the beginning of the operation definition
+> * The summary should be short and concise. It should be a one-liner without
+> trailing punctuation. Put expanded explanation in description.
### Operation arguments
values produced by other ops; while attributes are compile-time known constant
values, including two categories:
-1. Natural attributes: these attributes affect the behavior of the operations
- (e.g., padding for convolution);
-1. Derived attributes: these attributes are not needed to define the operation
- but are instead derived from information of the operation. E.g., the output
- shape of type. This is mostly used for convenience interface generation or
- interaction with other frameworks/translation.
+1. Natural attributes: these attributes affect the behavior of the operations
+ (e.g., padding for convolution);
+1. Derived attributes: these attributes are not needed to define the operation
+ but are instead derived from information of the operation. E.g., the output
+ shape of type. This is mostly used for convenience interface generation or
+ interaction with other frameworks/translation.
- All derived attributes should be materializable as an Attribute. That is,
- even though they are not materialized, it should be possible to store as
- an attribute.
+ All derived attributes should be materializable as an Attribute. That is,
+ even though they are not materialized, it should be possible to store as an
+ attribute.
Both operands and attributes are specified inside the `dag`-typed `arguments`,
led by `ins`:
There is no requirements on the relative order of operands and attributes; they
can mix freely. The relative order of operands themselves matters. From each
named argument a named getter will be generated that returns the argument with
-the return type (in the case of attributes the return type will be
-constructed from the storage type, while for operands it will be `Value`). Each
-attribute's raw value (e.g., as stored) can also be accessed via generated
-`<name>Attr` getters for use in transformation passes where the more user
-friendly return type is less suitable.
+the return type (in the case of attributes the return type will be constructed
+from the storage type, while for operands it will be `Value`). Each attribute's
+raw value (e.g., as stored) can also be accessed via generated `<name>Attr`
+getters for use in transformation passes where the more user friendly return
+type is less suitable.
All the arguments should be named to 1) provide documentation, 2) drive
auto-generation of getter methods, 3) provide a handle to reference for other
#### Variadic results
-Similar to variadic operands, `Variadic<...>` can also be used for results.
-And similarly, `SameVariadicResultSize` for multiple variadic results in the
-same operation.
+Similar to variadic operands, `Variadic<...>` can also be used for results. And
+similarly, `SameVariadicResultSize` for multiple variadic results in the same
+operation.
### Operation successors
### Operation traits and constraints
-Traits are operation properties that affect syntax or semantics. MLIR C++
-models various traits in the `mlir::OpTrait` namespace.
+Traits are operation properties that affect syntax or semantics. MLIR C++ models
+various traits in the `mlir::OpTrait` namespace.
Both operation traits, [interfaces](Interfaces.md#utilizing-the-ods-framework),
and constraints involving multiple operands/attributes/results are provided as
### Custom verifier code
Verification code will be automatically generated for
-[constraints](#constraints) specified on various entities of the op. To
-perform _additional_ verification, you can use
+[constraints](#constraints) specified on various entities of the op. To perform
+_additional_ verification, you can use
```tablegen
let verifier = [{
would result in calls to `parseMyDirective` and `printMyDirective` within the
parser and printer respectively. `Params` may be any combination of variables
(i.e. Attribute, Operand, Successor, etc.), type directives, and `attr-dict`.
-The type directives must refer to a variable, but that variable need not also
-be a parameter to the custom directive.
+The type directives must refer to a variable, but that variable need not also be
+a parameter to the custom directive.
The arguments to the `parse<UserDirective>` method are firstly a reference to
the `OpAsmParser`(`OpAsmParser &`), and secondly a set of output parameters
When a variable is optional, the value should only be specified if the variable
is present. Otherwise, the value should remain `None` or null.
-The arguments to the `print<UserDirective>` method is firstly a reference to
-the `OpAsmPrinter`(`OpAsmPrinter &`), second the op (e.g. `FooOp op` which
-can be `Operation *op` alternatively), and finally a set of output parameters
+The arguments to the `print<UserDirective>` method is firstly a reference to the
+`OpAsmPrinter`(`OpAsmPrinter &`), second the op (e.g. `FooOp op` which can be
+`Operation *op` alternatively), and finally a set of output parameters
corresponding to the parameters specified in the format. The mapping of
declarative parameter to `print` method argument is detailed below:
via type constraints or other information available. In these cases, the type of
that variable may be elided from the format.
-* Buildable Types
+* Buildable Types
-Some type constraints may only have one representation, allowing for them to
-be directly buildable; for example the `I32` or `Index` types. Types in `ODS`
-may mark themselves as buildable by setting the `builderCall` field or
-inheriting from the `BuildableType` class.
+Some type constraints may only have one representation, allowing for them to be
+directly buildable; for example the `I32` or `Index` types. Types in `ODS` may
+mark themselves as buildable by setting the `builderCall` field or inheriting
+from the `BuildableType` class.
-* Trait Equality Constraints
+* Trait Equality Constraints
There are many operations that have known type equality constraints registered
as traits on the operation; for example the true, false, and result values of a
`select` operation often have the same type. The assembly format may inspect
these equal constraints to discern the types of missing variables. The currently
-supported traits are: `AllTypesMatch`, `TypesMatchWith`, `SameTypeOperands`,
-and `SameOperandsAndResultType`.
+supported traits are: `AllTypesMatch`, `TypesMatchWith`, `SameTypeOperands`, and
+`SameOperandsAndResultType`.
### `hasCanonicalizer`
### `hasFolder`
-This boolean field indicate whether general folding rules have been defined
-for this operation. If it is `1`, then `::fold()` should be defined.
+This boolean field indicate whether general folding rules have been defined for
+this operation. If it is `1`, then `::fold()` should be defined.
### Extra declarations
`extraClassDeclaration`. Code in `extraClassDeclaration` will be copied
literally to the generated C++ op class.
-Note that `extraClassDeclaration` is a mechanism intended for long-tail cases
-by power users; for not-yet-implemented widely-applicable cases, improving the
+Note that `extraClassDeclaration` is a mechanism intended for long-tail cases by
+power users; for not-yet-implemented widely-applicable cases, improving the
infrastructure is preferable.
### Generated C++ code
#### Class name and namespaces
For each operation, its generated C++ class name is the symbol `def`ed with
-TableGen with dialect prefix removed. The first `_` serves as the delimiter.
-For example, for `def TF_AddOp`, the C++ class name would be `AddOp`.
-We remove the `TF` prefix because it is for scoping ops; other dialects
-may as well define their own `AddOp`s.
+TableGen with dialect prefix removed. The first `_` serves as the delimiter. For
+example, for `def TF_AddOp`, the C++ class name would be `AddOp`. We remove the
+`TF` prefix because it is for scoping ops; other dialects may as well define
+their own `AddOp`s.
The namespaces of the generated C++ class will come from the dialect's
-`cppNamespace` field. For example, if a dialect's `cppNamespace` is `A::B`,
-then an op of that dialect will be placed in
-`namespace A { namespace B { ... } }`. If a dialect does not specify a
-`cppNamespace`, we then use the dialect's name as the namespace.
+`cppNamespace` field. For example, if a dialect's `cppNamespace` is `A::B`, then
+an op of that dialect will be placed in `namespace A { namespace B { ... } }`.
+If a dialect does not specify a `cppNamespace`, we then use the dialect's name
+as the namespace.
This means the qualified name of the generated C++ class does not necessarily
match exactly with the operation name as explained in
An operation's constraint can cover different range; it may
-* Only concern a single attribute (e.g. being a 32-bit integer greater than 5),
-* Multiple operands and results (e.g., the 1st result's shape must be the same
- as the 1st operand), or
-* Intrinsic to the operation itself (e.g., having no side effect).
+* Only concern a single attribute (e.g. being a 32-bit integer greater than
+ 5),
+* Multiple operands and results (e.g., the 1st result's shape must be the same
+ as the 1st operand), or
+* Intrinsic to the operation itself (e.g., having no side effect).
We call them as single-entity constraint, multi-entity constraint, and traits,
respectively.
To help modelling constraints of common types, a set of `TypeConstraint`s are
created; they are the `Type` subclass hierarchy. It includes `F32` for the
-constraints of being a float, `TensorOf<[F32]>` for the constraints of being
-a float tensor, and so on.
+constraints of being a float, `TensorOf<[F32]>` for the constraints of being a
+float tensor, and so on.
Similarly, a set of `AttrConstraint`s are created for helping modelling
constraints of common attribute kinds. They are the `Attr` subclass hierarchy.
### Multi-entity constraint
-Constraints involving more than one operand/attribute/result are quite common
-on operations, like the element type and shape relation between operands and
+Constraints involving more than one operand/attribute/result are quite common on
+operations, like the element type and shape relation between operands and
results. These constraints should be specified as the `Op` class template
parameter as described in
[Operation traits and constraints](#operation-traits-and-constraints).
substitution: `SubstLeaves`, concatenation: `Concat`).
`CPred` is the basis for composing more complex predicates. It is the "atom"
-predicate from the perspective of TableGen and the "interface" between
-TableGen and C++. What is inside is already C++ code, which will be treated
-as opaque strings with special placeholders to be substituted.
+predicate from the perspective of TableGen and the "interface" between TableGen
+and C++. What is inside is already C++ code, which will be treated as opaque
+strings with special placeholders to be substituted.
You can put any C++ code that returns a boolean value inside a `CPred`,
-including evaluating expressions, calling functions, calling class methods,
-and so on.
+including evaluating expressions, calling functions, calling class methods, and
+so on.
To help interaction with the C++ environment, there are a few special
placeholders provided to refer to entities in the context where this predicate
-is used. They serve as "hooks" to the enclosing environment. This includes
+is used. They serve as "hooks" to the enclosing environment. This includes
`$_builder`, `$_op`, and `$_self`:
-* `$_builder` will be replaced by a `mlir::Builder` instance so that you can
- access common build methods.
-* `$_op` will be replaced by the current operation so that you can access
- information of the current operation.
-* `$_self` will be replaced with the entity this predicate is attached to.
- E.g., `BoolAttr` is an attribute constraint that wraps a
- `CPred<"$_self.isa<BoolAttr>()">`. Then for `F32:$attr`,`$_self` will be
- replaced by `$attr`. For type constraints, it's a little bit special since
- we want the constraints on each type definition reads naturally and we want
- to attach type constraints directly to an operand/result, `$_self` will be
- replaced by the operand/result's type. E.g., for `F32` in `F32:$operand`, its
- `$_self` will be expanded as `getOperand(...).getType()`.
+* `$_builder` will be replaced by a `mlir::Builder` instance so that you can
+ access common build methods.
+* `$_op` will be replaced by the current operation so that you can access
+ information of the current operation.
+* `$_self` will be replaced with the entity this predicate is attached to.
+ E.g., `BoolAttr` is an attribute constraint that wraps a
+ `CPred<"$_self.isa<BoolAttr>()">`. Then for `F32:$attr`,`$_self` will be
+ replaced by `$attr`. For type constraints, it's a little bit special since
+ we want the constraints on each type definition reads naturally and we want
+ to attach type constraints directly to an operand/result, `$_self` will be
+ replaced by the operand/result's type. E.g., for `F32` in `F32:$operand`,
+ its `$_self` will be expanded as `getOperand(...).getType()`.
TODO: Reconsider the leading symbol for special placeholders. Eventually we want
to allow referencing operand/result $-names; such $-names can start with
`$_self.isa<IntegerAttr>()`, with `$_self` as the special placeholder to be
replaced by the current attribute `attr` at expansion time.
-For more complicated predicates, you can wrap it in a single `CPred`, or you
-can use predicate combiners to combine them. For example, to write the
-constraint that an attribute `attr` is a 32-bit or 64-bit integer, you can
-write it as
+For more complicated predicates, you can wrap it in a single `CPred`, or you can
+use predicate combiners to combine them. For example, to write the constraint
+that an attribute `attr` is a 32-bit or 64-bit integer, you can write it as
```tablegen
And<[
TODO: Build up a library of reusable primitive constraints
If the predicate is very complex to write with `CPred` together with predicate
-combiners, you can also write it as a normal C++ function and use the `CPred`
-as a way to "invoke" the function. For example, to verify an attribute `attr`
-has some property, you can write a C++ function like
+combiners, you can also write it as a normal C++ function and use the `CPred` as
+a way to "invoke" the function. For example, to verify an attribute `attr` has
+some property, you can write a C++ function like
```cpp
bool HasSomeProperty(Attribute attr) { ... }
}
```
-As to whether we should define the predicate using a single `CPred` wrapping
-the whole expression, multiple `CPred`s with predicate combiners, or a single
+As to whether we should define the predicate using a single `CPred` wrapping the
+whole expression, multiple `CPred`s with predicate combiners, or a single
`CPred` "invoking" a function, there are no clear-cut criteria. Defining using
`CPred` and predicate combiners is preferable since it exposes more information
(instead hiding all the logic behind a C++ function) into the op definition spec
-so that it can potentially drive more auto-generation cases. But it will
-require a nice library of common predicates as the building blocks to avoid the
+so that it can potentially drive more auto-generation cases. But it will require
+a nice library of common predicates as the building blocks to avoid the
duplication, which is being worked on right now.
## Attribute Definition
ODS provides attribute wrappers over C++ attribute classes. There are a few
common C++ [attribute classes][AttrClasses] defined in MLIR's core IR library
-and one is free to define dialect-specific attribute classes. ODS allows one
-to use these attributes in TableGen to define operations, potentially with
-more fine-grained constraints. For example, `StrAttr` directly maps to
-`StringAttr`; `F32Attr`/`F64Attr` requires the `FloatAttr` to additionally
-be of a certain bitwidth.
+and one is free to define dialect-specific attribute classes. ODS allows one to
+use these attributes in TableGen to define operations, potentially with more
+fine-grained constraints. For example, `StrAttr` directly maps to `StringAttr`;
+`F32Attr`/`F64Attr` requires the `FloatAttr` to additionally be of a certain
+bitwidth.
ODS attributes are defined as having a storage type (corresponding to a backing
`mlir::Attribute` that _stores_ the attribute), a return type (corresponding to
### TypeParameter tablegen class
This is used to further specify attributes about each of the types parameters.
-It includes documentation (`description` and `syntax`), the C++ type to use, and
-a custom allocator to use in the storage constructor method.
+It includes documentation (`summary` and `syntax`), the C++ type to use, and a
+custom allocator to use in the storage constructor method.
```tablegen
// DO NOT DO THIS!
### Run `mlir-tblgen` to see the generated content
-TableGen syntax sometimes can be obscure; reading the generated content can be
-a very helpful way to understand and debug issues. To build `mlir-tblgen`, run
+TableGen syntax sometimes can be obscure; reading the generated content can be a
+very helpful way to understand and debug issues. To build `mlir-tblgen`, run
`cmake --build . --target mlir-tblgen` in your build directory and find the
`mlir-tblgen` binary in the `bin/` subdirectory. All the supported generators
can be found via `mlir-tblgen --help`. For example, `--gen-op-decls` and
The op description should as declarative as possible to allow a wide range of
tools to work with them and query methods generated from them. In particular
-this means specifying traits, constraints and shape inference information in
-a way that is easily analyzable (e.g., avoid opaque calls to C++ functions where
+this means specifying traits, constraints and shape inference information in a
+way that is easily analyzable (e.g., avoid opaque calls to C++ functions where
possible).
We considered the approaches of several contemporary systems and focused on
CPred<"$_self.isa<ScalableVectorType>()">,
"scalable vector type">,
BuildableType<"$_builder.getType<ScalableVectorType>()"> {
- let typeDescription = [{
+ let description = [{
`arm_sve.vector` represents vectors that will be processed by a scalable
vector architecture.
}];
list<Type> allowedTypes> : Type<
And<[ScalableVectorOf<allowedTypes>.predicate,
ScalableVectorOfLength<allowedLengths>.predicate]>,
- ScalableVectorOf<allowedTypes>.description #
- ScalableVectorOfLength<allowedLengths>.description>;
+ ScalableVectorOf<allowedTypes>.summary #
+ ScalableVectorOfLength<allowedLengths>.summary>;
//===----------------------------------------------------------------------===//
// ArmSVE op definitions
def Async_TokenType : DialectType<AsyncDialect,
CPred<"$_self.isa<::mlir::async::TokenType>()">, "token type">,
BuildableType<"$_builder.getType<::mlir::async::TokenType>()"> {
- let typeDescription = [{
+ let description = [{
`async.token` is a type returned by asynchronous operations, and it becomes
`ready` when the asynchronous operations that created it is completed.
}];
SubstLeaves<"$_self",
"$_self.cast<::mlir::async::ValueType>().getValueType()",
type.predicate>
- ]>, "async value type with " # type.description # " underlying type"> {
- let typeDescription = [{
+ ]>, "async value type with " # type.summary # " underlying type"> {
+ let description = [{
`async.value` represents a value returned by asynchronous operations,
which may or may not be available currently, but will be available at some
point in the future.
def Async_GroupType : DialectType<AsyncDialect,
CPred<"$_self.isa<::mlir::async::GroupType>()">, "group type">,
BuildableType<"$_builder.getType<::mlir::async::GroupType>()"> {
- let typeDescription = [{
+ let description = [{
`async.group` represent a set of async tokens or values and allows to
execute async operations on all of them together (e.g. wait for the
completion of all/any of them).
"$_self",
"$_self.cast<::mlir::LLVM::LLVMPointerType>().getElementType()",
pointee.predicate>]>,
- "LLVM pointer to " # pointee.description>;
+ "LLVM pointer to " # pointee.summary>;
// Type constraint accepting any LLVM structure type.
def LLVM_AnyStruct : Type<CPred<"$_self.isa<::mlir::LLVM::LLVMStructType>()">,
"$_self",
"$_self.cast<::mlir::LLVM::LLVMVectorType>().getElementType()",
element.predicate>]>,
- "LLVM vector of " # element.description>;
+ "LLVM vector of " # element.summary>;
// Type constraint accepting a constrained type, or a vector of such types.
class LLVM_ScalarOrVectorOf<Type element> :
Type<Or<[etype.predicate,
TensorOf<[etype]>.predicate,
VectorOf<[etype]>.predicate]>,
- "primitive/tensor/vector of " # etype.description>;
+ "primitive/tensor/vector of " # etype.summary>;
// An implementation of QuantizedType.
def quant_QuantizedType :
def Shape_ShapeType : DialectType<ShapeDialect,
CPred<"$_self.isa<::mlir::shape::ShapeType>()">, "shape">,
BuildableType<"$_builder.getType<::mlir::shape::ShapeType>()"> {
- let typeDescription = [{
+ let description = [{
`shape.shape` represents either an unranked shape, a ranked shape with
possibly unknown dimensions or an invalid shape. The rank is of type
`shape.size` and, if rank is known, the extent is a 1D tensor of type
def Shape_SizeType : DialectType<ShapeDialect,
CPred<"$_self.isa<::mlir::shape::SizeType>()">, "size">,
BuildableType<"$_builder.getType<::mlir::shape::SizeType>()"> {
- let typeDescription = [{
+ let description = [{
`shape.size` represents a non-negative integer with support for being
unknown and invalid.
CPred<"$_self.isa<::mlir::shape::ValueShapeType>()">, "value shape">,
BuildableType<"::mlir::shape::ValueShapeType::get($_builder.getContext())">
{
- let typeDescription = [{
+ let description = [{
`shape.value_shape` represents the value produced by an operation (this
corresponds to `Value` in the compiler) and a shape. Conceptually this is a
tuple of a value (potentially unknown) and `shape.shape`. The value and
1DTensorOf<[Index]>,
BuildableType<"::mlir::RankedTensorType::get({ShapedType::kDynamicSize}, "
"$_builder.getType<::mlir::IndexType>())"> {
- let typeDescription = [{
+ let description = [{
The extent tensor is a tensor of rank one with arbitrarily many index
elements (tensor<?xindex>). Like `!shape.shape`, it is used to represent
shapes with the difference that it is guaranteed to be error-free.
def Shape_WitnessType : DialectType<ShapeDialect,
CPred<"$_self.isa<::mlir::shape::WitnessType>()">, "witness">,
BuildableType<"$_builder.getType<::mlir::shape::WitnessType>()"> {
- let typeDescription = [{
+ let description = [{
A witness is a structural device in the compiler to maintain ordering of
code relying on information obtained from passing assertions. Witnesses do
not represent any physical data.
StructFieldAttr<"input_zp", I32Attr>,
StructFieldAttr<"output_zp", I32Attr>
]> {
- let description = "Attribute for UnaryOp quantization information.";
+ let summary = "Attribute for UnaryOp quantization information.";
}
// There is no explicit BinaryOpQuantizationAttr for 2-input/1-output ops. In
StructFieldAttr<"input_zp", I32Attr>,
StructFieldAttr<"weight_zp", I32Attr>
]> {
- let description = "Attribute for Conv type op quantization information.";
+ let summary = "Attribute for Conv type op quantization information.";
}
def Tosa_MatMulOpQuantizationAttr : StructAttr<"MatMulOpQuantizationAttr",
StructFieldAttr<"a_zp", I32Attr>,
StructFieldAttr<"b_zp", I32Attr>
]> {
- let description = "Attribute for MatMulOp quantization information.";
+ let summary = "Attribute for MatMulOp quantization information.";
}
// This attribute holds input zero point correction applied to the padding
Tosa_Dialect, [
StructFieldAttr<"input_zp", I32Attr>
]> {
- let description = "Attribute for PadOp quantization information.";
+ let summary = "Attribute for PadOp quantization information.";
}
//===----------------------------------------------------------------------===//
class Constraint<Pred pred, string desc = ""> {
// The predicates that this constraint requires.
Pred predicate = pred;
- // User-readable description used in error reporting messages. If empty, a
- // generic message will be used.
- string description = desc;
+ // User-readable one line summary used in error reporting messages. If empty,
+ // a generic message will be used.
+ string summary = desc;
}
// Subclasses used to differentiate different constraint kinds. These are used
// are considered as uncategorized constraints.
// Subclass for constraints on a type.
-class TypeConstraint<Pred predicate, string description = "",
+class TypeConstraint<Pred predicate, string summary = "",
string cppClassNameParam = "::mlir::Type"> :
- Constraint<predicate, description> {
+ Constraint<predicate, summary> {
// The name of the C++ Type class if known, or Type if not.
string cppClassName = cppClassNameParam;
}
// Subclass for constraints on an attribute.
-class AttrConstraint<Pred predicate, string description = ""> :
- Constraint<predicate, description>;
+class AttrConstraint<Pred predicate, string summary = ""> :
+ Constraint<predicate, summary>;
// Subclass for constraints on a region.
-class RegionConstraint<Pred predicate, string description = ""> :
- Constraint<predicate, description>;
+class RegionConstraint<Pred predicate, string summary = ""> :
+ Constraint<predicate, summary>;
// Subclass for constraints on a successor.
-class SuccessorConstraint<Pred predicate, string description = ""> :
- Constraint<predicate, description>;
+class SuccessorConstraint<Pred predicate, string summary = ""> :
+ Constraint<predicate, summary>;
// How to use these constraint categories:
//
class Type<Pred condition, string descr = "",
string cppClassName = "::mlir::Type"> :
TypeConstraint<condition, descr, cppClassName> {
- string typeDescription = "";
+ string description = "";
string builderCall = "";
}
-// Allows providing an alternative name and description to an existing type def.
-class TypeAlias<Type t, string description = t.description> :
- Type<t.predicate, description> {
- let typeDescription = t.typeDescription;
+// Allows providing an alternative name and summary to an existing type def.
+class TypeAlias<Type t, string summary = t.summary> :
+ Type<t.predicate, summary> {
+ let description = t.description;
let builderCall = t.builderCall;
}
// A variadic type constraint. It expands to zero or more of the base type. This
// class is used for supporting variadic operands/results.
-class Variadic<Type type> : TypeConstraint<type.predicate, type.description> {
+class Variadic<Type type> : TypeConstraint<type.predicate, type.summary> {
Type baseType = type;
}
// An optional type constraint. It expands to either zero or one of the base
// type. This class is used for supporting optional operands/results.
-class Optional<Type type> : TypeConstraint<type.predicate, type.description> {
+class Optional<Type type> : TypeConstraint<type.predicate, type.summary> {
Type baseType = type;
}
BuildableType<"$_builder.getType<::mlir::NoneType>()">;
// Any type from the given list
-class AnyTypeOf<list<Type> allowedTypes, string description = "",
+class AnyTypeOf<list<Type> allowedTypes, string summary = "",
string cppClassName = "::mlir::Type"> : Type<
// Satisfy any of the allowed type's condition
Or<!foreach(allowedtype, allowedTypes, allowedtype.predicate)>,
- !if(!eq(description, ""),
- !interleave(!foreach(t, allowedTypes, t.description), " or "),
- description)>;
+ !if(!eq(summary, ""),
+ !interleave(!foreach(t, allowedTypes, t.summary), " or "),
+ summary)>;
// Integer types.
SubstLeaves<"$_self",
"$_self.cast<::mlir::ComplexType>().getElementType()",
type.predicate>]>,
- "complex type with " # type.description # " elements",
+ "complex type with " # type.summary # " elements",
"::mlir::ComplexType">,
SameBuildabilityAs<type, "::mlir::ComplexType::get($_builder.get" # type #
"Type())"> {
def AnyComplex : Type<CPred<"$_self.isa<::mlir::ComplexType>()">,
"complex-type", "::mlir::ComplexType">;
-class OpaqueType<string dialect, string name, string description>
+class OpaqueType<string dialect, string name, string summary>
: Type<CPred<"isOpaqueTypeWithName($_self, \""#dialect#"\", \""#name#"\")">,
- description, "::mlir::OpaqueType">,
+ summary, "::mlir::OpaqueType">,
BuildableType<"::mlir::OpaqueType::get($_builder.getContext(), "
"$_builder.getIdentifier(\"" # dialect # "\"), \""
# name # "\")">;
Type<And<[containerPred,
SubstLeaves<"$_self", !cast<string>(elementTypeCall),
etype.predicate>]>,
- descr # " of " # etype.description # " values", cppClassName> {
+ descr # " of " # etype.summary # " values", cppClassName> {
// The type of elements in the container.
Type elementType = etype;
list<Type> allowedTypes> : Type<
And<[VectorOf<allowedTypes>.predicate,
VectorOfRank<allowedRanks>.predicate]>,
- VectorOf<allowedTypes>.description #
- VectorOfRank<allowedRanks>.description,
+ VectorOf<allowedTypes>.summary # VectorOfRank<allowedRanks>.summary,
"::mlir::VectorType">;
// Whether the number of elements of a vector is from the given
list<Type> allowedTypes> : Type<
And<[VectorOf<allowedTypes>.predicate,
VectorOfLength<allowedLengths>.predicate]>,
- VectorOf<allowedTypes>.description #
- VectorOfLength<allowedLengths>.description,
+ VectorOf<allowedTypes>.summary # VectorOfLength<allowedLengths>.summary,
"::mlir::VectorType">;
def AnyVector : VectorOf<[AnyType]>;
// TODO: Have an easy way to add another constraint to a type.
class StaticShapeTensorOf<list<Type> allowedTypes>
: Type<And<[TensorOf<allowedTypes>.predicate, HasStaticShapePred]>,
- "statically shaped " # TensorOf<allowedTypes>.description,
+ "statically shaped " # TensorOf<allowedTypes>.summary,
"::mlir::TensorType">;
def AnyStaticShapeTensor : StaticShapeTensorOf<[AnyType]>;
class TensorRankOf<list<Type> allowedTypes, list<int> ranks> :
Type<And<[TensorOf<allowedTypes>.predicate, HasAnyRankOfPred<ranks>]>,
!interleave(!foreach(rank, ranks, rank # "D"), "/") # " " #
- TensorOf<allowedTypes>.description, "::mlir::TensorType">;
+ TensorOf<allowedTypes>.summary, "::mlir::TensorType">;
class 0DTensorOf<list<Type> allowedTypes> : TensorRankOf<allowedTypes, [0]>;
class 1DTensorOf<list<Type> allowedTypes> : TensorRankOf<allowedTypes, [1]>;
class MemRefRankOf<list<Type> allowedTypes, list<int> ranks> :
Type<And<[MemRefOf<allowedTypes>.predicate, HasAnyRankOfPred<ranks>]>,
!interleave(!foreach(rank, ranks, rank # "D"), "/") # " " #
- MemRefOf<allowedTypes>.description>;
+ MemRefOf<allowedTypes>.summary>;
class StaticShapeMemRefOf<list<Type> allowedTypes>
: Type<And<[MemRefOf<allowedTypes>.predicate, HasStaticShapePred]>,
- "statically shaped " # MemRefOf<allowedTypes>.description>;
+ "statically shaped " # MemRefOf<allowedTypes>.summary>;
def AnyStaticShapeMemRef : StaticShapeMemRefOf<[AnyType]>;
class StridedMemRefOf<list<Type> allowedTypes>
: Type<And<[MemRefOf<allowedTypes>.predicate, HasStridesPred]>,
- "strided " # MemRefOf<allowedTypes>.description>;
+ "strided " # MemRefOf<allowedTypes>.summary>;
def AnyStridedMemRef : StridedMemRefOf<[AnyType]>;
class AnyStridedMemRefOfRank<int rank> :
Type<And<[AnyStridedMemRef.predicate,
MemRefRankOf<[AnyType], [rank]>.predicate]>,
- AnyStridedMemRef.description # " of rank " # rank>;
+ AnyStridedMemRef.summary # " of rank " # rank>;
class StridedMemRefRankOf<list<Type> allowedTypes, list<int> ranks> :
Type<And<[MemRefOf<allowedTypes>.predicate, HasAnyRankOfPred<ranks>]>,
!interleave(!foreach(rank, ranks, rank # "D"), "/") # " " #
- MemRefOf<allowedTypes>.description>;
+ MemRefOf<allowedTypes>.summary>;
// This represents a generic tuple without any constraints on element type.
def AnyTuple : Type<IsTupleTypePred, "tuple", "::mlir::TupleType">;
"; })"
>
]>,
- descr # " with any combination of " # etype.description # " values"> {
+ descr # " with any combination of " # etype.summary # " values"> {
// The type of elements in the container.
Type elementType = etype;
// Decorates an attribute to have an (unvalidated) default value if not present.
class DefaultValuedAttr<Attr attr, string val> :
- Attr<attr.predicate, attr.description> {
+ Attr<attr.predicate, attr.summary> {
// Construct this attribute with the input attribute and change only
// the default value.
// Note: this has to be kept up to date with Attr above.
// Decorates an attribute as optional. The return type of the generated
// attribute accessor method will be Optional<>.
-class OptionalAttr<Attr attr> : Attr<attr.predicate, attr.description> {
+class OptionalAttr<Attr attr> : Attr<attr.predicate, attr.summary> {
// Rewrite the attribute to be optional.
// Note: this has to be kept up to date with Attr above.
let storageType = attr.storageType;
// Base class for attributes containing types. Example:
// def IntTypeAttr : TypeAttrBase<"IntegerType", "integer type attribute">
// defines a type attribute containing an integer type.
-class TypeAttrBase<string retType, string description> :
+class TypeAttrBase<string retType, string summary> :
Attr<And<[
CPred<"$_self.isa<::mlir::TypeAttr>()">,
CPred<"$_self.cast<::mlir::TypeAttr>().getValue().isa<"
# retType # ">()">]>,
- description> {
+ summary> {
let storageType = [{ ::mlir::TypeAttr }];
let returnType = retType;
let valueType = NoneType;
// Op attributes of this kind are stored as StringAttr. Extra verification will
// be generated on the string though: only the symbols of the allowed cases are
// permitted as the string value.
-class StrEnumAttr<string name, string description,
- list<StrEnumAttrCase> cases> :
- EnumAttrInfo<name, cases>,
+class StrEnumAttr<string name, string summary, list<StrEnumAttrCase> cases>
+ : EnumAttrInfo<name, cases>,
StringBasedAttr<
And<[StrAttr.predicate, Or<!foreach(case, cases, case.predicate)>]>,
- !if(!empty(description), "allowed string cases: " #
+ !if(!empty(summary), "allowed string cases: " #
!interleave(!foreach(case, cases, "'" # case.symbol # "'"), ", "),
- description)>;
+ summary)>;
// An enum attribute backed by IntegerAttr.
//
// Op attributes of this kind are stored as IntegerAttr. Extra verification will
// be generated on the integer though: only the values of the allowed cases are
// permitted as the integer value.
-class IntEnumAttr<I intType, string name, string description,
+class IntEnumAttr<I intType, string name, string summary,
list<IntEnumAttrCaseBase> cases> :
EnumAttrInfo<name, cases>,
SignlessIntegerAttrBase<intType,
- !if(!empty(description), "allowed " # intType.description # " cases: " #
- !interleave(!foreach(case, cases, case.value), ", "), description)> {
+ !if(!empty(summary), "allowed " # intType.summary # " cases: " #
+ !interleave(!foreach(case, cases, case.value), ", "), summary)> {
let predicate = And<[
SignlessIntegerAttrBase<intType, "">.predicate,
Or<!foreach(case, cases, case.predicate)>]>;
}
-class I32EnumAttr<string name, string description,
+class I32EnumAttr<string name, string summary,
list<I32EnumAttrCase> cases> :
- IntEnumAttr<I32, name, description, cases> {
+ IntEnumAttr<I32, name, summary, cases> {
let returnType = cppNamespace # "::" # name;
let underlyingType = "uint32_t";
let convertFromStorage = "static_cast<" # returnType # ">($_self.getInt())";
let constBuilderCall =
"$_builder.getI32IntegerAttr(static_cast<int32_t>($0))";
}
-class I64EnumAttr<string name, string description,
+class I64EnumAttr<string name, string summary,
list<I64EnumAttrCase> cases> :
- IntEnumAttr<I64, name, description, cases> {
+ IntEnumAttr<I64, name, summary, cases> {
let returnType = cppNamespace # "::" # name;
let underlyingType = "uint64_t";
let convertFromStorage = "static_cast<" # returnType # ">($_self.getInt())";
// be generated on the integer to make sure only allowed bit are set. Besides,
// helper methods are generated to parse a string separated with a specified
// delimiter to a symbol and vice versa.
-class BitEnumAttr<string name, string description,
+class BitEnumAttr<string name, string summary,
list<BitEnumAttrCase> cases> :
- EnumAttrInfo<name, cases>, SignlessIntegerAttrBase<I32, description> {
+ EnumAttrInfo<name, cases>, SignlessIntegerAttrBase<I32, summary> {
let predicate = And<[
I32Attr.predicate,
// Make sure we don't have unknown bit set.
//===----------------------------------------------------------------------===//
// Composite attribute kinds
-class DictionaryAttrBase<Pred condition, string description> :
- Attr<condition, description> {
+class DictionaryAttrBase<Pred condition, string summary> :
+ Attr<condition, summary> {
let storageType = [{ ::mlir::DictionaryAttr }];
let returnType = [{ ::mlir::DictionaryAttr }];
let valueType = NoneType;
: DictionaryAttrBase<CPred<"$_self.isa<::mlir::DictionaryAttr>()">,
"dictionary of named attribute values">;
-class ElementsAttrBase<Pred condition, string description> :
- Attr<condition, description> {
+class ElementsAttrBase<Pred condition, string summary> :
+ Attr<condition, summary> {
let storageType = [{ ::mlir::ElementsAttr }];
let returnType = [{ ::mlir::ElementsAttr }];
let convertFromStorage = "$_self";
def ElementsAttr : ElementsAttrBase<CPred<"$_self.isa<::mlir::ElementsAttr>()">,
"constant vector/tensor attribute">;
-class IntElementsAttrBase<Pred condition, string description> :
+class IntElementsAttrBase<Pred condition, string summary> :
ElementsAttrBase<And<[CPred<"$_self.isa<::mlir::DenseIntElementsAttr>()">,
condition]>,
- description> {
+ summary> {
let storageType = [{ ::mlir::DenseIntElementsAttr }];
let returnType = [{ ::mlir::DenseIntElementsAttr }];
CPred<"$_self.cast<::mlir::DenseIntElementsAttr>().getType().getShape() == "
"::mlir::ArrayRef<int64_t>({" # !interleave(dims, ", ") # "})">]>;
- let description = width # "-bit signless int elements attribute of shape [" #
- !interleave(dims, ", ") # "]";
+ let summary = width # "-bit signless int elements attribute of shape [" #
+ !interleave(dims, ", ") # "]";
let constBuilderCall = "::mlir::DenseIntElementsAttr::get("
"::mlir::RankedTensorType::get({" # !interleave(dims, ", ") #
}
// Base class for array attributes.
-class ArrayAttrBase<Pred condition, string description> :
- Attr<condition, description> {
+class ArrayAttrBase<Pred condition, string summary> : Attr<condition, summary> {
let storageType = [{ ::mlir::ArrayAttr }];
let returnType = [{ ::mlir::ArrayAttr }];
let valueType = NoneType;
// Base class for array attributes whose elements are of the same kind.
// `element` specifies the element attribute kind stored in this array.
-class TypedArrayAttrBase<Attr element, string description>: ArrayAttrBase<
+class TypedArrayAttrBase<Attr element, string summary>: ArrayAttrBase<
And<[
// Guarantee this is an ArrayAttr first
CPred<"$_self.isa<::mlir::ArrayAttr>()">,
"[](::mlir::Attribute attr) { return ",
SubstLeaves<"$_self", "attr", element.predicate>,
"; })">]>,
- description> {
+ summary> {
let constBuilderCall = "$_builder.getArrayAttr($0)";
Attr elementAttr = element;
class Confined<Attr attr, list<AttrConstraint> constraints> : Attr<
And<!listconcat([attr.predicate],
!foreach(pred, constraints, pred.predicate))>,
- !foldl(/*init*/attr.description, /*list*/constraints,
- prev, cur, prev # " " # cur.description)> {
+ !foldl(/*init*/attr.summary, /*list*/constraints,
+ prev, cur, prev # " " # cur.summary)> {
let storageType = attr.storageType;
let returnType = attr.returnType;
let convertFromStorage = attr.convertFromStorage;
class AllAttrConstraintsOf<list<AttrConstraint> constraints> : AttrConstraint<
And<!listconcat([!head(constraints).predicate],
!foreach(pred, !tail(constraints), pred.predicate))>,
- !interleave(!foreach(con, constraints, con.description), " and ")> {
+ !interleave(!foreach(con, constraints, con.summary), " and ")> {
}
class IntMinValue<int n> : AttrConstraint<
// A variadic region constraint. It expands to zero or more of the base region.
class VariadicRegion<Region region>
- : Region<region.predicate, region.description>;
+ : Region<region.predicate, region.summary>;
//===----------------------------------------------------------------------===//
// Successor definitions
// A variadic successor constraint. It expands to zero or more of the base
// successor.
class VariadicSuccessor<Successor successor>
- : Successor<successor.predicate, successor.description>;
+ : Successor<successor.predicate, successor.summary>;
//===----------------------------------------------------------------------===//
// OpTrait definitions
// PredOpTrait is an op trait implemented by way of a predicate on the op.
class PredOpTrait<string descr, Pred pred> : OpTrait {
- string description = descr;
+ string summary = descr;
Pred predicate = pred;
}
// The constraint, either attribute or type, of the argument.
Constraint constraint = varConstraint;
- // A description for the argument.
- string description = desc;
+ // One-line human-readable description of the argument.
+ string summary = desc;
// The list of decorators for this variable, e.g. side effects.
list<OpVariableDecorator> decorators = varDecorators;
CPred<"::llvm::is_splat(::llvm::makeArrayRef({"
# !interleave(values, ", ") #"}))">;
-class AllMatch<list<string> values, string description> :
- PredOpTrait<description, AllMatchPred<values>>;
+class AllMatch<list<string> values, string summary> :
+ PredOpTrait<summary, AllMatchPred<values>>;
// TODO: Only works for non-variadic.
class AllMatchSameOperatorPred<list<string> names, string operator> :
AllMatchPred<!foreach(n, names, !subst("$_self", "$" # n, operator))>;
class AllMatchSameOperatorTrait<list<string> names, string operator,
- string description> :
+ string summary> :
PredOpTrait<
- "all of {" # !interleave(names, ", ") # "} have same " # description,
+ "all of {" # !interleave(names, ", ") # "} have same " # summary,
AllMatchSameOperatorPred<names, operator>> {
list<string> values = names;
}
AllMatchSameOperatorTrait<names, "$_self.getType()", "type">;
// A type constraint that denotes `transform(lhs.getType()) == rhs.getType()`.
-class TypesMatchWith<string description, string lhsArg, string rhsArg,
+class TypesMatchWith<string summary, string lhsArg, string rhsArg,
string transform> :
- PredOpTrait<description, CPred<
+ PredOpTrait<summary, CPred<
!subst("$_self", "$" # lhsArg # ".getType()", transform)
# " == $" # rhsArg # ".getType()">> {
string lhs = lhsArg;
class TypeIsPred<string name, Type type> :
SubstLeaves<"$_self", "$" # name # ".getType()", type.predicate>;
class TypeIs<string name, Type type> : PredOpTrait<
- "'" # name # "' is " # type.description, TypeIsPred<name, type>>;
+ "'" # name # "' is " # type.summary, TypeIsPred<name, type>>;
// Predicate to verify that a named argument or result's element type matches a
// given type.
SubstLeaves<"$_self", "getElementTypeOrSelf($" # name # ")",
type.predicate>]>;
class ElementTypeIs<string name, Type type> : PredOpTrait<
- "'" # name # "' is " # type.description, ElementTypeIsPred<name, type>>;
+ "'" # name # "' is " # type.summary, ElementTypeIsPred<name, type>>;
// Predicate to verify that the i'th operand and the j'th operand have the same
// elemental type.
// The name of the C++ base class to use for this Type.
string cppBaseClassName = baseCppClass;
- // Short summary of the type.
- string summary = ?;
+ // Additional, longer human-readable description of what the op does.
+ string description = "";
// Name of storage class to generate or use.
string storageClass = name # "TypeStorage";
code allocator = ?;
// The C++ type of this parameter.
string cppType = type;
- // A description of this parameter.
- string description = desc;
+ // One-line human-readable description of the argument.
+ string summary = desc;
// The format string for the asm syntax (documentation only).
string syntax = ?;
}
// Returns the user-readable description of this constraint. If the
// description is not provided, returns the TableGen def name.
- StringRef getDescription() const;
+ StringRef getSummary() const;
// Constraint kind
enum Kind { CK_Attr, CK_Region, CK_Successor, CK_Type, CK_Uncategorized };
std::string getPredTemplate() const;
// Returns the description of what the predicate is verifying.
- StringRef getDescription() const;
+ StringRef getSummary() const;
static bool classof(const OpTrait *t) { return t->getKind() == Kind::Pred; }
};
explicit Type(const llvm::Record *record);
// Returns the description of the type.
- StringRef getTypeDescription() const;
+ StringRef getDescription() const;
// Returns the dialect for the type if defined.
Dialect getDialect() const;
// Get the parameter name.
StringRef getName() const;
// If specified, get the custom allocator code for this parameter.
- llvm::Optional<StringRef> getAllocator() const;
+ Optional<StringRef> getAllocator() const;
// Get the C++ type of this parameter.
StringRef getCppType() const;
// Get a description of this parameter for documentation purposes.
- llvm::Optional<StringRef> getDescription() const;
+ Optional<StringRef> getSummary() const;
// Get the assembly syntax documentation.
StringRef getSyntax() const;
return getPredicate().getCondition();
}
-StringRef Constraint::getDescription() const {
- // If a summary is found, we use that given that it is a focused single line
- // comment.
+StringRef Constraint::getSummary() const {
if (Optional<StringRef> summary = def->getValueAsOptionalString("summary"))
return *summary;
- // If a summary can't be found, look for a specific description field to use
- // for the constraint.
- StringRef desc = def->getValueAsString("description");
- if (!desc.empty())
- return desc;
- // Otherwise, fallback to the name of the constraint definition.
return def->getName();
}
return pred.getCondition();
}
-llvm::StringRef PredOpTrait::getDescription() const {
- return def->getValueAsString("description");
+llvm::StringRef PredOpTrait::getSummary() const {
+ return def->getValueAsString("summary");
}
OpInterface InterfaceOpTrait::getOpInterface() const {
Type::Type(const llvm::Record *record) : TypeConstraint(record) {}
-StringRef Type::getTypeDescription() const {
- return def->getValueAsString("typeDescription");
+StringRef Type::getDescription() const {
+ return def->getValueAsString("description");
}
Dialect Type::getDialect() const {
StringRef TypeParameter::getName() const {
return def->getArgName(num)->getValue();
}
-llvm::Optional<StringRef> TypeParameter::getAllocator() const {
+Optional<StringRef> TypeParameter::getAllocator() const {
llvm::Init *parameterType = def->getArg(num);
if (isa<llvm::StringInit>(parameterType))
return llvm::Optional<StringRef>();
"Parameters DAG arguments must be either strings or defs "
"which inherit from TypeParameter\n");
}
-llvm::Optional<StringRef> TypeParameter::getDescription() const {
+Optional<StringRef> TypeParameter::getSummary() const {
auto *parameterType = def->getArg(num);
if (auto *typeParameter = dyn_cast<llvm::DefInit>(parameterType)) {
const auto *desc = typeParameter->getDef()->getValue("description");
if (llvm::StringInit *ci = dyn_cast<llvm::StringInit>(desc->getValue()))
return ci->getValue();
}
- return llvm::Optional<StringRef>();
+ return Optional<StringRef>();
}
StringRef TypeParameter::getSyntax() const {
auto *parameterType = def->getArg(num);
}
def MyStruct : StructAttr<"MyStruct", Test_Dialect_2,
[StructFieldAttr<"potatoes", I64ElementsAttr>]> {
- let description = "A structure describing a number of potatoes.";
+ let summary = "A structure describing a number of potatoes.";
}
def StructAttrOp : NS_Op<"struct_attr_op", []> {
StringRef enumName = enumAttr.getEnumClassName();
StringRef cppNamespace = enumAttr.getCppNamespace();
std::string underlyingType = std::string(enumAttr.getUnderlyingType());
- StringRef description = enumAttr.getDescription();
+ StringRef description = enumAttr.getSummary();
StringRef strToSymFnName = enumAttr.getStringToSymbolFnName();
StringRef symToStrFnName = enumAttr.getSymbolToStringFnName();
StringRef symToStrFnRetType = enumAttr.getSymbolToStringFnRetType();
<< formatv(
" return op->emitOpError(valueKind) << \" #\" << "
"valueGroupStartIndex << \" must be {0}, but got \" << type;\n",
- constraint.getDescription())
+ constraint.getSummary())
<< " }\n"
<< " return ::mlir::success();\n"
<< "}\n\n";
body << tgfmt(" if (!($0)) return $1\"attribute '$2' "
"failed to satisfy constraint: $3\");\n",
/*ctx=*/nullptr, tgfmt(condition, &ctx.withSelf(varName)),
- emitErrorPrefix, attrName, attr.getDescription());
+ emitErrorPrefix, attrName, attr.getSummary());
if (allowMissingAttr)
body << " }\n";
body << " }\n";
body << tgfmt(" if (!($0))\n "
"return emitOpError(\"failed to verify that $1\");\n",
&verifyCtx, tgfmt(t->getPredTemplate(), &verifyCtx),
- t->getDescription());
+ t->getSummary());
}
}
"verify constraint: {2}\";\n }\n",
constraint,
region.name.empty() ? "" : "('" + region.name + "') ",
- region.constraint.getDescription())
+ region.constraint.getSummary())
<< " ++index;\n"
<< " }\n";
}
"failed to "
"verify constraint: {2}\";\n }\n",
constraint, successor.name,
- successor.constraint.getDescription())
+ successor.constraint.getSummary())
<< " ++index;\n"
<< " }\n";
}
os << "`" << it.name << "`";
else
os << "«unnamed»";
- os << " | " << it.constraint.getDescription() << "\n";
+ os << " | " << it.constraint.getSummary() << "\n";
}
//===----------------------------------------------------------------------===//
for (const auto &it : op.getAttributes()) {
StringRef storageType = it.attr.getStorageType();
os << "`" << it.name << "` | " << storageType << " | "
- << it.attr.getDescription() << "\n";
+ << it.attr.getSummary() << "\n";
}
}
//===----------------------------------------------------------------------===//
static void emitTypeDoc(const Type &type, raw_ostream &os) {
- os << "### " << type.getDescription() << "\n";
- emitDescription(type.getTypeDescription(), os);
+ os << "### " << type.getSummary() << "\n";
+ emitDescription(type.getDescription(), os);
os << "\n";
}
// Emit attribute documentation.
SmallVector<TypeParameter, 4> parameters;
td.getParameters(parameters);
- if (parameters.size() != 0) {
+ if (!parameters.empty()) {
os << "\n#### Type parameters:\n\n";
os << "| Parameter | C++ type | Description |\n"
<< "| :-------: | :-------: | ----------- |\n";
for (const auto &it : parameters) {
- auto desc = it.getDescription();
+ auto desc = it.getSummary();
os << "| " << it.getName() << " | `" << td.getCppClassName() << "` | "
<< (desc ? *desc : "") << " |\n";
}
<< ")) {\n"
<< formatv(" return parser.emitError(parser.getNameLoc()) << "
"\"'{0}' must be {1}, but got \" << type;\n",
- variable->name, constraint.getDescription())
+ variable->name, constraint.getSummary())
<< " }\n"
<< " }\n";
}
formatv("\"operand {0} of native code call '{1}' failed to satisfy "
"constraint: "
"'{2}'\"",
- i, tree.getNativeCodeTemplate(), constraint.getDescription()));
+ i, tree.getNativeCodeTemplate(), constraint.getSummary()));
}
LLVM_DEBUG(llvm::dbgs() << "done emitting match for native code call\n");
formatv("\"operand {0} of op '{1}' failed to satisfy constraint: "
"'{2}'\"",
operand - op.operand_begin(), op.getOperationName(),
- constraint.getDescription()));
+ constraint.getSummary()));
}
}
formatv("\"op '{0}' attribute '{1}' failed to satisfy constraint: "
"{2}\"",
op.getOperationName(), namedAttr->name,
- matcher.getAsConstraint().getDescription()));
+ matcher.getAsConstraint().getSummary()));
}
// Capture the value
emitMatchCheck(
opName, tgfmt(condition, &fmtCtx.withSelf(self.str())),
formatv("\"value entity '{0}' failed to satisfy constraint: {1}\"",
- entities.front(), constraint.getDescription()));
+ entities.front(), constraint.getSummary()));
} else if (isa<AttrConstraint>(constraint)) {
PrintFatalError(
formatv("\"entities '{0}' failed to satisfy constraint: "
"{1}\"",
llvm::join(entities, ", "),
- constraint.getDescription()));
+ constraint.getSummary()));
}
}
StructAttr structAttr(&structDef);
StringRef structName = structAttr.getStructClassName();
StringRef cppNamespace = structAttr.getCppNamespace();
- StringRef description = structAttr.getDescription();
+ StringRef description = structAttr.getSummary();
auto fields = structAttr.getAllFields();
// Wrap in the appropriate namespace.
OptionalAttr<I32Attr>>,
StructFieldAttr<"sample_default_valued_integer",
DefaultValuedAttr<I32Attr, "42">>] > {
- let description = "Structure for test data";
+ let summary = "Structure for test data";
}