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