# Table-driven Declarative Rewrite Rule (DRR)

In addition to subclassing the `mlir::RewritePattern` C++ class, MLIR also
supports defining rewrite rules in a declarative manner. Similar to
[Op Definition Specification](OpDefinitions.md) (ODS), this is achieved via
[TableGen][TableGen], which is a language to maintain records of domain-specific
information. The rewrite rules are specified concisely in a TableGen record,
which will be expanded into an equivalent `mlir::RewritePattern` subclass at
compiler build time.

This manual explains in detail all of the available mechanisms for defining
rewrite rules in such a declarative 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.

Given that declarative rewrite rules depend on op definition specification, this
manual assumes knowledge of the [ODS](OpDefinitions.md) doc.

## Benefits

Compared to the hand-written C++ classes, this declarative approach has several
benefits, including but not limited to:

*   **Being declarative**: The pattern creator just needs to state the rewrite
    pattern declaratively, without worrying about the concrete C++ methods to
    call.
*   **Removing boilerplate and showing the very essence of the rewrite**:
    `mlir::RewritePattern` is already good at hiding boilerplate for defining a
    rewrite rule. But we still need to write the class and function structures
    required by the C++ programming language, inspect ops for matching, and call
    op `build()` methods for constructing. These statements are typically quite
    simple and similar, so they can be further condensed with auto-generation.
    Because we reduce the boilerplate to the bare minimum, the declarative
    rewrite rule will just contain the very essence of the rewrite. This makes
    it very easy to understand the pattern.

## Strengths and Limitations

The declarative rewrite rule is **operation-based**: it describes a rule to
match against a directed acyclic graph (DAG) of operations and generate DAGs of
operations. This gives DRR both its strengths and limitations: it is good at
expressing op to op conversions, but not that well suited for, say, converting
an op into a loop nest.

Per the current implementation, DRR does not have good support for the following
features:

*   Matching and generating ops with regions.
*   Matching and generating ops with block arguments.
*   Matching multi-result ops in nested patterns.
*   Matching and generating variadic operand/result ops in nested patterns.
*   Packing and unpacking variadic operands/results during generation.
*   [`NativeCodeCall`](#nativecodecall-transforming-the-generated-op) returning
    more than one results.

## Rule Definition

The core construct for defining a rewrite rule is defined in
[`OpBase.td`][OpBase] as

```tablegen
class Pattern<
    dag sourcePattern, list<dag> resultPatterns,
    list<dag> additionalConstraints = [],
    dag benefitsAdded = (addBenefit 0)>;
```

A declarative rewrite rule contains two main components:

*   A *source pattern*, which is used for matching a DAG of operations.
*   One or more *result patterns*, which are used for generating DAGs of
    operations to replace the matched DAG of operations.

We allow multiple result patterns to support
[multi-result ops](#supporting-multi-result-ops) and
[auxiliary ops](#supporting-auxiliary-ops), but frequently we just want to
convert one DAG of operations to another DAG of operations. There is a handy
wrapper of `Pattern`, `Pat`, which takes a single result pattern:

```tablegen
class Pat<
    dag sourcePattern, dag resultPattern,
    list<dag> additionalConstraints = [],
    dag benefitsAdded = (addBenefit 0)> :
  Pattern<sourcePattern, [resultPattern], additionalConstraints, benefitAdded>;
```

Each pattern is specified as a TableGen `dag` object with the syntax of
`(operator arg0, arg1, ...)`.

`operator` is typically an MLIR op, but it can also be other
[directives](#rewrite-directives). `argN` is for matching (if used in source
pattern) or generating (if used in result pattern) the `N`-th argument for
`operator`. If the `operator` is some MLIR operation, it means the `N`-th
argument as specified in the `arguments` list of the op's definition. Therefore,
we say op argument specification in pattern is **position-based**: the position
where they appear matters.

`argN` can be a `dag` object itself, thus we can have nested `dag` tree to model
the def-use relationship between ops.

### Source pattern

The source pattern is for matching a DAG of operations. Arguments in the `dag`
object are intended to **capture** the op arguments. They can also be used to
**further limit** the match criteria. The capturing is done by specifying a
symbol starting with the `$` sign, while further constraints are introduced by
specifying a `TypeConstraint` (for an operand) or a `AttrConstraint` (for an
attribute).

#### Binding op arguments and limiting the match

For example,

```tablegen
def AOp : Op<"a_op"> {
    let arguments = (ins
      AnyType:$a_input,
      AnyAttr:$a_attr
    );

    let results = (outs
      AnyType:$a_output
    );
}

def : Pat<(AOp $input, F32Attr:$attr), ...>;
```

In the above, we are matching an `AOp` whose `$input` can be anything valid as
defined by the op and whose `$attr` must be a float attribute. If the match
succeeds, we bind the `$input` symbol to the op's only input (`$a_input`) and
`$attr` to the only attribute (`$a_attr`); we can reference them using `$input`
and `$attr` in result patterns and additional constraints.

The pattern is position-based: the symbol names used for capturing here do not
need to match with the op definition as shown in the above example. As another
example, the pattern can be written as `def : Pat<(AOp $a, F32Attr:$b), ...>;`
and use `$a` and `$b` to refer to the captured input and attribute. But using
the ODS name directly in the pattern is also allowed. Operands in the source
pattern can have the same name. This bounds one operand to the name while
verifying the rest are all equal.

Also note that we only need to add `TypeConstraint` or `AttributeConstraint`
when we need to further limit the match criteria. If all valid cases to the op
are acceptable, then we can leave the constraint unspecified.

`$_` is a special symbol to mean ignore capturing an argument. For example,
`def : Pat<(AOp $_, $b), ...>` means only `$b` is interesting to capture and
will be referenced later in result patterns. It's still possible to place
additional constraints even if the symbol is not to be captured; for such case,
you can simply use just the `TypeConstraint` or `AttributeConstraint` without a
bound symbol, for example, `def : Pat<(AOp $a, F32Attr), ...>`.

#### Matching DAG of operations

To match a DAG of ops, use nested `dag` objects:

```tablegen

def BOp : Op<"b_op"> {
    let arguments = (ins);

    let results = (outs
      AnyType:$b_output
    );
}


def : Pat<(AOp (BOp), $attr), ...>;
```

The above pattern matches an `AOp` whose only operand is generated by a `BOp`,
that is, the following MLIR code:

```mlir
%0 = "b_op"() : () -> (...)
%1 = "a_op"(%0) {attr: ...} : () -> (...)
```

#### Binding op results

To bind a symbol to the results of a matched op for later reference, attach the
symbol to the op itself:

```tablegen
def : Pat<(AOp (BOp:$b_result), $attr), ...>;
```

The above will bind `$b_result` to the matched `BOp`'s result. (There are more
details regarding multi-result ops, which is covered
[later](#supporting-multi-result-ops).)

### Result pattern

The result pattern is for generating a DAG of operations. Arguments in the `dag`
object are intended to **reference** values captured in the source pattern and
potentially **apply transformations**.

#### Referencing bound symbols

For example,

```tablegen
def COp : Op<"c_op"> {
    let arguments = (ins
      AnyType:$c_input,
      AnyAttr:$c_attr
    );

    let results = (outs
      AnyType:$c_output
    );
}

def : Pat<(AOp $input, $attr), (COp $input, $attr)>;
```

In the above, `AOp`'s only operand and attribute are bound to `$input` and
`$attr`, respectively. We then reference them in the result pattern for
generating the `COp` by passing them in as arguments to `COp`'s `build()`
method.

We can also reference symbols bound to matched op's results:

```tablegen
def : Pat<(AOp (BOp:$b_result) $attr), (COp $b_result $attr)>;
```

In the above, we are using `BOp`'s result for building `COp`.

#### Building operations

Given that `COp` was specified with table-driven op definition, there will be
several `build()` methods generated for it. One of them has aggregated
parameters for result types, operands, and attributes in the signature: `void
COp::build(..., ArrayRef<Type> resultTypes, Array<Value> operands,
ArrayRef<NamedAttribute> attr)`. The pattern in the above calls this `build()`
method for constructing the `COp`.

In general, arguments in the result pattern will be passed directly to the
`build()` method to leverage the auto-generated `build()` method, list them in
the pattern by following the exact same order as the ODS `arguments` definition.
Otherwise, a custom `build()` method that matches the argument list is required.

Right now all ODS-generated `build()` methods require specifying the result
type(s), unless the op has known traits like `SameOperandsAndResultType` that we
can use to auto-generate a `build()` method with result type deduction. When
generating an op to replace the result of the matched root op, we can use the
matched root op's result type when calling the ODS-generated builder. Otherwise
(e.g., generating an [auxiliary op](#supporting-auxiliary-ops) or generating an
op with a nested result pattern), DRR will not be able to deduce the result
type(s). The pattern author will need to define a custom builder that has result
type deduction ability via `OpBuilder` in ODS. For example, in the following
pattern

```tablegen
def : Pat<(AOp $input, $attr), (COp (AOp $input, $attr) $attr)>;
```

`AOp` is generated via a nested result pattern; DRR won't be able to deduce the
result type for it. A custom builder for `AOp` should be defined and it should
deduce the result type by itself. The builder should have the separate parameter
for each operand and attribute and deduce the result type internally by itself.
For example, for the above `AOp`, a possible builder is:

```c++

void AOp::build(OpBuilder &builder, OperationState &state,
                Value input, Attribute attr) {
  state.addOperands({input});
  state.addAttribute("a_attr", attr);
  Type type = ...; // Deduce result type here
  state.addTypes({type});
}
```

Failing to define such a builder will result in an error at C++ compilation time
saying the call to `AOp::build()` cannot be resolved because of the number of
parameters mismatch.

#### Generating DAG of operations

`dag` objects can be nested to generate a DAG of operations:

```tablegen
def : Pat<(AOp $input, $attr), (COp (BOp), $attr)>;
```

In the above, we generate a `BOp`, and then use its result to generate the `COp`
to replace the matched `AOp`.

#### Binding op results

In the result pattern, we can bind to the result(s) of a newly built op by
attaching symbols to the op. (But we **cannot** bind to op arguments given that
they are referencing previously bound symbols.) This is useful for reusing newly
created results where suitable. For example,

```tablegen
def DOp : Op<"d_op"> {
    let arguments = (ins
      AnyType:$d_input1,
      AnyType:$d_input2,
    );

    let results = (outs
      AnyType:$d_output
    );
}

def : Pat<(AOp $input, $ignored_attr), (DOp (BOp:$b_result) $b_result)>;
```

In this pattern, an `AOp` is matched and replaced with a `DOp` whose two
operands are from the result of a single `BOp`. This is only possible by binding
the result of the `BOp` to a name and reuse it for the second operand of the
`DOp`

#### `NativeCodeCall`: transforming the generated op

Sometimes the captured arguments are not exactly what we want so they cannot be
directly fed in as arguments to build the new op. For such cases, we can apply
transformations on the arguments by calling into C++ helper functions. This is
achieved by `NativeCodeCall`.

For example, if we want to capture some op's attributes and group them as an
array attribute to construct a new op:

```tablegen

def TwoAttrOp : Op<"two_attr_op"> {
    let arguments = (ins
      AnyAttr:$op_attr1,
      AnyAttr:$op_attr2
    );

    let results = (outs
      AnyType:$op_output
    );
}

def OneAttrOp : Op<"one_attr_op"> {
    let arguments = (ins
      ArrayAttr:$op_attr
    );

    let results = (outs
      AnyType:$op_output
    );
}
```

We can write a C++ helper function:

```c++
ArrayAttr createArrayAttr(Builder &builder, Attribute a, Attribute b) {
  return builder.getArrayAttr({a, b});
}
```

And then write the pattern as:

```tablegen
def createArrayAttr : NativeCodeCall<"createArrayAttr($_builder, $0, $1)">;

def : Pat<(TwoAttrOp $attr1, $attr2),
          (OneAttrOp (createArrayAttr $attr1, $attr2))>;
```

And make sure the generated C++ code from the above pattern has access to the
definition of the C++ helper function.

In the above example, we are using a string to specialize the `NativeCodeCall`
template. The string can be an arbitrary C++ expression that evaluates into some
C++ object expected at the `NativeCodeCall` site (here it would be expecting an
array attribute). Typically the string should be a function call.

##### `NativeCodeCall` placeholders

In `NativeCodeCall`, we can use placeholders like `$_builder`, `$N` and `$N...`.
The former is called *special placeholder*, while the latter is called
*positional placeholder* and *positional range placeholder*.

`NativeCodeCall` right now only supports three special placeholders:
`$_builder`, `$_loc`, and `$_self`:

*   `$_builder` will be replaced by the current `mlir::PatternRewriter`.
*   `$_loc` will be replaced by the fused location or custom location (as
    determined by location directive).
*   `$_self` will be replaced by the defining operation in a source pattern.

We have seen how `$_builder` can be used in the above; it allows us to pass a
`mlir::Builder` (`mlir::PatternRewriter` is a subclass of `mlir::OpBuilder`,
which is a subclass of `mlir::Builder`) to the C++ helper function to use the
handy methods on `mlir::Builder`.

Here's an example how we should use `$_self` in source pattern,

```tablegen

def : Pat<(OneAttrOp (NativeCodeCall<"Foo($_self, &$0)"> I32Attr:$val)),
          (TwoAttrOp $val, $val)>;
```

In the above, `$_self` is substituted by the defining operation of the first
operand of OneAttrOp. Note that we don't support binding name to
`NativeCodeCall` in the source pattern. To carry some return values from a
helper function, put the names (constraint is optional) in the parameter list
and they will be bound to the variables with corresponding type. Then these names
must be either passed by reference or pointer to the variable used as argument
so that the matched value can be returned. In the same example, `$val` will be
bound to a variable with `Attribute` type (as `I32Attr`) and the type of the
second argument in `Foo()` could be `Attribute&` or `Attribute*`. Names with
attribute constraints will be captured as `Attribute`s while everything else
will be treated as `Value`s.

Positional placeholders will be substituted by the `dag` object parameters at
the `NativeCodeCall` use site. For example, if we define `SomeCall :
NativeCodeCall<"someFn($1, $2, $0)">` and use it like `(SomeCall $in0, $in1,
$in2)`, then this will be translated into C++ call `someFn($in1, $in2, $in0)`.

Positional range placeholders will be substituted by multiple `dag` object
parameters at the `NativeCodeCall` use site. For example, if we define
`SomeCall : NativeCodeCall<"someFn($1...)">` and use it like `(SomeCall $in0,
$in1, $in2)`, then this will be translated into C++ call `someFn($in1, $in2)`.

##### `NativeCodeCall` binding multi-results

To bind multi-results and access the N-th result with `$<name>__N`, specify the
number of return values in the template. Note that only `Value` type is
supported for multiple results binding. For example,

```tablegen

def PackAttrs : NativeCodeCall<"packAttrs($0, $1)", 2>;
def : Pattern<(TwoResultOp $attr1, $attr2),
              [(OneResultOp (PackAttr:$res__0, $attr1, $attr2)),
               (OneResultOp $res__1)]>;

```

Use `NativeCodeCallVoid` for cases with no return value.

The correct number of returned value specified in NativeCodeCall is important.
It will be used to verify the consistency of the number of return values.
Additionally, `mlir-tblgen` will try to capture the return values of
`NativeCodeCall` in the generated code so that it will trigger a later
compilation error if a `NativeCodeCall` that doesn't return any result isn't
labeled with 0 returns.

##### Customizing entire op building

`NativeCodeCall` is not only limited to transforming arguments for building an
op; it can be also used to specify how to build an op entirely. An example:

If we have a C++ function for building an op:

```c++
Operation *createMyOp(OpBuilder builder, Value input, Attribute attr);
```

We can wrap it up and invoke it like:

```tablegen
def createMyOp : NativeCodeCall<"createMyOp($_builder, $0, $1)">;

def : Pat<(... $input, $attr), (createMyOp $input, $attr)>;
```

### Supporting auxiliary ops

A declarative rewrite rule supports multiple result patterns. One of the
purposes is to allow generating *auxiliary ops*. Auxiliary ops are operations
used for building the replacement ops; but they are not directly used for
replacement themselves.

For the case of uni-result ops, if there are multiple result patterns, only the
value generated from the last result pattern will be used to replace the matched
root op's result; all other result patterns will be considered as generating
auxiliary ops.

Normally we want to specify ops as nested `dag` objects if their def-use
relationship can be expressed in the way that an op's result can feed as the
argument to consuming op. But that is not always possible. For example, if we
want to allocate memory and store some computation (in pseudocode):

```mlir
%dst = arith.addi %lhs, %rhs
```

into

```mlir
%shape = shape %lhs
%mem = memref.alloc %shape
%sum = arith.addi %lhs, %rhs
memref.store %mem, %sum
%dst = memref.load %mem
```

We cannot fit in with just one result pattern given `store` does not return a
value. Instead we can use multiple result patterns:

```tablegen
def : Pattern<(AddIOp $lhs, $rhs),
              [(StoreOp (AllocOp:$mem (ShapeOp $lhs)), (AddIOp $lhs, $rhs)),
               (LoadOp $mem)];
```

In the above we use the first result pattern to generate the first four ops, and
use the last pattern to generate the last op, which is used to replace the
matched op.

### Supporting multi-result ops

Multi-result ops bring extra complexity to declarative rewrite rules. We use
TableGen `dag` objects to represent ops in patterns; there is no native way to
indicate that an op generates multiple results. The approach adopted is based on
**naming convention**: a `__N` suffix is added to a symbol to indicate the
`N`-th result.

#### `__N` suffix

The `__N` suffix is specifying the `N`-th result as a whole (which can be
[variadic](#supporting-variadic-ops)). For example, we can bind a symbol to some
multi-result op and reference a specific result later:

```tablegen
def ThreeResultOp : Op<"three_result_op"> {
    let arguments = (ins ...);

    let results = (outs
      AnyTensor:$output1,
      AnyTensor:$output2,
      AnyTensor:$output3
    );
}

def : Pattern<(ThreeResultOp:$results ...),
              [(... $results__0), ..., (... $results__2), ...]>;
```

In the above pattern we bind `$results` to all the results generated by
`ThreeResultOp` and references its `$output1` and `$output3` later in the result
patterns.

We can also bind a symbol and reference one of its specific result at the same
time, which is typically useful when generating multi-result ops:

```tablegen
// TwoResultOp has similar definition as ThreeResultOp, but only has two
// results.

def : Pattern<(TwoResultOp ...),
              [(ThreeResultOp:$results__2, ...),
               (replaceWithValue $results__0)]>;
```

In the above, we created a `ThreeResultOp` and bind `results` to its results,
and uses its last result (`$output3`) and first result (`$output1`) to replace
the `TwoResultOp`'s two results, respectively.

#### Replacing multi-result ops

The above example also shows how to replace a matched multi-result op.

To replace an `N`-result op, the result patterns must generate at least `N`
declared values (see [Declared vs. actual value](#declared-vs-actual-value) for
definition). If there are more than `N` declared values generated, only the last
`N` declared values will be used to replace the matched op. Note that because of
the existence of multi-result op, one result pattern **may** generate multiple
declared values. So it means we do not necessarily need `N` result patterns to
replace an `N`-result op. For example, to replace an op with three results, you
can have

```tablegen
// ThreeResultOp/TwoResultOp/OneResultOp generates three/two/one result(s),
// respectively.

// Replace each result with a result generated from an individual op.
def : Pattern<(ThreeResultOp ...),
              [(OneResultOp ...), (OneResultOp ...), (OneResultOp ...)]>;

// Replace the first two results with two results generated from the same op.
def : Pattern<(ThreeResultOp ...),
              [(TwoResultOp ...), (OneResultOp ...)]>;

// Replace all three results with three results generated from the same op.
def : Pat<(ThreeResultOp ...), (ThreeResultOp ...)>;

def : Pattern<(ThreeResultOp ...),
              [(AuxiliaryOp ...), (ThreeResultOp ...)]>;
```

But using a single op to serve as both auxiliary op and replacement op is
forbidden, i.e., the following is not allowed because that the first
`TwoResultOp` generates two results but only the second result is used for
replacing the matched op's result:

```tablegen
def : Pattern<(ThreeResultOp ...),
              [(TwoResultOp ...), (TwoResultOp ...)]>;
```

### Supporting variadic ops

#### Declared vs. actual value

Before going into details on variadic op support, we need to define a few terms
regarding an op's values.

*   *Value*: either an operand or a result
*   *Declared operand/result/value*: an operand/result/value statically declared
    in ODS of the op
*   *Actual operand/result/value*: an operand/result/value of an op instance at
    runtime

The above terms are needed because ops can have multiple results, and some of
the results can also be variadic. For example,

```tablegen
def MultiVariadicOp : Op<"multi_variadic_op"> {
    let arguments = (ins
      AnyTensor:$input1,
      Variadic<AnyTensor>:$input2,
      AnyTensor:$input3
    );

    let results = (outs
      AnyTensor:$output1,
      Variadic<AnyTensor>:$output2,
      AnyTensor:$output3
    );
}
```

We say the above op has 3 declared operands and 3 declared results. But at
runtime, an instance can have 3 values corresponding to `$input2` and 2 values
correspond to `$output2`; we say it has 5 actual operands and 4 actual results.
A variadic operand/result is a considered as a declared value that can
correspond to multiple actual values.

[TODO]

### Supplying additional constraints

Constraints can be placed on op arguments when matching. But sometimes we need
to also place constraints on the matched op's results or sometimes need to limit
the matching with some constraints that cover both the arguments and the
results. The third parameter to `Pattern` (and `Pat`) is for this purpose.

For example, we can write

```tablegen
def HasNoUseOf: Constraint<CPred<"$_self.use_empty()">, "has no use">;

def HasSameElementType : Constraint<
    CPred<"$0.cast<ShapedType>().getElementType() == "
          "$1.cast<ShapedType>().getElementType()">,
    "has same element type">;

def : Pattern<(TwoResultOp:$results $input),
              [(...), (...)],
              [(F32Tensor:$results__0), (HasNoUseOf:$results__1),
               (HasSameElementShape $results__0, $input)]>;
```

You can

*   Use normal `TypeConstraint`s on previous bound symbols (the first result of
    `TwoResultOp` must be a float tensor);
*   Define new `Constraint` for previous bound symbols (the second result of
    `TwoResultOp` must has no use);
*   Apply constraints on multiple bound symbols (`$input` and `TwoResultOp`'s
    first result must have the same element type).

### Adjusting benefits

The benefit of a `Pattern` is an integer value indicating the benefit of
matching the pattern. It determines the priorities of patterns inside the
pattern rewrite driver. A pattern with a higher benefit is applied before one
with a lower benefit.

In DRR, a rule is set to have a benefit of the number of ops in the source
pattern. This is based on the heuristics and assumptions that:

*   Larger matches are more beneficial than smaller ones.
*   If a smaller one is applied first the larger one may not apply anymore.

The fourth parameter to `Pattern` (and `Pat`) allows to manually tweak a
pattern's benefit. Just supply `(addBenefit N)` to add `N` to the benefit value.

## Rewrite directives

### `location`

By default the C++ pattern expanded from a DRR pattern uses the fused location
of all source ops as the location for all generated ops. This is not always the
best location mapping relationship. For such cases, DRR provides the `location`
directive to provide finer control.

`location` is of the following syntax:

```tablegen
(location $symbol0, $symbol1, ...)
```

where all `$symbol` should be bound previously in the pattern and one optional
string may be specified as an attribute. The following locations are created:

*   If only 1 symbol is specified then that symbol's location is used,
*   If multiple are specified then a fused location is created;
*   If no symbol is specified then string must be specified and a NamedLoc is
    created instead;

`location` must be used as a trailing argument to an op creation. For example,

```tablegen
def : Pat<(LocSrc1Op:$src1 (LocSrc2Op:$src2 ...),
          (LocDst1Op (LocDst2Op ..., (location $src2)), (location "outer"))>;
```

In the above pattern, the generated `LocDst2Op` will use the matched location of
`LocSrc2Op` while the root `LocDst1Op` node will used the named location
`outer`.

### `replaceWithValue`

The `replaceWithValue` directive is used to eliminate a matched op by replacing
all of its uses with a captured value. It is of the following syntax:

```tablegen
(replaceWithValue $symbol)
```

where `$symbol` should be a symbol bound previously in the pattern.

For example,

```tablegen
def : Pat<(Foo $input), (replaceWithValue $input)>;
```

The above pattern removes the `Foo` and replaces all uses of `Foo` with
`$input`.

### `returnType`

The `returnType` directive allows patterns to directly specify return types for
replacement ops that lack return type inference with op traits or user-defined
builders with return type deduction.

The `returnType` directive must be used as a trailing argument to a node
describing a replacement op. The directive comes in three forms:

*   `(returnType $value)`: copy the type of the operand or result bound to
    `value`.
*   `(returnType "$_builder.getI32Type()")`: a string literal embedding C++. The
    embedded snippet is expected to return a `Type` or a `TypeRange`.
*   `(returnType (NativeCodeCall<"myFunc($0)"> $value))`: a DAG node with a
    native code call that can be passed any bound variables arguments.

Specify multiple return types with a mix of any of the above. Example:

```tablegen
def : Pat<(SourceOp $arg0, $arg1),
          (OpA $arg0, (TwoResultOp:$res__1 $arg1,
                         (returnType $arg1, "$_builder.getI64Type()")))>;
```

Explicitly-specified return types will take precedence over return types
inferred from op traits or user-defined builders. The return types of values
replacing root op results cannot be overridden.

### `either`

The `either` directive is used to specify the operands may be matched in either
order.

```tablegen
def : Pat<(TwoArgOp (either $firstArg, (AnOp $secondArg))),
          (...)>;
```

The above pattern will accept either `"test.TwoArgOp"(%I32Arg, %AnOpArg)` and
`"test.TwoArgOp"(%AnOpArg, %I32Arg)`.

Only operand is supported with `either` and note that an operation with
`Commutative` trait doesn't imply that it'll have the same behavior than
`either` while pattern matching.

## Debugging Tips

### 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
`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`.

To see the generated code, invoke `mlir-tblgen` with a specific generator by
providing include paths via `-I`. For example,

```sh
# To see all the C++ pattern rewrite classes
mlir-tblgen --gen-rewriters -I /path/to/mlir/include /path/to/input/td/file
```

### Compilation error: no matching member function for call to 'build'

This is because DRR is failing to call a `build()` method with result type
deduction ability. See [building operations](#building-operations) for more
details.

[TableGen]: https://llvm.org/docs/TableGen/index.html
[OpBase]: https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/IR/OpBase.td
