diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -558,6 +558,105 @@ Code placed in `verifier` will be called after the auto-generated verification code. +### Declarative Assembly Format + +The custom assembly form of the operation may be specified in a declarative +string that matches the operations operands, attributes, etc. With the ability +to express additional information that needs to be parsed to build the +operation: + +```tablegen +def CallOp : Std_Op<"call", ...> { + let arguments = (ins FlatSymbolRefAttr:$callee, Variadic:$args); + let results = (outs Variadic); + + let assemblyFormat = [{ + $callee `(` $args `)` attr-dict `:` functional-type($args, results) + }]; +} +``` + +The format is comprised of three components: + +#### Directives + +A directive is a type of builtin function, with an optional set of arguments. +The available directives are as follows: + +* `attr-dict` + - Represents the attribute dictionary of the operation. + +* `functional-type` ( inputs , results ) + - Formats the `inputs` and `results` arguments as a + [function type](LangRef.md#function-type). + - The constraints on `inputs` and `results` are the same as the `input` of + the `type` directive. + +* `operands` + - Represents all of the operands of an operation. + +* `results` + - Represents all of the results of an operation. + +* `type` ( input ) + - Represents the type of the given input. + - `input` must be either an operand or result [variable](#variables), the + `operands` directive, or the `results` directive. + +#### Literals + +A literal is either a keyword or punctuation surrounded by \`\`. + +The following are the set of valid punctuation: + `:`, `,`, `=`, `<`, `>`, `(`, `)`, `[`, `]`, `->` + +#### Variables + +A variable is an entity that has been registered on the operation itself, i.e. +an argument(attribute or operand), result, etc. In the `CallOp` example above, +the variables would be `$callee` and `$args`. + +#### Requirements + +The format specification has a certain set of requirements that must be adhered +to: + +1. The output and operation name are never shown as they are fixed and cannot be + altered. +1. All operands within the operation must appear within the format, either + individually or with the `operands` directive. +1. All operand and result types must appear within the format using the various + `type` directives, either individually or with the `operands` or `results` + directives. +1. The `attr-dict` directive must always be present. +1. Must not contain overlapping information; e.g. multiple instances of + 'attr-dict', types, operands, etc. + - Note that `attr-dict` does not overlap with individual attributes. These + attributes will simply be elided when printing the attribute dictionary. + +##### Type Inferrence + +One requirement of the format is that the types of operands and results must +always be present. In certain instances, the type of a variable may be deduced +via type constraints or other information available. In these cases, the type of +that variable may be elided from the format. + +* 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. + +* 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`, `SameTypeOperands`, and +`SameOperandsAndResultType`. + ### `hasCanonicalizer` This boolean field indicate whether canonicalization patterns have been defined @@ -1126,40 +1225,6 @@ TODO: document expectation if the dependent op's definition changes. -### A proposal for auto-generating printer and parser methods - -NOTE: Auto-generating printing/parsing (as explained in the below) has _not_ -been prototyped, and potentially just being able to specify custom printer/ -parser methods are sufficient. This should presumably be influenced by the -design of the assembler/disassembler logic that LLVM backends get for free -for machine instructions. - -The custom assembly form of the operation is specified using a string with -matching operation name, operands and attributes. With the ability -to express additional information that needs to be parsed to build the -operation: - -```tablegen -tfl.add $lhs, $rhs {fused_activation_function: $fused_activation_function}: ${type(self)} -``` - -1. The output is never shown in the "mnemonics" string as that is fixed form - and cannot be altered. -1. Custom parsing of ops may include some punctuation (e.g., parenthesis). -1. The operands/results are added to the created operation in the order that - they are shown in the input and output dags. -1. The `${type(self)}` operator is used to represent the type of the operator. - The type of operands can also be queried. -1. Attributes names are matched to the placeholders in the mnemonic strings. - E.g., attribute axis is matched with `$axis`. Custom parsing for attribute - type can be defined along with the attribute definition. -1. The information in the custom assembly form should be sufficient to invoke - the builder generated. That may require being able to propagate information - (e.g., the `$lhs` has the same type as the result). - -Printing is effectively the inverse of the parsing function generated with the -mnemonic string serving as a template. - [TableGen]: https://llvm.org/docs/TableGen/index.html [TableGenIntro]: https://llvm.org/docs/TableGen/LangIntro.html [TableGenRef]: https://llvm.org/docs/TableGen/LangRef.html