xref: /llvm-project/mlir/include/mlir/IR/PatternBase.td (revision 08d7377b67358496a409080fac22f3f7c077fb63)
1//===-- PatternBase.td - Base pattern definition file ------*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This files contains all of the base constructs for defining DRR patterns.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef PATTERNBASE_TD
14#define PATTERNBASE_TD
15
16include "mlir/IR/OpBase.td"
17
18//===----------------------------------------------------------------------===//
19// Pattern definitions
20//===----------------------------------------------------------------------===//
21
22// Marker used to identify the delta value added to the default benefit value.
23def addBenefit;
24
25// Base class for op+ -> op+ rewrite rules. These allow declaratively
26// specifying rewrite rules.
27//
28// A rewrite rule contains two components: a source pattern and one or more
29// result patterns. Each pattern is specified as a (recursive) DAG node (tree)
30// in the form of `(node arg0, arg1, ...)`.
31//
32// The `node` are normally MLIR ops, but it can also be one of the directives
33// listed later in this section.
34//
35// ## Symbol binding
36//
37// In the source pattern, `argN` can be used to specify matchers (e.g., using
38// type/attribute type constraints, etc.) and bound to a name for later use.
39// We can also bind names to op instances to reference them later in
40// multi-entity constraints. Operands in the source pattern can have
41// the same name. This bounds one operand to the name while verifying
42// the rest are all equal.
43//
44//
45// In the result pattern, `argN` can be used to refer to a previously bound
46// name, with potential transformations (e.g., using tAttr, etc.). `argN` can
47// itself be nested DAG node. We can also bound names to ops to reference
48// them later in other result patterns.
49//
50// For example,
51//
52// ```
53// def : Pattern<(OneResultOp1:$op1 $arg0, $arg1, $arg0),
54//               [(OneResultOp2:$op2 $arg0, $arg1),
55//                (OneResultOp3 $op2 (OneResultOp4))],
56//               [(HasStaticShapePred $op1)]>;
57// ```
58//
59// First `$arg0` and '$arg1' are bound to the `OneResultOp1`'s first
60// and second arguments and used later to build `OneResultOp2`. Second '$arg0'
61// is verified to be equal to the first '$arg0' operand.
62// `$op1` is bound to `OneResultOp1` and used to check whether the result's
63// shape is static. `$op2` is bound to `OneResultOp2` and used to
64// build `OneResultOp3`.
65//
66// ## Multi-result op
67//
68// To create multi-result ops in result pattern, you can use a syntax similar
69// to uni-result op, and it will act as a value pack for all results:
70//
71// ```
72// def : Pattern<(ThreeResultOp ...),
73//               [(TwoResultOp ...), (OneResultOp ...)]>;
74// ```
75//
76// Then `TwoResultOp` will replace the first two values of `ThreeResultOp`.
77//
78// You can also use `$<name>__N` to explicitly access the N-th result.
79// ```
80// def : Pattern<(FiveResultOp ...),
81//               [(TwoResultOp1:$res1__1 ...), (replaceWithValue $res1__0),
82//                (TwoResultOp2:$res2 ...), (replaceWithValue $res2__1)]>;
83// ```
84//
85// Then the values generated by `FiveResultOp` will be replaced by
86//
87// * `FiveResultOp`#0: `TwoResultOp1`#1
88// * `FiveResultOp`#1: `TwoResultOp1`#0
89// * `FiveResultOp`#2: `TwoResultOp2`#0
90// * `FiveResultOp`#3: `TwoResultOp2`#1
91// * `FiveResultOp`#4: `TwoResultOp2`#1
92class Pattern<dag source, list<dag> results, list<dag> preds = [],
93  list<dag> supplemental_results = [],
94  dag benefitAdded = (addBenefit 0)> {
95  dag sourcePattern = source;
96  // Result patterns. Each result pattern is expected to replace one result
97  // of the root op in the source pattern. In the case of more result patterns
98  // than needed to replace the source op, only the last N results generated
99  // by the last N result pattern is used to replace a N-result source op.
100  // So that the beginning result patterns can be used to generate additional
101  // ops to aid building the results used for replacement.
102  list<dag> resultPatterns = results;
103  // Multi-entity constraints. Each constraint here involves multiple entities
104  // matched in source pattern and places further constraints on them as a
105  // whole.
106  list<dag> constraints = preds;
107  // Optional patterns that are executed after the result patterns. Similar to
108  // auxiliary patterns, they are not used for replacement. These patterns can
109  // be used to invoke additional code after the result patterns, e.g. copy
110  // the attributes from the source op to the result ops.
111  list<dag> supplementalPatterns = supplemental_results;
112  // The delta value added to the default benefit value. The default value is
113  // the number of ops in the source pattern. The rule with the highest final
114  // benefit value will be applied first if there are multiple rules matches.
115  // This delta value can be either positive or negative.
116  dag benefitDelta = benefitAdded;
117}
118
119// Form of a pattern which produces a single result.
120class Pat<dag pattern, dag result, list<dag> preds = [],
121  list<dag> supplemental_results = [],
122  dag benefitAdded = (addBenefit 0)> :
123  Pattern<pattern, [result], preds, supplemental_results, benefitAdded>;
124
125// Native code call wrapper. This allows invoking an arbitrary C++ expression
126// to create an op operand/attribute or replace an op result.
127//
128// ## Placeholders
129//
130// If used as a DAG leaf, i.e., `(... NativeCodeCall<"...">:$arg, ...)`,
131// the wrapped expression can take special placeholders listed below:
132//
133// * `$_builder` will be replaced by the current `mlir::PatternRewriter`.
134// * `$_self` will be replaced by the defining operation in a source pattern.
135//   E.g., `NativeCodeCall<"Foo($_self, &$0)> I32Attr:$attr)>`, `$_self` will be
136//   replaced with the defining operation of the first operand of OneArgOp.
137//
138// If used as a DAG node, i.e., `(NativeCodeCall<"..."> <arg0>, ..., <argN>)`,
139// then positional placeholders are also supported; placeholder `$N` in the
140// wrapped C++ expression will be replaced by `<argN>`.
141//
142// ## Bind multiple results
143//
144// To bind multi-results and access the N-th result with `$<name>__N`, specify
145// the number of return values in the template. Note that only `Value` type is
146// supported for multiple results binding.
147
148class NativeCodeCall<string expr, int returns = 1> {
149  string expression = expr;
150  int numReturns = returns;
151}
152
153class NativeCodeCallVoid<string expr> : NativeCodeCall<expr, 0>;
154
155def ConstantLikeMatcher : NativeCodeCall<"::mlir::success("
156    "::mlir::matchPattern($_self->getResult(0), ::mlir::m_Constant(&$0)))">;
157
158//===----------------------------------------------------------------------===//
159// Rewrite directives
160//===----------------------------------------------------------------------===//
161
162// Directive used in result pattern to indicate that no new op are generated,
163// so to replace the matched DAG with an existing SSA value.
164def replaceWithValue;
165
166// Directive used in result patterns to specify the location of the generated
167// op. This directive must be used as a trailing argument to op creation or
168// native code calls.
169//
170// Usage:
171// * Create a named location: `(location "myLocation")`
172// * Copy the location of a captured symbol: `(location $arg)`
173// * Create a fused location: `(location "metadata", $arg0, $arg1)`
174
175def location;
176
177// Directive used in result patterns to specify return types for a created op.
178// This allows ops to be created without relying on type inference with
179// `OpTraits` or an op builder with deduction.
180//
181// This directive must be used as a trailing argument to op creation.
182//
183// Specify one return type with a string literal:
184//
185// ```
186// (AnOp $val, (returnType "$_builder.getI32Type()"))
187// ```
188//
189// Pass a captured value to copy its return type:
190//
191// ```
192// (AnOp $val, (returnType $val));
193// ```
194//
195// Pass a native code call inside a DAG to create a new type with arguments.
196//
197// ```
198// (AnOp $val,
199//       (returnType (NativeCodeCall<"$_builder.getTupleType({$0})"> $val)));
200// ```
201//
202// Specify multiple return types with multiple of any of the above.
203
204def returnType;
205
206// Directive used to specify the operands may be matched in either order. When
207// two adjacents are marked with `either`, it'll try to match the operands in
208// either ordering of constraints. Example:
209//
210// ```
211// (TwoArgOp (either $firstArg, (AnOp $secondArg)))
212// ```
213// The above pattern will accept either `"test.TwoArgOp"(%I32Arg, %AnOpArg)` and
214// `"test.TwoArgOp"(%AnOpArg, %I32Arg)`.
215//
216// Only operand is supported with `either` and note that an operation with
217// `Commutative` trait doesn't imply that it'll have the same behavior than
218// `either` while pattern matching.
219def either;
220
221// Directive used to match variadic operands. This directive only matches if
222// the variadic operand has the same length as the specified formal
223// sub-dags.
224//
225// ```
226// (VariadicOp (variadic:$input1 $input1a, $input1b),
227//             (variadic:$input2 $input2a, $input2b, $input2c),
228//             $attr1, $attr2)
229// ```
230//
231// The pattern above only matches if the `$input1` operand is of length 2,
232// `$input2` is of length 3, and all sub-dags match respectively. The `$input1`
233// symbol denotes the full variadic operand range. The `$input1a` symbol
234// denotes the first operand in the variadic sub-operands.
235def variadic;
236
237//===----------------------------------------------------------------------===//
238// Common value constraints
239//===----------------------------------------------------------------------===//
240
241def HasNoUseOf: Constraint<
242    CPred<"$_self.use_empty()">, "has no use">;
243
244#endif // PATTERNBASE_TD
245