CINXE.COM
'pdl' Dialect - MLIR
<!doctype html><html lang=en-us><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>'pdl' Dialect - MLIR</title><meta name=description content="Multi-Level IR Compiler Framework"><meta name=generator content="Hugo 0.119.0"><link href=https://mlir.llvm.org/index.xml rel=alternate type=application/rss+xml><link rel=canonical href=https://mlir.llvm.org/docs/Dialects/PDLOps/><link rel=stylesheet href=https://mlir.llvm.org/css/theme.css><script src=https://use.fontawesome.com/releases/v5.0.6/js/all.js></script> <link rel=stylesheet href=https://mlir.llvm.org/css/chroma.min.css><script src=https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js></script> <script src=https://cdn.jsdelivr.net/npm/jquery.easing@1.4.1/jquery.easing.min.js></script> <script src=https://mlir.llvm.org/js/bundle.js></script> <script type=text/javascript src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> <script type=text/x-mathjax-config> MathJax.Hub.Config({ tex2jax: { inlineMath: [['$', '$'] ], displayMath: [ ['$$','$$'], ["\\[","\\]"] ] } }); </script><link rel=apple-touch-icon sizes=180x180 href="/apple-touch-icon.png?v=1"><link rel=icon type=image/png sizes=32x32 href="/favicon-32x32.png?v=1"><link rel=icon type=image/png sizes=16x16 href="/favicon-16x16.png?v=1"><link rel=manifest href="/site.webmanifest?v=1"><link rel=mask-icon href="/safari-pinned-tab.svg?v=1" color=#3775e0><link rel="shortcut icon" href="/favicon.ico?v=1"><meta name=msapplication-TileColor content="#2d89ef"><meta name=theme-color content="#ffffff"><link rel=icon href=/favicon.svg type=image/svg+xml sizes=any><style>:root{}</style></head><body><div class=container><header><h1><div><img src=https://mlir.llvm.org//mlir-logo.png width=40px align=absmiddle> MLIR</div></h1><p class=description>Multi-Level IR Compiler Framework</p></header><div class=global-menu><nav><ul><li class=parent><a href>Community<i class="fas fa-angle-right"></i></a><ul class=sub-menu><li class=child><a href=https://llvm.discourse.group/c/mlir/31>Forums</a></li><li class=child><a href=https://discord.gg/xS7Z362>Chat</a></li></ul></li><li><a href=/getting_started/Debugging/>Debugging Tips</a></li><li><a href=/getting_started/Faq/>FAQ</a></li><li class=parent><a href=https://github.com/llvm/llvm-project/tree/main/mlir>Source<i class="fas fa-angle-right"></i></a><ul class=sub-menu><li class=child><a href=/doxygen/>Doxygen</a></li><li class=child><a href=https://github.com/llvm/llvm-project/tree/main/mlir>GitHub</a></li></ul></li><li><a href="https://bugs.llvm.org/buglist.cgi?bug_status=__open__&list_id=177877&order=changeddate%20DESC%2Cpriority%2Cbug_severity&product=MLIR&query_format=specific">Bugs</a></li><li><a href=https://github.com/llvm/mlir-www/tree/main/website/static/LogoAssets>Logo Assets</a></li><li><a href=https://www.youtube.com/MLIRCompiler>Youtube Channel</a></li></ul></nav></div><div class=content-container><main><h1>'pdl' Dialect</h1><p>High level pattern definition dialect</p><p>PDL presents a high level abstraction for the rewrite pattern infrastructure available in MLIR. This abstraction allows for representing patterns transforming MLIR, as MLIR. This allows for applying all of the benefits that the general MLIR infrastructure provides, to the infrastructure itself. This means that pattern matching can be more easily verified for correctness, targeted by frontends, and optimized.</p><p>PDL abstracts over various different aspects of patterns and core MLIR data structures. Patterns are specified via a <code>pdl.pattern</code> operation. These operations contain a region body for the “matcher” code, and terminate with a <code>pdl.rewrite</code> that either dispatches to an external rewriter or contains a region for the rewrite specified via <code>pdl</code>. The types of values in <code>pdl</code> are handle types to MLIR C++ types, with <code>!pdl.attribute</code>, <code>!pdl.operation</code>, <code>!pdl.value</code>, and <code>!pdl.type</code> directly mapping to <code>mlir::Attribute</code>, <code>mlir::Operation*</code>, <code>mlir::Value</code>, and <code>mlir::Type</code> respectively.</p><p>An example pattern is shown below:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// pdl.pattern contains metadata similarly to a `RewritePattern`. </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>pattern <span class=p>:</span> benefit<span class=p>(</span><span class=m>1</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=c>// External input operand values are specified via `pdl.operand` operations. </span></span></span><span class=line><span class=cl><span class=c></span> <span class=c>// Result types are constrainted via `pdl.type` operations. </span></span></span><span class=line><span class=cl><span class=c></span> </span></span><span class=line><span class=cl> <span class=nv>%resultType</span> <span class=p>=</span> pdl<span class=p>.</span>type </span></span><span class=line><span class=cl> <span class=nv>%inputOperand</span> <span class=p>=</span> pdl<span class=p>.</span>operand </span></span><span class=line><span class=cl> <span class=nv>%root</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"foo.op"</span><span class=p>(</span><span class=nv>%inputOperand</span><span class=p>)</span> <span class=p>-></span> <span class=nv>%resultType</span> </span></span><span class=line><span class=cl> pdl<span class=p>.</span>rewrite <span class=nv>%root</span> <span class=p>{</span> </span></span><span class=line><span class=cl> pdl<span class=p>.</span>replace <span class=nv>%root</span> with <span class=p>(</span><span class=nv>%inputOperand</span><span class=p>)</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>The above pattern simply replaces an operation with its first operand. Note how the input operation is specified structurally, similarly to how it would look in memory. This is a simple example and pdl provides support for many other features such as applying external constraints or external generator methods. These features and more are detailed below.</p><p><nav id=TableOfContents><ul><li><a href=#operations>Operations</a><ul><li><a href=#pdlapply_native_constraint-pdlapplynativeconstraintop><code>pdl.apply_native_constraint</code> (pdl::ApplyNativeConstraintOp)</a></li><li><a href=#pdlapply_native_rewrite-pdlapplynativerewriteop><code>pdl.apply_native_rewrite</code> (pdl::ApplyNativeRewriteOp)</a></li><li><a href=#pdlattribute-pdlattributeop><code>pdl.attribute</code> (pdl::AttributeOp)</a></li><li><a href=#pdlerase-pdleraseop><code>pdl.erase</code> (pdl::EraseOp)</a></li><li><a href=#pdloperand-pdloperandop><code>pdl.operand</code> (pdl::OperandOp)</a></li><li><a href=#pdloperands-pdloperandsop><code>pdl.operands</code> (pdl::OperandsOp)</a></li><li><a href=#pdloperation-pdloperationop><code>pdl.operation</code> (pdl::OperationOp)</a></li><li><a href=#pdlpattern-pdlpatternop><code>pdl.pattern</code> (pdl::PatternOp)</a></li><li><a href=#pdlrange-pdlrangeop><code>pdl.range</code> (pdl::RangeOp)</a></li><li><a href=#pdlreplace-pdlreplaceop><code>pdl.replace</code> (pdl::ReplaceOp)</a></li><li><a href=#pdlresult-pdlresultop><code>pdl.result</code> (pdl::ResultOp)</a></li><li><a href=#pdlresults-pdlresultsop><code>pdl.results</code> (pdl::ResultsOp)</a></li><li><a href=#pdlrewrite-pdlrewriteop><code>pdl.rewrite</code> (pdl::RewriteOp)</a></li><li><a href=#pdltype-pdltypeop><code>pdl.type</code> (pdl::TypeOp)</a></li><li><a href=#pdltypes-pdltypesop><code>pdl.types</code> (pdl::TypesOp)</a></li></ul></li><li><a href=#types>Types</a><ul><li><a href=#attributetype>AttributeType</a></li><li><a href=#operationtype>OperationType</a></li><li><a href=#rangetype>RangeType</a></li><li><a href=#typetype>TypeType</a></li><li><a href=#valuetype>ValueType</a></li></ul></li></ul></nav><h2 id=operations>Operations <a class=headline-hash href=#operations>¶</a></h2><p><a href=https://github.com/llvm/llvm-project/blob/main/mlir/include/mlir/Dialect/PDL/IR/PDLOps.td>source</a></p><h3 id=pdlapply_native_constraint-pdlapplynativeconstraintop><code>pdl.apply_native_constraint</code> (pdl::ApplyNativeConstraintOp) <a class=headline-hash href=#pdlapply_native_constraint-pdlapplynativeconstraintop>¶</a></h3><p><em>Apply a native constraint to a set of provided entities</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.apply_native_constraint` $name `(` $args `:` type($args) `)` (`:` type($results)^ )? attr-dict </code></pre><p><code>pdl.apply_native_constraint</code> operations apply a native C++ constraint, that has been registered externally with the consumer of PDL, to a given set of entities and optionally return a number of values.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Apply `myConstraint` to the entities defined by `input`, `attr`, and `op`. </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>apply_native_constraint <span class=s>"myConstraint"</span><span class=p>(</span><span class=nv>%input</span><span class=p>,</span> <span class=nv>%attr</span><span class=p>,</span> <span class=nv>%op</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>value<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>attribute<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>operation<span class=p>)</span> </span></span><span class=line><span class=cl><span class=c>// Apply constraint `with_result` to `root`. This constraint returns an attribute. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%attr</span> <span class=p>=</span> pdl<span class=p>.</span>apply_native_constraint <span class=s>"with_result"</span><span class=p>(</span><span class=nv>%root</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>operation<span class=p>)</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>attribute </span></span></code></pre></div><p>Traits: <code>HasParent<pdl::PatternOp></code></p><h4 id=attributes>Attributes: <a class=headline-hash href=#attributes>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>name</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr><tr><td><code>isNegated</code></td><td>::mlir::BoolAttr</td><td>bool attribute</td></tr></table><h4 id=operands>Operands: <a class=headline-hash href=#operands>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>args</code></td><td>variadic of pdl type</td></tr></tbody></table><h4 id=results>Results: <a class=headline-hash href=#results>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>results</code></td><td>variadic of pdl type</td></tr></tbody></table><h3 id=pdlapply_native_rewrite-pdlapplynativerewriteop><code>pdl.apply_native_rewrite</code> (pdl::ApplyNativeRewriteOp) <a class=headline-hash href=#pdlapply_native_rewrite-pdlapplynativerewriteop>¶</a></h3><p><em>Apply a native rewrite method inside of pdl.rewrite region</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.apply_native_rewrite` $name (`(` $args^ `:` type($args) `)`)? (`:` type($results)^)? attr-dict </code></pre><p><code>pdl.apply_native_rewrite</code> operations apply a native C++ function, that has been registered externally with the consumer of PDL, to perform a rewrite and optionally return a number of values. The native function may accept any number of arguments. This operation is used within a pdl.rewrite region to enable the interleaving of native rewrite methods with other pdl constructs.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Apply a native rewrite method that returns an attribute. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%ret</span> <span class=p>=</span> pdl<span class=p>.</span>apply_native_rewrite <span class=s>"myNativeFunc"</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%attr1</span><span class=p>)</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>attribute </span></span></code></pre></div><div class=highlight><pre tabindex=0 class=chroma><code class=language-c++ data-lang=c++><span class=line><span class=cl><span class=c1>// The native rewrite as defined in C++: </span></span></span><span class=line><span class=cl><span class=c1></span><span class=k>static</span> <span class=n>Attribute</span> <span class=nf>myNativeFunc</span><span class=p>(</span><span class=n>PatternRewriter</span> <span class=o>&</span><span class=n>rewriter</span><span class=p>,</span> <span class=n>Value</span> <span class=n>arg0</span><span class=p>,</span> <span class=n>Attribute</span> <span class=n>arg1</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=c1>// Just return the second arg. </span></span></span><span class=line><span class=cl><span class=c1></span> <span class=k>return</span> <span class=n>arg1</span><span class=p>;</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=kt>void</span> <span class=nf>registerNativeRewrite</span><span class=p>(</span><span class=n>PDLPatternModule</span> <span class=o>&</span><span class=n>pdlModule</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=n>pdlModule</span><span class=p>.</span><span class=n>registerRewriteFunction</span><span class=p>(</span><span class=s>"myNativeFunc"</span><span class=p>,</span> <span class=n>myNativeFunc</span><span class=p>);</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>Traits: <code>HasParent<pdl::RewriteOp></code></p><h4 id=attributes-1>Attributes: <a class=headline-hash href=#attributes-1>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>name</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr></table><h4 id=operands-1>Operands: <a class=headline-hash href=#operands-1>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>args</code></td><td>variadic of pdl type</td></tr></tbody></table><h4 id=results-1>Results: <a class=headline-hash href=#results-1>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>results</code></td><td>variadic of pdl type</td></tr></tbody></table><h3 id=pdlattribute-pdlattributeop><code>pdl.attribute</code> (pdl::AttributeOp) <a class=headline-hash href=#pdlattribute-pdlattributeop>¶</a></h3><p><em>Define an input attribute in a pattern</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.attribute` (`:` $valueType^)? (`=` $value^)? attr-dict-with-keyword </code></pre><p><code>pdl.attribute</code> operations capture named attribute edges into an operation. Instances of this operation define, and partially constrain, attributes of a given operation. A <code>pdl.attribute</code> may partially constrain the input by specifying an expected attribute value type (via a <code>pdl.type</code> operation), or a constant value for the attribute (via <code>val</code>). Only one of these may be set for a given input, as the type of the constant value provides the type. When defined within a <code>pdl.rewrite</code> region, the constant value must be specified.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Define an attribute: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%attr</span> <span class=p>=</span> pdl<span class=p>.</span>attribute </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Define an attribute with an expected type: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%type</span> <span class=p>=</span> pdl<span class=p>.</span>type <span class=p>:</span> <span class=k>i32</span> </span></span><span class=line><span class=cl><span class=nv>%attr</span> <span class=p>=</span> pdl<span class=p>.</span>attribute <span class=p>:</span> <span class=nv>%type</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Define an attribute with a constant value: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%attr</span> <span class=p>=</span> <span class=nl>pdl.attribute =</span> <span class=s>"hello"</span> </span></span></code></pre></div><h4 id=attributes-2>Attributes: <a class=headline-hash href=#attributes-2>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>value</code></td><td>::mlir::Attribute</td><td>any attribute</td></tr></table><h4 id=operands-2>Operands: <a class=headline-hash href=#operands-2>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>valueType</code></td><td>PDL handle to an <code>mlir::Type</code></td></tr></tbody></table><h4 id=results-2>Results: <a class=headline-hash href=#results-2>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>attr</code></td><td>PDL handle to an <code>mlir::Attribute</code></td></tr></tbody></table><h3 id=pdlerase-pdleraseop><code>pdl.erase</code> (pdl::EraseOp) <a class=headline-hash href=#pdlerase-pdleraseop>¶</a></h3><p><em>Mark an input operation as <code>erased</code></em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.erase` $opValue attr-dict </code></pre><p><code>pdl.erase</code> operations are used within <code>pdl.rewrite</code> regions to specify that an input operation should be marked as erased. The semantics of this operation correspond with the <code>eraseOp</code> method on a <code>PatternRewriter</code>.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl>pdl<span class=p>.</span>erase <span class=nv>%root</span> </span></span></code></pre></div><p>Traits: <code>HasParent<pdl::RewriteOp></code></p><h4 id=operands-3>Operands: <a class=headline-hash href=#operands-3>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>opValue</code></td><td>PDL handle to an <code>mlir::Operation *</code></td></tr></tbody></table><h3 id=pdloperand-pdloperandop><code>pdl.operand</code> (pdl::OperandOp) <a class=headline-hash href=#pdloperand-pdloperandop>¶</a></h3><p><em>Define an external input operand in a pattern</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.operand` (`:` $valueType^)? attr-dict </code></pre><p><code>pdl.operand</code> operations capture external operand edges into an operation node that originate from operations or block arguments not otherwise specified within the pattern (i.e. via <code>pdl.result</code> or <code>pdl.results</code>). These operations define individual operands of a given operation. A <code>pdl.operand</code> may partially constrain an operand by specifying an expected value type (via a <code>pdl.type</code> operation).</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Define an external operand: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%operand</span> <span class=p>=</span> pdl<span class=p>.</span>operand </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Define an external operand with an expected type: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%type</span> <span class=p>=</span> pdl<span class=p>.</span>type <span class=p>:</span> <span class=k>i32</span> </span></span><span class=line><span class=cl><span class=nv>%operand</span> <span class=p>=</span> pdl<span class=p>.</span>operand <span class=p>:</span> <span class=nv>%type</span> </span></span></code></pre></div><p>Traits: <code>HasParent<pdl::PatternOp></code></p><h4 id=operands-4>Operands: <a class=headline-hash href=#operands-4>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>valueType</code></td><td>PDL handle to an <code>mlir::Type</code></td></tr></tbody></table><h4 id=results-3>Results: <a class=headline-hash href=#results-3>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>value</code></td><td>PDL handle for an <code>mlir::Value</code></td></tr></tbody></table><h3 id=pdloperands-pdloperandsop><code>pdl.operands</code> (pdl::OperandsOp) <a class=headline-hash href=#pdloperands-pdloperandsop>¶</a></h3><p><em>Define a range of input operands in a pattern</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.operands` (`:` $valueType^)? attr-dict </code></pre><p><code>pdl.operands</code> operations capture external operand range edges into an operation node that originate from operations or block arguments not otherwise specified within the pattern (i.e. via <code>pdl.result</code> or <code>pdl.results</code>). These operations define groups of input operands into a given operation. A <code>pdl.operands</code> may partially constrain a set of input operands by specifying expected value types (via <code>pdl.types</code> operations).</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Define a range of input operands: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%operands</span> <span class=p>=</span> pdl<span class=p>.</span>operands </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Define a range of input operands with expected types: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%types</span> <span class=p>=</span> pdl<span class=p>.</span>types <span class=p>:</span> <span class=p>[</span><span class=k>i32</span><span class=p>,</span> <span class=k>i64</span><span class=p>,</span> <span class=k>i32</span><span class=p>]</span> </span></span><span class=line><span class=cl><span class=nv>%typed_operands</span> <span class=p>=</span> pdl<span class=p>.</span>operands <span class=p>:</span> <span class=nv>%types</span> </span></span></code></pre></div><p>Traits: <code>HasParent<pdl::PatternOp></code></p><h4 id=operands-5>Operands: <a class=headline-hash href=#operands-5>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>valueType</code></td><td>range of PDL handle to an <code>mlir::Type</code> values</td></tr></tbody></table><h4 id=results-4>Results: <a class=headline-hash href=#results-4>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>value</code></td><td>range of PDL handle for an <code>mlir::Value</code> values</td></tr></tbody></table><h3 id=pdloperation-pdloperationop><code>pdl.operation</code> (pdl::OperationOp) <a class=headline-hash href=#pdloperation-pdloperationop>¶</a></h3><p><em>Define an operation within a pattern</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.operation` ($opName^)? (`(` $operandValues^ `:` type($operandValues) `)`)? custom<OperationOpAttributes>($attributeValues, $attributeValueNames) (`->` `(` $typeValues^ `:` type($typeValues) `)`)? attr-dict </code></pre><p><code>pdl.operation</code> operations define operation nodes within a pattern. Within a match sequence, i.e. when directly nested within a <code>pdl.pattern</code>, these operations correspond to input operations, or those that already existing within the MLIR module. Inside of a <code>pdl.rewrite</code>, these operations correspond to operations that should be created as part of the replacement sequence.</p><p><code>pdl.operation</code>s are composed of a name, and a set of attribute, operand, and result type values, that map to what those that would be on a constructed instance of that operation. The results of a <code>pdl.operation</code> are a handle to the operation itself. Handles to the results of the operation can be extracted via <code>pdl.result</code>.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Define an instance of a `foo.op` operation. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%op</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"foo.op"</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%arg1</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>value<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>value<span class=p>)</span> </span></span><span class=line><span class=cl> <span class=p>{</span><span class=s>"attrA"</span> <span class=p>=</span> <span class=nv>%attr0</span><span class=p>}</span> <span class=p>-></span> <span class=p>(</span><span class=nv>%type</span><span class=p>,</span> <span class=nv>%type</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>type<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>type<span class=p>)</span> </span></span></code></pre></div><p>When used within a matching context, the name of the operation may be omitted.</p><p>When used within a rewriting context, i.e. when defined within a <code>pdl.rewrite</code>, all of the result types must be “inferable”. This means that the type must be attributable to either a constant type value or the result type of another entity, such as an attribute, the result of a <code>apply_native_rewrite</code>, or the result type of another operation. If the result type value does not meet any of these criteria, the operation must override the <code>InferTypeOpInterface</code> to ensure that the result types can be inferred.</p><p>The operands of the operation are interpreted in the following ways:</p><ol><li>A single !pdl.range<value>:</li></ol><p>In this case, the single range is treated as all of the operands of the operation.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Define an instance with single range of operands. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%op</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"func.return"</span><span class=p>(</span><span class=nv>%allArgs</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>range<span class=p><</span>value<span class=p>>)</span> </span></span></code></pre></div><ol start=2><li>A variadic number of either !pdl.value or !pdl.range<value>:</li></ol><p>In this case, the inputs are expected to correspond with the operand groups defined on the operation in ODS.</p><pre tabindex=0><code class=language-tablgen data-lang=tablgen>// Given the following operation definition in ODS: def MyIndirectCallOp { let results = (outs FunctionType:$call, Variadic<AnyType>:$args); } </code></pre><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// We can match the operands as so: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%op</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"my.indirect_call"</span><span class=p>(</span><span class=nv>%call</span><span class=p>,</span> <span class=nv>%args</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>value<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>range<span class=p><</span>value<span class=p>>)</span> </span></span></code></pre></div><p>The results of the operation are interpreted in the following ways:</p><ol><li>A single !pdl.range<type>:</li></ol><p>In this case, the single range is treated as all of the result types of the operation.</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Define an instance with single range of types. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%allResultTypes</span> <span class=p>=</span> pdl<span class=p>.</span>types </span></span><span class=line><span class=cl><span class=nv>%op</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"builtin.unrealized_conversion_cast"</span> <span class=p>-></span> <span class=p>(</span><span class=nv>%allResultTypes</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>types<span class=p>)</span> </span></span></code></pre></div><ol start=2><li>A variadic number of either !pdl.type or !pdl.range<type>:</li></ol><p>In this case, the inputs are expected to correspond with the result groups defined on the operation in ODS.</p><pre tabindex=0><code class=language-tablgen data-lang=tablgen>// Given the following operation definition in ODS: def MyOp { let results = (outs SomeType:$result, Variadic<SomeType>:$otherResults); } </code></pre><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// We can match the results as so: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%result</span> <span class=p>=</span> pdl<span class=p>.</span>type </span></span><span class=line><span class=cl><span class=nv>%otherResults</span> <span class=p>=</span> pdl<span class=p>.</span>types </span></span><span class=line><span class=cl><span class=nv>%op</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"foo.op"</span> <span class=p>-></span> <span class=p>(</span><span class=nv>%result</span><span class=p>,</span> <span class=nv>%otherResults</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>type<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>range<span class=p><</span>type<span class=p>>)</span> </span></span></code></pre></div><p>Traits: <code>AttrSizedOperandSegments</code></p><h4 id=attributes-3>Attributes: <a class=headline-hash href=#attributes-3>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>opName</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr><tr><td><code>attributeValueNames</code></td><td>::mlir::ArrayAttr</td><td>string array attribute</td></tr></table><h4 id=operands-6>Operands: <a class=headline-hash href=#operands-6>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>operandValues</code></td><td>variadic of single element or range of PDL handle for an <code>mlir::Value</code></td></tr><tr><td style=text-align:center><code>attributeValues</code></td><td>variadic of PDL handle to an <code>mlir::Attribute</code></td></tr><tr><td style=text-align:center><code>typeValues</code></td><td>variadic of single element or range of PDL handle to an <code>mlir::Type</code></td></tr></tbody></table><h4 id=results-5>Results: <a class=headline-hash href=#results-5>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>op</code></td><td>PDL handle to an <code>mlir::Operation *</code></td></tr></tbody></table><h3 id=pdlpattern-pdlpatternop><code>pdl.pattern</code> (pdl::PatternOp) <a class=headline-hash href=#pdlpattern-pdlpatternop>¶</a></h3><p><em>Define a rewrite pattern</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.pattern` ($sym_name^)? `:` `benefit` `(` $benefit `)` attr-dict-with-keyword $bodyRegion </code></pre><p><code>pdl.pattern</code> operations provide a transformable representation for a <code>RewritePattern</code>. The attributes on this operation correspond to the various metadata on a <code>RewritePattern</code>, such as the benefit. The match section of the pattern is specified within the region body, with the rewrite provided by a terminating <code>pdl.rewrite</code>.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Provide a pattern matching "foo.op" that replaces the root with its </span></span></span><span class=line><span class=cl><span class=c>// operand. </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>pattern <span class=p>:</span> benefit<span class=p>(</span><span class=m>1</span><span class=p>)</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%resultType</span> <span class=p>=</span> pdl<span class=p>.</span>type </span></span><span class=line><span class=cl> <span class=nv>%inputOperand</span> <span class=p>=</span> pdl<span class=p>.</span>operand </span></span><span class=line><span class=cl> <span class=nv>%root</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"foo.op"</span><span class=p>(</span><span class=nv>%inputOperand</span><span class=p>)</span> <span class=p>-></span> <span class=p>(</span><span class=nv>%resultType</span><span class=p>)</span> </span></span><span class=line><span class=cl> pdl<span class=p>.</span>rewrite <span class=nv>%root</span> <span class=p>{</span> </span></span><span class=line><span class=cl> pdl<span class=p>.</span>replace <span class=nv>%root</span> with <span class=p>(</span><span class=nv>%inputOperand</span><span class=p>)</span> </span></span><span class=line><span class=cl> <span class=p>}</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>Traits: <code>IsolatedFromAbove</code>, <code>SingleBlock</code></p><p>Interfaces: <code>OpAsmOpInterface</code>, <code>Symbol</code></p><h4 id=attributes-4>Attributes: <a class=headline-hash href=#attributes-4>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>benefit</code></td><td>::mlir::IntegerAttr</td><td>16-bit signless integer attribute whose value is non-negative</td></tr><tr><td><code>sym_name</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr></table><h3 id=pdlrange-pdlrangeop><code>pdl.range</code> (pdl::RangeOp) <a class=headline-hash href=#pdlrange-pdlrangeop>¶</a></h3><p><em>Construct a range of pdl entities</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.range` ($arguments^ `:` type($arguments))? custom<RangeType>(ref(type($arguments)), type($result)) attr-dict </code></pre><p><code>pdl.range</code> operations construct a range from a given set of PDL entities, which all share the same underlying element type. For example, a <code>!pdl.range<value></code> may be constructed from a list of <code>!pdl.value</code> or <code>!pdl.range<value></code> entities.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Construct a range of values. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%valueRange</span> <span class=p>=</span> pdl<span class=p>.</span>range <span class=nv>%inputValue</span><span class=p>,</span> <span class=nv>%inputRange</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>value<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>range<span class=p><</span>value<span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Construct a range of types. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%typeRange</span> <span class=p>=</span> pdl<span class=p>.</span>range <span class=nv>%inputType</span><span class=p>,</span> <span class=nv>%inputRange</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>type<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>range<span class=p><</span>type<span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Construct an empty range of types. </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%valueRange</span> <span class=p>=</span> pdl<span class=p>.</span>range <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>range<span class=p><</span>type<span class=p>></span> </span></span></code></pre></div><p>TODO: Range construction is currently limited to rewrites, but it could be extended to constraints under certain circustances; i.e., if we can determine how to extract the underlying elements. If we can’t, e.g. if there are multiple sub ranges used for construction, we won’t be able to determine their sizes during constraint time.</p><p>Traits: <code>AlwaysSpeculatableImplTrait</code>, <code>HasParent<pdl::RewriteOp></code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>NoMemoryEffect (MemoryEffectOpInterface)</code></p><p>Effects: <code>MemoryEffects::Effect{}</code></p><h4 id=operands-7>Operands: <a class=headline-hash href=#operands-7>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>arguments</code></td><td>variadic of pdl type</td></tr></tbody></table><h4 id=results-6>Results: <a class=headline-hash href=#results-6>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>result</code></td><td>range of PDL handle to an <code>mlir::Type</code> or PDL handle for an <code>mlir::Value</code> values</td></tr></tbody></table><h3 id=pdlreplace-pdlreplaceop><code>pdl.replace</code> (pdl::ReplaceOp) <a class=headline-hash href=#pdlreplace-pdlreplaceop>¶</a></h3><p><em>Mark an input operation as <code>replaced</code></em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.replace` $opValue `with` (`(` $replValues^ `:` type($replValues) `)`)? ($replOperation^)? attr-dict </code></pre><p><code>pdl.replace</code> operations are used within <code>pdl.rewrite</code> regions to specify that an input operation should be marked as replaced. The semantics of this operation correspond with the <code>replaceOp</code> method on a <code>PatternRewriter</code>. The set of replacement values can be either:</p><ul><li>a single <code>Operation</code> (<code>replOperation</code> should be populated)<ul><li>The operation will be replaced with the results of this operation.</li></ul></li><li>a set of <code>Value</code>s (<code>replValues</code> should be populated)<ul><li>The operation will be replaced with these values.</li></ul></li></ul><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Replace root node with 2 values: </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>replace <span class=nv>%root</span> with <span class=p>(</span><span class=nv>%val0</span><span class=p>,</span> <span class=nv>%val1</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>value<span class=p>,</span> <span class=p>!</span>pdl<span class=p>.</span>value<span class=p>)</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Replace root node with a range of values: </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>replace <span class=nv>%root</span> with <span class=p>(</span><span class=nv>%vals</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>range<span class=p><</span>value<span class=p>>)</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Replace root with another operation: </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>replace <span class=nv>%root</span> with <span class=nv>%otherOp</span> </span></span></code></pre></div><p>Traits: <code>AttrSizedOperandSegments</code>, <code>HasParent<pdl::RewriteOp></code></p><h4 id=operands-8>Operands: <a class=headline-hash href=#operands-8>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>opValue</code></td><td>PDL handle to an <code>mlir::Operation *</code></td></tr><tr><td style=text-align:center><code>replOperation</code></td><td>PDL handle to an <code>mlir::Operation *</code></td></tr><tr><td style=text-align:center><code>replValues</code></td><td>variadic of single element or range of PDL handle for an <code>mlir::Value</code></td></tr></tbody></table><h3 id=pdlresult-pdlresultop><code>pdl.result</code> (pdl::ResultOp) <a class=headline-hash href=#pdlresult-pdlresultop>¶</a></h3><p><em>Extract a result from an operation</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.result` $index `of` $parent attr-dict </code></pre><p><code>pdl.result</code> operations extract result edges from an operation node within a pattern or rewrite region. The provided index is zero-based, and represents the concrete result to extract, i.e. this is not the result index as defined by the ODS definition of the operation.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Extract a result: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%operation</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=p>...</span> </span></span><span class=line><span class=cl><span class=nv>%pdl_result</span> <span class=p>=</span> pdl<span class=p>.</span>result <span class=m>1</span> of <span class=nv>%operation</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Imagine the following IR being matched: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%result_0</span><span class=p>,</span> <span class=nv>%result_1</span> <span class=p>=</span> foo<span class=p>.</span>op <span class=p>...</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// If the example pattern snippet above were matching against `foo.op` in </span></span></span><span class=line><span class=cl><span class=c>// the IR snippet, `%pdl_result` would correspond to `%result_1`. </span></span></span></code></pre></div><p>Traits: <code>AlwaysSpeculatableImplTrait</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>NoMemoryEffect (MemoryEffectOpInterface)</code></p><p>Effects: <code>MemoryEffects::Effect{}</code></p><h4 id=attributes-5>Attributes: <a class=headline-hash href=#attributes-5>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>index</code></td><td>::mlir::IntegerAttr</td><td>32-bit signless integer attribute</td></tr></table><h4 id=operands-9>Operands: <a class=headline-hash href=#operands-9>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>parent</code></td><td>PDL handle to an <code>mlir::Operation *</code></td></tr></tbody></table><h4 id=results-7>Results: <a class=headline-hash href=#results-7>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>val</code></td><td>PDL handle for an <code>mlir::Value</code></td></tr></tbody></table><h3 id=pdlresults-pdlresultsop><code>pdl.results</code> (pdl::ResultsOp) <a class=headline-hash href=#pdlresults-pdlresultsop>¶</a></h3><p><em>Extract a result group from an operation</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.results` ($index^)? `of` $parent custom<ResultsValueType>(ref($index), type($val)) attr-dict </code></pre><p><code>pdl.results</code> operations extract a result group from an operation within a pattern or rewrite region. If an index is provided, this operation extracts a result group as defined by the ODS definition of the operation. In this case the result of this operation may be either a single <code>pdl.value</code> or a <code>pdl.range<value></code>, depending on the constraint of the result in ODS. If no index is provided, this operation extracts the full result range of the operation.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Extract all of the results of an operation: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%operation</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=p>...</span> </span></span><span class=line><span class=cl><span class=nv>%results</span> <span class=p>=</span> pdl<span class=p>.</span>results of <span class=nv>%operation</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Extract the results in the first result group of an operation, which is </span></span></span><span class=line><span class=cl><span class=c>// variadic: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%operation</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=p>...</span> </span></span><span class=line><span class=cl><span class=nv>%results</span> <span class=p>=</span> pdl<span class=p>.</span>results <span class=m>0</span> of <span class=nv>%operation</span> <span class=p>-></span> <span class=p>!</span>pdl<span class=p>.</span>range<span class=p><</span>value<span class=p>></span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Extract the results in the second result group of an operation, which is </span></span></span><span class=line><span class=cl><span class=c>// not variadic: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%operation</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=p>...</span> </span></span><span class=line><span class=cl><span class=nv>%results</span> <span class=p>=</span> pdl<span class=p>.</span>results <span class=m>1</span> of <span class=nv>%operation</span> <span class=p>-></span> <span class=p>!</span>pdl<span class=p>.</span>value </span></span></code></pre></div><p>Traits: <code>AlwaysSpeculatableImplTrait</code></p><p>Interfaces: <code>ConditionallySpeculatable</code>, <code>NoMemoryEffect (MemoryEffectOpInterface)</code></p><p>Effects: <code>MemoryEffects::Effect{}</code></p><h4 id=attributes-6>Attributes: <a class=headline-hash href=#attributes-6>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>index</code></td><td>::mlir::IntegerAttr</td><td>32-bit signless integer attribute</td></tr></table><h4 id=operands-10>Operands: <a class=headline-hash href=#operands-10>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>parent</code></td><td>PDL handle to an <code>mlir::Operation *</code></td></tr></tbody></table><h4 id=results-8>Results: <a class=headline-hash href=#results-8>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>val</code></td><td>single element or range of PDL handle for an <code>mlir::Value</code></td></tr></tbody></table><h3 id=pdlrewrite-pdlrewriteop><code>pdl.rewrite</code> (pdl::RewriteOp) <a class=headline-hash href=#pdlrewrite-pdlrewriteop>¶</a></h3><p><em>Specify the rewrite of a matched pattern</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.rewrite` ($root^)? (`with` $name^ (`(` $externalArgs^ `:` type($externalArgs) `)`)?)? ($bodyRegion^)? attr-dict-with-keyword </code></pre><p><code>pdl.rewrite</code> operations terminate the region of a <code>pdl.pattern</code> and specify the main rewrite of a <code>pdl.pattern</code>, on the optional root operation. The rewrite is specified either via a string name (<code>name</code>) to a native rewrite function, or via the region body. The rewrite region, if specified, must contain a single block. If the rewrite is external it functions similarly to <code>pdl.apply_native_rewrite</code>, and takes a set of additional positional values defined within the matcher as arguments. If the rewrite is external, the root operation is passed to the native function as the leading arguments. The root operation, if provided, specifies the starting point in the pattern for the subgraph isomorphism search. Pattern matching will proceed from this node downward (towards the defining operation) or upward (towards the users) until all the operations in the pattern have been matched. If the root is omitted, the pdl_interp lowering will automatically select the best root of the pdl.rewrite among all the operations in the pattern.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Specify an external rewrite function: </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>rewrite <span class=nv>%root</span> with <span class=s>"myExternalRewriter"</span><span class=p>(</span><span class=nv>%value</span> <span class=p>:</span> <span class=p>!</span>pdl<span class=p>.</span>value<span class=p>)</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Specify a rewrite inline using PDL with the given root: </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>rewrite <span class=nv>%root</span> <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%op</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"foo.op"</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%arg1</span><span class=p>)</span> </span></span><span class=line><span class=cl> pdl<span class=p>.</span>replace <span class=nv>%root</span> with <span class=nv>%op</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Specify a rewrite inline using PDL, automatically selecting root: </span></span></span><span class=line><span class=cl><span class=c></span>pdl<span class=p>.</span>rewrite <span class=p>{</span> </span></span><span class=line><span class=cl> <span class=nv>%op1</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"foo.op"</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%arg1</span><span class=p>)</span> </span></span><span class=line><span class=cl> <span class=nv>%op2</span> <span class=p>=</span> pdl<span class=p>.</span>operation <span class=s>"bar.op"</span><span class=p>(</span><span class=nv>%arg0</span><span class=p>,</span> <span class=nv>%arg1</span><span class=p>)</span> </span></span><span class=line><span class=cl> pdl<span class=p>.</span>replace <span class=nv>%root1</span> with <span class=nv>%op1</span> </span></span><span class=line><span class=cl> pdl<span class=p>.</span>replace <span class=nv>%root2</span> with <span class=nv>%op2</span> </span></span><span class=line><span class=cl><span class=p>}</span> </span></span></code></pre></div><p>Traits: <code>AttrSizedOperandSegments</code>, <code>HasParent<pdl::PatternOp></code>, <code>NoRegionArguments</code>, <code>NoTerminator</code>, <code>SingleBlock</code>, <code>Terminator</code></p><p>Interfaces: <code>OpAsmOpInterface</code></p><h4 id=attributes-7>Attributes: <a class=headline-hash href=#attributes-7>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>name</code></td><td>::mlir::StringAttr</td><td>string attribute</td></tr></table><h4 id=operands-11>Operands: <a class=headline-hash href=#operands-11>¶</a></h4><table><thead><tr><th style=text-align:center>Operand</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>root</code></td><td>PDL handle to an <code>mlir::Operation *</code></td></tr><tr><td style=text-align:center><code>externalArgs</code></td><td>variadic of pdl type</td></tr></tbody></table><h3 id=pdltype-pdltypeop><code>pdl.type</code> (pdl::TypeOp) <a class=headline-hash href=#pdltype-pdltypeop>¶</a></h3><p><em>Define a type handle within a pattern</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.type` attr-dict (`:` $constantType^)? </code></pre><p><code>pdl.type</code> operations capture result type constraints of <code>Attributes</code>, <code>Values</code>, and <code>Operations</code>. Instances of this operation define, and partially constrain, results types of a given entity. A <code>pdl.type</code> may partially constrain the result by specifying a constant <code>Type</code>.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Define a type: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%type</span> <span class=p>=</span> pdl<span class=p>.</span>type </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Define a type with a constant value: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%type</span> <span class=p>=</span> pdl<span class=p>.</span>type <span class=p>:</span> <span class=k>i32</span> </span></span></code></pre></div><h4 id=attributes-8>Attributes: <a class=headline-hash href=#attributes-8>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>constantType</code></td><td>::mlir::TypeAttr</td><td>any type attribute</td></tr></table><h4 id=results-9>Results: <a class=headline-hash href=#results-9>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>result</code></td><td>PDL handle to an <code>mlir::Type</code></td></tr></tbody></table><h3 id=pdltypes-pdltypesop><code>pdl.types</code> (pdl::TypesOp) <a class=headline-hash href=#pdltypes-pdltypesop>¶</a></h3><p><em>Define a range of type handles within a pattern</em></p><p>Syntax:</p><pre tabindex=0><code>operation ::= `pdl.types` attr-dict (`:` $constantTypes^)? </code></pre><p><code>pdl.types</code> operations capture result type constraints of <code>Value</code>s, and <code>Operation</code>s. Instances of this operation define results types of a given entity. A <code>pdl.types</code> may partially constrain the results by specifying an array of <code>Type</code>s.</p><p>Example:</p><div class=highlight><pre tabindex=0 class=chroma><code class=language-mlir data-lang=mlir><span class=line><span class=cl><span class=c>// Define a range of types: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%types</span> <span class=p>=</span> pdl<span class=p>.</span>types </span></span><span class=line><span class=cl> </span></span><span class=line><span class=cl><span class=c>// Define a range of types with a range of constant values: </span></span></span><span class=line><span class=cl><span class=c></span><span class=nv>%types</span> <span class=p>=</span> pdl<span class=p>.</span>types <span class=p>:</span> <span class=p>[</span><span class=k>i32</span><span class=p>,</span> <span class=k>i64</span><span class=p>,</span> <span class=k>i32</span><span class=p>]</span> </span></span></code></pre></div><h4 id=attributes-9>Attributes: <a class=headline-hash href=#attributes-9>¶</a></h4><table><tr><th>Attribute</th><th>MLIR Type</th><th>Description</th></tr><tr><td><code>constantTypes</code></td><td>::mlir::ArrayAttr</td><td>type array attribute</td></tr></table><h4 id=results-10>Results: <a class=headline-hash href=#results-10>¶</a></h4><table><thead><tr><th style=text-align:center>Result</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center><code>result</code></td><td>range of PDL handle to an <code>mlir::Type</code> values</td></tr></tbody></table><h2 id=types>Types <a class=headline-hash href=#types>¶</a></h2><h3 id=attributetype>AttributeType <a class=headline-hash href=#attributetype>¶</a></h3><p>PDL handle to an <code>mlir::Attribute</code></p><p>Syntax: <code>!pdl.attribute</code></p><p>This type represents a handle to an instance of an <code>mlir::Attribute</code>, bound to a value that is usable within a PDL pattern or rewrite.</p><h3 id=operationtype>OperationType <a class=headline-hash href=#operationtype>¶</a></h3><p>PDL handle to an <code>mlir::Operation *</code></p><p>Syntax: <code>!pdl.operation</code></p><p>This type represents a handle to an instance of an <code>mlir::Operation *</code>, bound to a value that is usable within a PDL pattern or rewrite.</p><h3 id=rangetype>RangeType <a class=headline-hash href=#rangetype>¶</a></h3><p>PDL handle to a range of a given sub-type</p><p>This type represents a range of instances of the given PDL element type, i.e. <code>Attribute</code>, <code>Operation</code>, <code>Type</code>, or <code>Value</code>.</p><h4 id=parameters>Parameters: <a class=headline-hash href=#parameters>¶</a></h4><table><thead><tr><th style=text-align:center>Parameter</th><th style=text-align:center>C++ type</th><th>Description</th></tr></thead><tbody><tr><td style=text-align:center>elementType</td><td style=text-align:center><code>Type</code></td><td></td></tr></tbody></table><h3 id=typetype>TypeType <a class=headline-hash href=#typetype>¶</a></h3><p>PDL handle to an <code>mlir::Type</code></p><p>Syntax: <code>!pdl.type</code></p><p>This type represents a handle to an instance of an <code>mlir::Type</code>, bound to a value that is usable within a PDL pattern or rewrite.</p><h3 id=valuetype>ValueType <a class=headline-hash href=#valuetype>¶</a></h3><p>PDL handle for an <code>mlir::Value</code></p><p>Syntax: <code>!pdl.value</code></p><p>This type represents a handle to an instance of an <code>mlir::Value</code>, bound to a value that is usable within a PDL pattern or rewrite.</p><div class=edit-meta><br></div><nav class=pagination><a class="nav nav-prev" href=https://mlir.llvm.org/docs/Dialects/PDLInterpOps/ title="'pdl_interp' Dialect"><i class="fas fa-arrow-left" aria-hidden=true></i> Prev - 'pdl_interp' Dialect</a> <a class="nav nav-next" href=https://mlir.llvm.org/docs/Dialects/PolynomialDialect/ title="'polynomial' Dialect">Next - 'polynomial' Dialect <i class="fas fa-arrow-right" aria-hidden=true></i></a></nav><footer><p class=powered>Powered by <a href=https://gohugo.io>Hugo</a>. Theme by <a href=https://themes.gohugo.io/hugo-theme-techdoc/>TechDoc</a>. Designed by <a href=https://github.com/thingsym/hugo-theme-techdoc>Thingsym</a>.</p></footer></main><div class=sidebar><nav class=slide-menu><ul><li><a href=https://mlir.llvm.org/>Home</a></li><li><a href=https://mlir.llvm.org/users/>Users of MLIR</a></li><li><a href=https://mlir.llvm.org/pubs/>MLIR Related Publications</a></li><li><a href=https://mlir.llvm.org/talks/>Talks</a></li><li><a href=https://mlir.llvm.org/deprecation/>Deprecations & Current Refactoring</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/getting_started/>Getting Started<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/getting_started/ReportingIssues/>Reporting Issues</a></li><li><a href=https://mlir.llvm.org/getting_started/Debugging/>Debugging Tips</a></li><li><a href=https://mlir.llvm.org/getting_started/Faq/>FAQ</a></li><li><a href=https://mlir.llvm.org/getting_started/Contributing/>How to Contribute</a></li><li><a href=https://mlir.llvm.org/getting_started/DeveloperGuide/>Developer Guide</a></li><li><a href=https://mlir.llvm.org/getting_started/openprojects/>Open Projects</a></li><li><a href=https://mlir.llvm.org/getting_started/Glossary/>Glossary</a></li><li><a href=https://mlir.llvm.org/getting_started/TestingGuide/>Testing Guide</a></li></ul></li><li class="parent has-sub-menu"><a href=https://mlir.llvm.org/docs/>Code Documentation<span class="mark opened">-</span></a><ul class=sub-menu><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Bindings/>Bindings<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Bindings/Python/>MLIR Python Bindings</a></li></ul></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Tools/>Tools<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Tools/MLIRLSP/>MLIR : Language Server Protocol</a></li><li><a href=https://mlir.llvm.org/docs/Tools/mlir-reduce/>MLIR Reduce</a></li><li><a href=https://mlir.llvm.org/docs/Tools/mlir-rewrite/>mlir-rewrite</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/QuantPasses/></a></li><li><a href=https://mlir.llvm.org/docs/ActionTracing/>Action: Tracing and Debugging MLIR-based Compilers</a></li><li><a href=https://mlir.llvm.org/docs/BufferDeallocationInternals/>Buffer Deallocation - Internals</a></li><li><a href=https://mlir.llvm.org/docs/Bufferization/>Bufferization</a></li><li><a href=https://mlir.llvm.org/docs/DataLayout/>Data Layout Modeling</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/DefiningDialects/>Defining Dialects<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/DefiningDialects/Constraints/>Constraints</a></li><li><a href=https://mlir.llvm.org/docs/DefiningDialects/AttributesAndTypes/>Defining Dialect Attributes and Types</a></li><li><a href=https://mlir.llvm.org/docs/DefiningDialects/Operations/>Operation Definition Specification (ODS)</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Diagnostics/>Diagnostic Infrastructure</a></li><li><a href=https://mlir.llvm.org/docs/DialectConversion/>Dialect Conversion</a></li><li class="parent has-sub-menu"><a href=https://mlir.llvm.org/docs/Dialects/>Dialects<span class="mark opened">-</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Dialects/DLTITransformOps/></a></li><li><a href=https://mlir.llvm.org/docs/Dialects/OpenACCDialect/>'acc' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Affine/>'affine' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/AMDGPU/>'amdgpu' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/AMX/>'amx' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ArithOps/>'arith' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ArmNeon/>'arm_neon' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ArmSVE/>'arm_sve' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ArmSME/>'ArmSME' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/AsyncDialect/>'async' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/BufferizationOps/>'bufferization' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ControlFlowDialect/>'cf' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ComplexOps/>'complex' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/DLTIDialect/>'dlti' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/EmitC/>'emitc' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Func/>'func' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/GPU/>'gpu' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/IndexOps/>'index' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/IRDL/>'irdl' Dialect</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Dialects/Linalg/>'linalg' Dialect<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Dialects/Linalg/OpDSL/>Linalg OpDSL</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Dialects/LLVM/>'llvm' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MathOps/>'math' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MemRef/>'memref' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Mesh/>'mesh' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MLProgramOps/>'ml_program' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MPI/>'mpi' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/NVGPU/>'nvgpu' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/NVVMDialect/>'nvvm' Dialect</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Dialects/OpenMPDialect/>'omp' Dialect<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Dialects/OpenMPDialect/ODS/>ODS Documentation</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Dialects/PDLInterpOps/>'pdl_interp' Dialect</a></li><li class=active><a href=https://mlir.llvm.org/docs/Dialects/PDLOps/>'pdl' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/PolynomialDialect/>'polynomial' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/PtrOps/>'ptr' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/QuantDialect/>'quant' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ROCDLDialect/>'rocdl' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/SCFDialect/>'scf' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/ShapeDialect/>'shape' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/SparseTensorOps/>'sparse_tensor' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/TensorOps/>'tensor' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/UBOps/>'ub' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/VCIXDialect/>'vcix' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Vector/>'vector' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/X86Vector/>'x86vector' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/XeGPU/>'xegpu' Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Builtin/>Builtin Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/MatchOpInterfaces/>OpInterface definitions</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/SPIR-V/>SPIR-V Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/TOSA/>Tensor Operator Set Architecture (TOSA) Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Dialects/Transform/>Transform Dialect</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Interfaces/>Interfaces</a></li><li><a href=https://mlir.llvm.org/docs/TargetLLVMIR/>LLVM IR Target</a></li><li><a href=https://mlir.llvm.org/docs/BytecodeFormat/>MLIR Bytecode Format</a></li><li><a href=https://mlir.llvm.org/docs/CAPI/>MLIR C API</a></li><li><a href=https://mlir.llvm.org/docs/LangRef/>MLIR Language Reference</a></li><li><a href=https://mlir.llvm.org/docs/ReleaseNotes/>MLIR Release Notes</a></li><li><a href=https://mlir.llvm.org/docs/Canonicalization/>Operation Canonicalization</a></li><li><a href=https://mlir.llvm.org/docs/OwnershipBasedBufferDeallocation/>Ownership-based Buffer Deallocation</a></li><li><a href=https://mlir.llvm.org/docs/PassManagement/>Pass Infrastructure</a></li><li><a href=https://mlir.llvm.org/docs/Passes/>Passes</a></li><li><a href=https://mlir.llvm.org/docs/PatternRewriter/>Pattern Rewriting : Generic DAG-to-DAG Rewriting</a></li><li><a href=https://mlir.llvm.org/docs/PDLL/>PDLL - PDL Language</a></li><li><a href=https://mlir.llvm.org/docs/Quantization/>Quantization</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Rationale/>Rationale<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Rationale/RationaleGenericDAGRewriter/>Generic DAG Rewriter Infrastructure Rationale</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/RationaleLinalgDialect/>Linalg Dialect Rationale: The Case For Compiler-Friendly Custom Operations</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/Rationale/>MLIR Rationale</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/MLIRForGraphAlgorithms/>MLIR: Incremental Application to Graph Algorithms in ML Frameworks</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/RationaleSimplifiedPolyhedralForm/>MLIR: The case for a simplified polyhedral form</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/SideEffectsAndSpeculation/>Side Effects & Speculation</a></li><li><a href=https://mlir.llvm.org/docs/Rationale/UsageOfConst/>Usage of 'const' in MLIR, for core IR types</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/ShapeInference/>Shape Inference</a></li><li><a href=https://mlir.llvm.org/docs/SPIRVToLLVMDialectConversion/>SPIR-V Dialect to LLVM Dialect conversion manual</a></li><li><a href=https://mlir.llvm.org/docs/SymbolsAndSymbolTables/>Symbols and Symbol Tables</a></li><li><a href=https://mlir.llvm.org/docs/DeclarativeRewrites/>Table-driven Declarative Rewrite Rule (DRR)</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Traits/>Traits<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Traits/Broadcastable/>The `Broadcastable` Trait</a></li></ul></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Tutorials/>Tutorials<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Tutorials/CreatingADialect/>Creating a Dialect</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/QuickstartRewrites/>Quickstart tutorial to adding MLIR graph rewrite</a></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Tutorials/Toy/>Toy Tutorial<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-1/>Chapter 1: Toy Language and AST</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-2/>Chapter 2: Emitting Basic MLIR</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-3/>Chapter 3: High-level Language-Specific Analysis and Transformation</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-4/>Chapter 4: Enabling Generic Transformation with Interfaces</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-5/>Chapter 5: Partial Lowering to Lower-Level Dialects for Optimization</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-6/>Chapter 6: Lowering to LLVM and CodeGeneration</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/Toy/Ch-7/>Chapter 7: Adding a Composite Type to Toy</a></li></ul></li><li class=has-sub-menu><a href=https://mlir.llvm.org/docs/Tutorials/transform/>Transform Dialect Tutorial<span class="mark closed">+</span></a><ul class=sub-menu><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch0/>Chapter 0: A Primer on “Structured” Linalg Operations</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch1/>Chapter 1: Combining Existing Transformations</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch2/>Chapter 2: Adding a Simple New Transformation Operation</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch3/>Chapter 3: More than Simple Transform Operations</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/Ch4/>Chapter 4: Matching Payload with Transform Operations</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/transform/ChH/>Chapter H: Reproducing Halide Schedule</a></li></ul></li><li><a href=https://mlir.llvm.org/docs/Tutorials/UnderstandingTheIRStructure/>Understanding the IR Structure</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/MlirOpt/>Using `mlir-opt`</a></li><li><a href=https://mlir.llvm.org/docs/Tutorials/DataFlowAnalysis/>Writing DataFlow Analyses in MLIR</a></li></ul></li></ul></li></ul></nav><div class=sidebar-footer></div></div></div><a href=# id=backtothetop-fixed class=backtothetop data-backtothetop-duration=600 data-backtothetop-easing=easeOutQuart data-backtothetop-fixed-fadein=1000 data-backtothetop-fixed-fadeout=1000 data-backtothetop-fixed-bottom=10 data-backtothetop-fixed-right=20><span class="fa-layers fa-fw"><i class="fas fa-circle"></i> <i class="fas fa-arrow-circle-up"></i></span></a></div></body></html>