xref: /llvm-project/mlir/docs/LangRef.md (revision 73fa6685c43ef61f5f5babb14f734097af6dc702)
155de49acSRiver Riddle# MLIR Language Reference
25b4a01d4SMehdi Amini
35b4a01d4SMehdi AminiMLIR (Multi-Level IR) is a compiler intermediate representation with
45b4a01d4SMehdi Aminisimilarities to traditional three-address SSA representations (like
55b4a01d4SMehdi Amini[LLVM IR](http://llvm.org/docs/LangRef.html) or
6c71fbdd8SQuinn Pham[SIL](https://github.com/apple/swift/blob/main/docs/SIL.rst)), but which
75b4a01d4SMehdi Aminiintroduces notions from polyhedral loop optimization as first-class concepts.
85b4a01d4SMehdi AminiThis hybrid design is optimized to represent, analyze, and transform high level
95b4a01d4SMehdi Aminidataflow graphs as well as target-specific code generated for high performance
105b4a01d4SMehdi Aminidata parallel systems. Beyond its representational capabilities, its single
115b4a01d4SMehdi Aminicontinuous design provides a framework to lower from dataflow graphs to
125b4a01d4SMehdi Aminihigh-performance target-specific code.
135b4a01d4SMehdi Amini
14a54f4eaeSMogballThis document defines and describes the key concepts in MLIR, and is intended to
15a54f4eaeSMogballbe a dry reference document - the
16a54f4eaeSMogball[rationale documentation](Rationale/Rationale.md),
1762828865SStephen Neuendorffer[glossary](../getting_started/Glossary.md), and other content are hosted
1862828865SStephen Neuendorfferelsewhere.
195b4a01d4SMehdi Amini
205b4a01d4SMehdi AminiMLIR is designed to be used in three different forms: a human-readable textual
215b4a01d4SMehdi Aminiform suitable for debugging, an in-memory form suitable for programmatic
22a54f4eaeSMogballtransformations and analysis, and a compact serialized form suitable for storage
23a54f4eaeSMogballand transport. The different forms all describe the same semantic content. This
24a54f4eaeSMogballdocument describes the human-readable textual form.
255b4a01d4SMehdi Amini
265b4a01d4SMehdi Amini[TOC]
275b4a01d4SMehdi Amini
285b4a01d4SMehdi Amini## High-Level Structure
295b4a01d4SMehdi Amini
3062828865SStephen NeuendorfferMLIR is fundamentally based on a graph-like data structure of nodes, called
3162828865SStephen Neuendorffer*Operations*, and edges, called *Values*. Each Value is the result of exactly
32a54f4eaeSMogballone Operation or Block Argument, and has a *Value Type* defined by the
33a54f4eaeSMogball[type system](#type-system). [Operations](#operations) are contained in
3462828865SStephen Neuendorffer[Blocks](#blocks) and Blocks are contained in [Regions](#regions). Operations
3562828865SStephen Neuendorfferare also ordered within their containing block and Blocks are ordered in their
36a54f4eaeSMogballcontaining region, although this order may or may not be semantically meaningful
37a54f4eaeSMogballin a given [kind of region](Interfaces.md/#regionkindinterfaces)). Operations
38a54f4eaeSMogballmay also contain regions, enabling hierarchical structures to be represented.
395b4a01d4SMehdi Amini
4062828865SStephen NeuendorfferOperations can represent many different concepts, from higher-level concepts
41a54f4eaeSMogballlike function definitions, function calls, buffer allocations, view or slices of
42a54f4eaeSMogballbuffers, and process creation, to lower-level concepts like target-independent
43a54f4eaeSMogballarithmetic, target-specific instructions, configuration registers, and logic
44a54f4eaeSMogballgates. These different concepts are represented by different operations in MLIR
45a54f4eaeSMogballand the set of operations usable in MLIR can be arbitrarily extended.
4662828865SStephen Neuendorffer
4762828865SStephen NeuendorfferMLIR also provides an extensible framework for transformations on operations,
4862828865SStephen Neuendorfferusing familiar concepts of compiler [Passes](Passes.md). Enabling an arbitrary
49a54f4eaeSMogballset of passes on an arbitrary set of operations results in a significant scaling
50a54f4eaeSMogballchallenge, since each transformation must potentially take into account the
51a54f4eaeSMogballsemantics of any operation. MLIR addresses this complexity by allowing operation
52a90a09faSmlevesquedionsemantics to be described abstractly using [Traits](Traits) and
53a54f4eaeSMogball[Interfaces](Interfaces.md), enabling transformations to operate on operations
54a54f4eaeSMogballmore generically. Traits often describe verification constraints on valid IR,
55a54f4eaeSMogballenabling complex invariants to be captured and checked. (see
56a54f4eaeSMogball[Op vs Operation](Tutorials/Toy/Ch-2.md/#op-vs-operation-using-mlir-operations))
5762828865SStephen Neuendorffer
5862828865SStephen NeuendorfferOne obvious application of MLIR is to represent an
5962828865SStephen Neuendorffer[SSA-based](https://en.wikipedia.org/wiki/Static_single_assignment_form) IR,
60caddfbd2SRiver Riddlelike the LLVM core IR, with appropriate choice of operation types to define
61caddfbd2SRiver RiddleModules, Functions, Branches, Memory Allocation, and verification constraints to
62caddfbd2SRiver Riddleensure the SSA Dominance property. MLIR includes a collection of dialects which
63caddfbd2SRiver Riddledefines just such structures. However, MLIR is intended to be general enough to
64caddfbd2SRiver Riddlerepresent other compiler-like data structures, such as Abstract Syntax Trees in
65caddfbd2SRiver Riddlea language frontend, generated instructions in a target-specific backend, or
66caddfbd2SRiver Riddlecircuits in a High-Level Synthesis tool.
675b4a01d4SMehdi Amini
685b4a01d4SMehdi AminiHere's an example of an MLIR module:
695b4a01d4SMehdi Amini
705b4a01d4SMehdi Amini```mlir
715b4a01d4SMehdi Amini// Compute A*B using an implementation of multiply kernel and print the
725b4a01d4SMehdi Amini// result using a TensorFlow op. The dimensions of A and B are partially
735b4a01d4SMehdi Amini// known. The shapes are assumed to match.
742310ced8SRiver Riddlefunc.func @mul(%A: tensor<100x?xf32>, %B: tensor<?x50xf32>) -> (tensor<100x50xf32>) {
755b4a01d4SMehdi Amini  // Compute the inner dimension of %A using the dim operation.
76a54f4eaeSMogball  %n = memref.dim %A, 1 : tensor<100x?xf32>
775b4a01d4SMehdi Amini
785b4a01d4SMehdi Amini  // Allocate addressable "buffers" and copy tensors %A and %B into them.
79a54f4eaeSMogball  %A_m = memref.alloc(%n) : memref<100x?xf32>
80437c6217SMatthias Springer  bufferization.materialize_in_destination %A in writable %A_m
81437c6217SMatthias Springer      : (tensor<100x?xf32>, memref<100x?xf32>) -> ()
825b4a01d4SMehdi Amini
83a54f4eaeSMogball  %B_m = memref.alloc(%n) : memref<?x50xf32>
84437c6217SMatthias Springer  bufferization.materialize_in_destination %B in writable %B_m
85437c6217SMatthias Springer      : (tensor<?x50xf32>, memref<?x50xf32>) -> ()
865b4a01d4SMehdi Amini
875b4a01d4SMehdi Amini  // Call function @multiply passing memrefs as arguments,
885b4a01d4SMehdi Amini  // and getting returned the result of the multiplication.
895b4a01d4SMehdi Amini  %C_m = call @multiply(%A_m, %B_m)
905b4a01d4SMehdi Amini          : (memref<100x?xf32>, memref<?x50xf32>) -> (memref<100x50xf32>)
915b4a01d4SMehdi Amini
92a54f4eaeSMogball  memref.dealloc %A_m : memref<100x?xf32>
93a54f4eaeSMogball  memref.dealloc %B_m : memref<?x50xf32>
945b4a01d4SMehdi Amini
955b4a01d4SMehdi Amini  // Load the buffer data into a higher level "tensor" value.
96a54f4eaeSMogball  %C = memref.tensor_load %C_m : memref<100x50xf32>
97a54f4eaeSMogball  memref.dealloc %C_m : memref<100x50xf32>
985b4a01d4SMehdi Amini
995b4a01d4SMehdi Amini  // Call TensorFlow built-in function to print the result tensor.
1009f39867bSRiver Riddle  "tf.Print"(%C){message: "mul result"} : (tensor<100x50xf32>) -> (tensor<100x50xf32>)
1015b4a01d4SMehdi Amini
1025b4a01d4SMehdi Amini  return %C : tensor<100x50xf32>
1035b4a01d4SMehdi Amini}
1045b4a01d4SMehdi Amini
1055b4a01d4SMehdi Amini// A function that multiplies two memrefs and returns the result.
1062310ced8SRiver Riddlefunc.func @multiply(%A: memref<100x?xf32>, %B: memref<?x50xf32>)
1075b4a01d4SMehdi Amini          -> (memref<100x50xf32>)  {
1085b4a01d4SMehdi Amini  // Compute the inner dimension of %A.
109a54f4eaeSMogball  %n = memref.dim %A, 1 : memref<100x?xf32>
1105b4a01d4SMehdi Amini
1115b4a01d4SMehdi Amini  // Allocate memory for the multiplication result.
112a54f4eaeSMogball  %C = memref.alloc() : memref<100x50xf32>
1135b4a01d4SMehdi Amini
1145b4a01d4SMehdi Amini  // Multiplication loop nest.
1155b4a01d4SMehdi Amini  affine.for %i = 0 to 100 {
1165b4a01d4SMehdi Amini     affine.for %j = 0 to 50 {
117a54f4eaeSMogball        memref.store 0 to %C[%i, %j] : memref<100x50xf32>
1185b4a01d4SMehdi Amini        affine.for %k = 0 to %n {
119a54f4eaeSMogball           %a_v  = memref.load %A[%i, %k] : memref<100x?xf32>
120a54f4eaeSMogball           %b_v  = memref.load %B[%k, %j] : memref<?x50xf32>
121a54f4eaeSMogball           %prod = arith.mulf %a_v, %b_v : f32
122a54f4eaeSMogball           %c_v  = memref.load %C[%i, %j] : memref<100x50xf32>
123a54f4eaeSMogball           %sum  = arith.addf %c_v, %prod : f32
124a54f4eaeSMogball           memref.store %sum, %C[%i, %j] : memref<100x50xf32>
1255b4a01d4SMehdi Amini        }
1265b4a01d4SMehdi Amini     }
1275b4a01d4SMehdi Amini  }
1285b4a01d4SMehdi Amini  return %C : memref<100x50xf32>
1295b4a01d4SMehdi Amini}
1305b4a01d4SMehdi Amini```
1315b4a01d4SMehdi Amini
1325b4a01d4SMehdi Amini## Notation
1335b4a01d4SMehdi Amini
1345b4a01d4SMehdi AminiMLIR has a simple and unambiguous grammar, allowing it to reliably round-trip
135a54f4eaeSMogballthrough a textual form. This is important for development of the compiler - e.g.
136a54f4eaeSMogballfor understanding the state of code as it is being transformed and writing test
137a54f4eaeSMogballcases.
1385b4a01d4SMehdi Amini
1395b4a01d4SMehdi AminiThis document describes the grammar using
1405b4a01d4SMehdi Amini[Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form).
1415b4a01d4SMehdi Amini
1425b4a01d4SMehdi AminiThis is the EBNF grammar used in this document, presented in yellow boxes.
1435b4a01d4SMehdi Amini
1445b4a01d4SMehdi Amini```
1455b4a01d4SMehdi Aminialternation ::= expr0 | expr1 | expr2  // Either expr0 or expr1 or expr2.
1465b4a01d4SMehdi Aminisequence    ::= expr0 expr1 expr2      // Sequence of expr0 expr1 expr2.
1475b4a01d4SMehdi Aminirepetition0 ::= expr*  // 0 or more occurrences.
1485b4a01d4SMehdi Aminirepetition1 ::= expr+  // 1 or more occurrences.
1495b4a01d4SMehdi Aminioptionality ::= expr?  // 0 or 1 occurrence.
1505b4a01d4SMehdi Aminigrouping    ::= (expr) // Everything inside parens is grouped together.
1515b4a01d4SMehdi Aminiliteral     ::= `abcd` // Matches the literal `abcd`.
1525b4a01d4SMehdi Amini```
1535b4a01d4SMehdi Amini
1545b4a01d4SMehdi AminiCode examples are presented in blue boxes.
1555b4a01d4SMehdi Amini
1569f39867bSRiver Riddle```
1575b4a01d4SMehdi Amini// This is an example use of the grammar above:
1585b4a01d4SMehdi Amini// This matches things like: ba, bana, boma, banana, banoma, bomana...
1595b4a01d4SMehdi Aminiexample ::= `b` (`an` | `om`)* `a`
1605b4a01d4SMehdi Amini```
1615b4a01d4SMehdi Amini
1625b4a01d4SMehdi Amini### Common syntax
1635b4a01d4SMehdi Amini
1645b4a01d4SMehdi AminiThe following core grammar productions are used in this document:
1655b4a01d4SMehdi Amini
1665b4a01d4SMehdi Amini```
1675b4a01d4SMehdi Amini// TODO: Clarify the split between lexing (tokens) and parsing (grammar).
1685b4a01d4SMehdi Aminidigit     ::= [0-9]
1695b4a01d4SMehdi Aminihex_digit ::= [0-9a-fA-F]
1705b4a01d4SMehdi Aminiletter    ::= [a-zA-Z]
1715b4a01d4SMehdi Aminiid-punct  ::= [$._-]
1725b4a01d4SMehdi Amini
1735b4a01d4SMehdi Aminiinteger-literal ::= decimal-literal | hexadecimal-literal
1745b4a01d4SMehdi Aminidecimal-literal ::= digit+
1755b4a01d4SMehdi Aminihexadecimal-literal ::= `0x` hex_digit+
1765b4a01d4SMehdi Aminifloat-literal ::= [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
1779db53a18SRiver Riddlestring-literal  ::= `"` [^"\n\f\v\r]* `"`   TODO: define escaping rules
1785b4a01d4SMehdi Amini```
1795b4a01d4SMehdi Amini
1805b4a01d4SMehdi AminiNot listed here, but MLIR does support comments. They use standard BCPL syntax,
1815b4a01d4SMehdi Aministarting with a `//` and going until the end of the line.
1825b4a01d4SMehdi Amini
183357f2d9cSSiddharth Bhat
184357f2d9cSSiddharth Bhat### Top level Productions
185357f2d9cSSiddharth Bhat
186357f2d9cSSiddharth Bhat```
187357f2d9cSSiddharth Bhat// Top level production
188357f2d9cSSiddharth Bhattoplevel := (operation | attribute-alias-def | type-alias-def)*
189357f2d9cSSiddharth Bhat```
190357f2d9cSSiddharth Bhat
191357f2d9cSSiddharth BhatThe production `toplevel` is the top level production that is parsed by any parsing
192357f2d9cSSiddharth Bhatconsuming the MLIR syntax. [Operations](#operations),
19369bc8c9eSManas[Attribute aliases](#attribute-value-aliases), and [Type aliases](#type-aliases)
194357f2d9cSSiddharth Bhatcan be declared on the toplevel.
195357f2d9cSSiddharth Bhat
1965b4a01d4SMehdi Amini### Identifiers and keywords
1975b4a01d4SMehdi Amini
1985b4a01d4SMehdi AminiSyntax:
1995b4a01d4SMehdi Amini
2005b4a01d4SMehdi Amini```
2015b4a01d4SMehdi Amini// Identifiers
2025b4a01d4SMehdi Aminibare-id ::= (letter|[_]) (letter|digit|[_$.])*
2035b4a01d4SMehdi Aminibare-id-list ::= bare-id (`,` bare-id)*
20462828865SStephen Neuendorffervalue-id ::= `%` suffix-id
2059a4472c5SJacques Pienaaralias-name :: = bare-id
2065b4a01d4SMehdi Aminisuffix-id ::= (digit+ | ((letter|id-punct) (letter|id-punct|digit)*))
2075b4a01d4SMehdi Amini
20896039b73SSiddharth Bhatsymbol-ref-id ::= `@` (suffix-id | string-literal) (`::` symbol-ref-id)?
20962828865SStephen Neuendorffervalue-id-list ::= value-id (`,` value-id)*
2105b4a01d4SMehdi Amini
21162828865SStephen Neuendorffer// Uses of value, e.g. in an operand list to an operation.
212f04cf6b7SStevengrevalue-use ::= value-id (`#` decimal-literal)?
21362828865SStephen Neuendorffervalue-use-list ::= value-use (`,` value-use)*
2145b4a01d4SMehdi Amini```
2155b4a01d4SMehdi Amini
216a54f4eaeSMogballIdentifiers name entities such as values, types and functions, and are chosen by
217a54f4eaeSMogballthe writer of MLIR code. Identifiers may be descriptive (e.g. `%batch_size`,
218a54f4eaeSMogball`@matmul`), or may be non-descriptive when they are auto-generated (e.g. `%23`,
219a54f4eaeSMogball`@func42`). Identifier names for values may be used in an MLIR text file but are
220a54f4eaeSMogballnot persisted as part of the IR - the printer will give them anonymous names
221a54f4eaeSMogballlike `%42`.
2225b4a01d4SMehdi Amini
2235b4a01d4SMehdi AminiMLIR guarantees identifiers never collide with keywords by prefixing identifiers
2245b4a01d4SMehdi Aminiwith a sigil (e.g. `%`, `#`, `@`, `^`, `!`). In certain unambiguous contexts
2255b4a01d4SMehdi Amini(e.g. affine expressions), identifiers are not prefixed, for brevity. New
2265b4a01d4SMehdi Aminikeywords may be added to future versions of MLIR without danger of collision
2275b4a01d4SMehdi Aminiwith existing identifiers.
2285b4a01d4SMehdi Amini
229a54f4eaeSMogballValue identifiers are only [in scope](#value-scoping) for the (nested) region in
230a54f4eaeSMogballwhich they are defined and cannot be accessed or referenced outside of that
231a54f4eaeSMogballregion. Argument identifiers in mapping functions are in scope for the mapping
232a54f4eaeSMogballbody. Particular operations may further limit which identifiers are in scope in
233a54f4eaeSMogballtheir regions. For instance, the scope of values in a region with
234a54f4eaeSMogball[SSA control flow semantics](#control-flow-and-ssacfg-regions) is constrained
235a54f4eaeSMogballaccording to the standard definition of
236a54f4eaeSMogball[SSA dominance](https://en.wikipedia.org/wiki/Dominator_\(graph_theory\)).
237a90a09faSmlevesquedionAnother example is the [IsolatedFromAbove trait](Traits/#isolatedfromabove),
238a54f4eaeSMogballwhich restricts directly accessing values defined in containing regions.
23962828865SStephen Neuendorffer
24062828865SStephen NeuendorfferFunction identifiers and mapping identifiers are associated with
241a54f4eaeSMogball[Symbols](SymbolsAndSymbolTables.md) and have scoping rules dependent on symbol
242a54f4eaeSMogballattributes.
2435b4a01d4SMehdi Amini
2445b4a01d4SMehdi Amini## Dialects
2455b4a01d4SMehdi Amini
2465b4a01d4SMehdi AminiDialects are the mechanism by which to engage with and extend the MLIR
2475b4a01d4SMehdi Aminiecosystem. They allow for defining new [operations](#operations), as well as
2485b4a01d4SMehdi Amini[attributes](#attributes) and [types](#type-system). Each dialect is given a
2495b4a01d4SMehdi Aminiunique `namespace` that is prefixed to each defined attribute/operation/type.
2505b4a01d4SMehdi AminiFor example, the [Affine dialect](Dialects/Affine.md) defines the namespace:
2515b4a01d4SMehdi Amini`affine`.
2525b4a01d4SMehdi Amini
2535b4a01d4SMehdi AminiMLIR allows for multiple dialects, even those outside of the main tree, to
2545b4a01d4SMehdi Aminico-exist together within one module. Dialects are produced and consumed by
2555b4a01d4SMehdi Aminicertain passes. MLIR provides a [framework](DialectConversion.md) to convert
2565b4a01d4SMehdi Aminibetween, and within, different dialects.
2575b4a01d4SMehdi Amini
2585b4a01d4SMehdi AminiA few of the dialects supported by MLIR:
2595b4a01d4SMehdi Amini
2605b4a01d4SMehdi Amini*   [Affine dialect](Dialects/Affine.md)
26123aa5a74SRiver Riddle*   [Func dialect](Dialects/Func.md)
2625b4a01d4SMehdi Amini*   [GPU dialect](Dialects/GPU.md)
2635b4a01d4SMehdi Amini*   [LLVM dialect](Dialects/LLVM.md)
2645b4a01d4SMehdi Amini*   [SPIR-V dialect](Dialects/SPIR-V.md)
2655b4a01d4SMehdi Amini*   [Vector dialect](Dialects/Vector.md)
2665b4a01d4SMehdi Amini
2675b4a01d4SMehdi Amini### Target specific operations
2685b4a01d4SMehdi Amini
2695b4a01d4SMehdi AminiDialects provide a modular way in which targets can expose target-specific
2705b4a01d4SMehdi Aminioperations directly through to MLIR. As an example, some targets go through
2715b4a01d4SMehdi AminiLLVM. LLVM has a rich set of intrinsics for certain target-independent
2725b4a01d4SMehdi Aminioperations (e.g. addition with overflow check) as well as providing access to
273a54f4eaeSMogballtarget-specific operations for the targets it supports (e.g. vector permutation
274a54f4eaeSMogballoperations). LLVM intrinsics in MLIR are represented via operations that start
275a54f4eaeSMogballwith an "llvm." name.
2765b4a01d4SMehdi Amini
2775b4a01d4SMehdi AminiExample:
2785b4a01d4SMehdi Amini
2795b4a01d4SMehdi Amini```mlir
2805b4a01d4SMehdi Amini// LLVM: %x = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %a, i16 %b)
2815b4a01d4SMehdi Amini%x:2 = "llvm.sadd.with.overflow.i16"(%a, %b) : (i16, i16) -> (i16, i1)
2825b4a01d4SMehdi Amini```
2835b4a01d4SMehdi Amini
2845b4a01d4SMehdi AminiThese operations only work when targeting LLVM as a backend (e.g. for CPUs and
2855b4a01d4SMehdi AminiGPUs), and are required to align with the LLVM definition of these intrinsics.
2865b4a01d4SMehdi Amini
2875b4a01d4SMehdi Amini## Operations
2885b4a01d4SMehdi Amini
2895b4a01d4SMehdi AminiSyntax:
2905b4a01d4SMehdi Amini
2915b4a01d4SMehdi Amini```
2925b4a01d4SMehdi Aminioperation             ::= op-result-list? (generic-operation | custom-operation)
2935b4a01d4SMehdi Amini                          trailing-location?
29462828865SStephen Neuendorffergeneric-operation     ::= string-literal `(` value-use-list? `)`  successor-list?
2955e118f93SMehdi Amini                          dictionary-properties? region-list? dictionary-attribute?
2965e118f93SMehdi Amini                          `:` function-type
2975b4a01d4SMehdi Aminicustom-operation      ::= bare-id custom-operation-format
2985b4a01d4SMehdi Aminiop-result-list        ::= op-result (`,` op-result)* `=`
299f04cf6b7SStevengreop-result             ::= value-id (`:` integer-literal)?
30022411d80SGeoffrey Martin-Noblesuccessor-list        ::= `[` successor (`,` successor)* `]`
3019a4472c5SJacques Pienaarsuccessor             ::= caret-id (`:` block-arg-list)?
302a33ba2b5SYan Xindictionary-properties ::= `<` dictionary-attribute `>`
30322411d80SGeoffrey Martin-Nobleregion-list           ::= `(` region (`,` region)* `)`
30422411d80SGeoffrey Martin-Nobledictionary-attribute  ::= `{` (attribute-entry (`,` attribute-entry)*)? `}`
305f04cf6b7SStevengretrailing-location     ::= `loc` `(` location `)`
3065b4a01d4SMehdi Amini```
3075b4a01d4SMehdi Amini
308a54f4eaeSMogballMLIR introduces a uniform concept called *operations* to enable describing many
309a54f4eaeSMogballdifferent levels of abstractions and computations. Operations in MLIR are fully
310a54f4eaeSMogballextensible (there is no fixed list of operations) and have application-specific
311a54f4eaeSMogballsemantics. For example, MLIR supports
312026fe5ffSRiver Riddle[target-independent operations](Dialects/MemRef.md),
313a54f4eaeSMogball[affine operations](Dialects/Affine.md), and
314a54f4eaeSMogball[target-specific machine operations](#target-specific-operations).
3155b4a01d4SMehdi Amini
3165b4a01d4SMehdi AminiThe internal representation of an operation is simple: an operation is
3175b4a01d4SMehdi Aminiidentified by a unique string (e.g. `dim`, `tf.Conv2d`, `x86.repmovsb`,
318a54f4eaeSMogball`ppc.eieio`, etc), can return zero or more results, take zero or more operands,
3195e118f93SMehdi Aminihas storage for [properties](#properties), has a dictionary of
3205e118f93SMehdi Amini[attributes](#attributes), has zero or more successors, and zero or more
3215e118f93SMehdi Aminienclosed [regions](#regions). The generic printing form includes all these
3225e118f93SMehdi Aminielements literally, with a function type to indicate the types of the
323a54f4eaeSMogballresults and operands.
3245b4a01d4SMehdi Amini
3255b4a01d4SMehdi AminiExample:
3265b4a01d4SMehdi Amini
3275b4a01d4SMehdi Amini```mlir
3285b4a01d4SMehdi Amini// An operation that produces two results.
3295b4a01d4SMehdi Amini// The results of %result can be accessed via the <name> `#` <opNo> syntax.
3305b4a01d4SMehdi Amini%result:2 = "foo_div"() : () -> (f32, i32)
3315b4a01d4SMehdi Amini
3325b4a01d4SMehdi Amini// Pretty form that defines a unique name for each result.
3335b4a01d4SMehdi Amini%foo, %bar = "foo_div"() : () -> (f32, i32)
3345b4a01d4SMehdi Amini
3355b4a01d4SMehdi Amini// Invoke a TensorFlow function called tf.scramble with two inputs
3365e118f93SMehdi Amini// and an attribute "fruit" stored in properties.
3375e118f93SMehdi Amini%2 = "tf.scramble"(%result#0, %bar) <{fruit = "banana"}> : (f32, i32) -> f32
3385e118f93SMehdi Amini
3395e118f93SMehdi Amini// Invoke an operation with some discardable attributes
3405e118f93SMehdi Amini%foo, %bar = "foo_div"() {some_attr = "value", other_attr = 42 : i64} : () -> (f32, i32)
3415b4a01d4SMehdi Amini```
3425b4a01d4SMehdi Amini
3435b4a01d4SMehdi AminiIn addition to the basic syntax above, dialects may register known operations.
344a54f4eaeSMogballThis allows those dialects to support *custom assembly form* for parsing and
3455b4a01d4SMehdi Aminiprinting operations. In the operation sets listed below, we show both forms.
3465b4a01d4SMehdi Amini
347caddfbd2SRiver Riddle### Builtin Operations
3485b4a01d4SMehdi Amini
349caddfbd2SRiver RiddleThe [builtin dialect](Dialects/Builtin.md) defines a select few operations that
350caddfbd2SRiver Riddleare widely applicable by MLIR dialects, such as a universal conversion cast
351caddfbd2SRiver Riddleoperation that simplifies inter/intra dialect conversion. This dialect also
352caddfbd2SRiver Riddledefines a top-level `module` operation, that represents a useful IR container.
3535b4a01d4SMehdi Amini
3545b4a01d4SMehdi Amini## Blocks
3555b4a01d4SMehdi Amini
3565b4a01d4SMehdi AminiSyntax:
3575b4a01d4SMehdi Amini
3585b4a01d4SMehdi Amini```
3595b4a01d4SMehdi Aminiblock           ::= block-label operation+
3605b4a01d4SMehdi Aminiblock-label     ::= block-id block-arg-list? `:`
3615b4a01d4SMehdi Aminiblock-id        ::= caret-id
3625b4a01d4SMehdi Aminicaret-id        ::= `^` suffix-id
36362828865SStephen Neuendorffervalue-id-and-type ::= value-id `:` type
3645b4a01d4SMehdi Amini
3655b4a01d4SMehdi Amini// Non-empty list of names and types.
36662828865SStephen Neuendorffervalue-id-and-type-list ::= value-id-and-type (`,` value-id-and-type)*
3675b4a01d4SMehdi Amini
36862828865SStephen Neuendorfferblock-arg-list ::= `(` value-id-and-type-list? `)`
3695b4a01d4SMehdi Amini```
3705b4a01d4SMehdi Amini
371a54f4eaeSMogballA *Block* is a list of operations. In
372a54f4eaeSMogball[SSACFG regions](#control-flow-and-ssacfg-regions), each block represents a
373a54f4eaeSMogballcompiler [basic block](https://en.wikipedia.org/wiki/Basic_block) where
374a54f4eaeSMogballinstructions inside the block are executed in order and terminator operations
375a54f4eaeSMogballimplement control flow branches between basic blocks.
3765b4a01d4SMehdi Amini
377b968c590SMehdi AminiThe last operation in a block must be a
378b968c590SMehdi Amini[terminator operation](#control-flow-and-ssacfg-regions). A region with a single
379b968c590SMehdi Aminiblock may opt out of this requirement by attaching the `NoTerminator` on the
380b968c590SMehdi Aminienclosing op. The top-level `ModuleOp` is an example of such an operation which
381b968c590SMehdi Aminidefines this trait and whose block body does not have a terminator.
382973ddb7dSMehdi Amini
383a54f4eaeSMogballBlocks in MLIR take a list of block arguments, notated in a function-like way.
384a54f4eaeSMogballBlock arguments are bound to values specified by the semantics of individual
385a54f4eaeSMogballoperations. Block arguments of the entry block of a region are also arguments to
386a54f4eaeSMogballthe region and the values bound to these arguments are determined by the
387a54f4eaeSMogballsemantics of the containing operation. Block arguments of other blocks are
388a54f4eaeSMogballdetermined by the semantics of terminator operations, e.g. Branches, which have
389a54f4eaeSMogballthe block as a successor. In regions with
390a54f4eaeSMogball[control flow](#control-flow-and-ssacfg-regions), MLIR leverages this structure
391a54f4eaeSMogballto implicitly represent the passage of control-flow dependent values without the
39262828865SStephen Neuendorffercomplex nuances of PHI nodes in traditional SSA representations. Note that
39362828865SStephen Neuendorffervalues which are not control-flow dependent can be referenced directly and do
39462828865SStephen Neuendorffernot need to be passed through block arguments.
3955b4a01d4SMehdi Amini
3965b4a01d4SMehdi AminiHere is a simple example function showing branches, returns, and block
3975b4a01d4SMehdi Aminiarguments:
3985b4a01d4SMehdi Amini
3995b4a01d4SMehdi Amini```mlir
4002310ced8SRiver Riddlefunc.func @simple(i64, i1) -> i64 {
4015b4a01d4SMehdi Amini^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a
402ace01605SRiver Riddle  cf.cond_br %cond, ^bb1, ^bb2
4035b4a01d4SMehdi Amini
4045b4a01d4SMehdi Amini^bb1:
405ace01605SRiver Riddle  cf.br ^bb3(%a: i64)    // Branch passes %a as the argument
4065b4a01d4SMehdi Amini
4075b4a01d4SMehdi Amini^bb2:
408a54f4eaeSMogball  %b = arith.addi %a, %a : i64
409ace01605SRiver Riddle  cf.br ^bb3(%b: i64)    // Branch passes %b as the argument
4105b4a01d4SMehdi Amini
4115b4a01d4SMehdi Amini// ^bb3 receives an argument, named %c, from predecessors
41262828865SStephen Neuendorffer// and passes it on to bb4 along with %a. %a is referenced
41362828865SStephen Neuendorffer// directly from its defining operation and is not passed through
41462828865SStephen Neuendorffer// an argument of ^bb3.
4155b4a01d4SMehdi Amini^bb3(%c: i64):
416ace01605SRiver Riddle  cf.br ^bb4(%c, %a : i64, i64)
4175b4a01d4SMehdi Amini
4185b4a01d4SMehdi Amini^bb4(%d : i64, %e : i64):
419a54f4eaeSMogball  %0 = arith.addi %d, %e : i64
42062828865SStephen Neuendorffer  return %0 : i64   // Return is also a terminator.
4215b4a01d4SMehdi Amini}
4225b4a01d4SMehdi Amini```
4235b4a01d4SMehdi Amini
424a54f4eaeSMogball**Context:** The "block argument" representation eliminates a number of special
425a54f4eaeSMogballcases from the IR compared to traditional "PHI nodes are operations" SSA IRs
426a54f4eaeSMogball(like LLVM). For example, the
427a54f4eaeSMogball[parallel copy semantics](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.524.5461&rep=rep1&type=pdf)
428a54f4eaeSMogballof SSA is immediately apparent, and function arguments are no longer a special
429a54f4eaeSMogballcase: they become arguments to the entry block
430a54f4eaeSMogball[[more rationale](Rationale/Rationale.md/#block-arguments-vs-phi-nodes)]. Blocks
431a54f4eaeSMogballare also a fundamental concept that cannot be represented by operations because
432a54f4eaeSMogballvalues defined in an operation cannot be accessed outside the operation.
4335b4a01d4SMehdi Amini
4345b4a01d4SMehdi Amini## Regions
4355b4a01d4SMehdi Amini
4365b4a01d4SMehdi Amini### Definition
4375b4a01d4SMehdi Amini
43862828865SStephen NeuendorfferA region is an ordered list of MLIR [Blocks](#blocks). The semantics within a
43962828865SStephen Neuendorfferregion is not imposed by the IR. Instead, the containing operation defines the
44062828865SStephen Neuendorffersemantics of the regions it contains. MLIR currently defines two kinds of
44162828865SStephen Neuendorfferregions: [SSACFG regions](#control-flow-and-ssacfg-regions), which describe
44262828865SStephen Neuendorffercontrol flow between blocks, and [Graph regions](#graph-regions), which do not
443a54f4eaeSMogballrequire control flow between block. The kinds of regions within an operation are
444a54f4eaeSMogballdescribed using the [RegionKindInterface](Interfaces.md/#regionkindinterfaces).
4455b4a01d4SMehdi Amini
446a54f4eaeSMogballRegions do not have a name or an address, only the blocks contained in a region
447a54f4eaeSMogballdo. Regions must be contained within operations and have no type or attributes.
448a54f4eaeSMogballThe first block in the region is a special block called the 'entry block'. The
449a54f4eaeSMogballarguments to the entry block are also the arguments of the region itself. The
450a54f4eaeSMogballentry block cannot be listed as a successor of any other block. The syntax for a
451a54f4eaeSMogballregion is as follows:
4525b4a01d4SMehdi Amini
4535b4a01d4SMehdi Amini```
45424a37a39SSiddharth Bhatregion      ::= `{` entry-block? block* `}`
45524a37a39SSiddharth Bhatentry-block ::= operation+
4565b4a01d4SMehdi Amini```
4575b4a01d4SMehdi Amini
45862828865SStephen NeuendorfferA function body is an example of a region: it consists of a CFG of blocks and
45962828865SStephen Neuendorfferhas additional semantic restrictions that other types of regions may not have.
46062828865SStephen NeuendorfferFor example, in a function body, block terminators must either branch to a
46162828865SStephen Neuendorfferdifferent block, or return from a function where the types of the `return`
462a54f4eaeSMogballarguments must match the result types of the function signature. Similarly, the
463a54f4eaeSMogballfunction arguments must match the types and count of the region arguments. In
464286a7a40SMarkus Böckgeneral, operations with regions can define these correspondences arbitrarily.
4655b4a01d4SMehdi Amini
46624a37a39SSiddharth BhatAn *entry block* is a block with no label and no arguments that may occur at
46724a37a39SSiddharth Bhatthe beginning of a region. It enables a common pattern of using a region to
46824a37a39SSiddharth Bhatopen a new scope.
46924a37a39SSiddharth Bhat
47024a37a39SSiddharth Bhat
47162828865SStephen Neuendorffer### Value Scoping
4725b4a01d4SMehdi Amini
47362828865SStephen NeuendorfferRegions provide hierarchical encapsulation of programs: it is impossible to
474a54f4eaeSMogballreference, i.e. branch to, a block which is not in the same region as the source
475a54f4eaeSMogballof the reference, i.e. a terminator operation. Similarly, regions provides a
476a54f4eaeSMogballnatural scoping for value visibility: values defined in a region don't escape to
477a54f4eaeSMogballthe enclosing region, if any. By default, operations inside a region can
478a54f4eaeSMogballreference values defined outside of the region whenever it would have been legal
479a54f4eaeSMogballfor operands of the enclosing operation to reference those values, but this can
480a54f4eaeSMogballbe restricted using traits, such as
481a90a09faSmlevesquedion[OpTrait::IsolatedFromAbove](Traits/#isolatedfromabove), or a custom
48262828865SStephen Neuendorfferverifier.
4835b4a01d4SMehdi Amini
4845b4a01d4SMehdi AminiExample:
4855b4a01d4SMehdi Amini
4865b4a01d4SMehdi Amini```mlir
48762828865SStephen Neuendorffer  "any_op"(%a) ({ // if %a is in-scope in the containing region...
48862828865SStephen Neuendorffer     // then %a is in-scope here too.
48962828865SStephen Neuendorffer    %new_value = "another_op"(%a) : (i64) -> (i64)
49062828865SStephen Neuendorffer  }) : (i64) -> (i64)
49162828865SStephen Neuendorffer```
49262828865SStephen Neuendorffer
493a54f4eaeSMogballMLIR defines a generalized 'hierarchical dominance' concept that operates across
494a54f4eaeSMogballhierarchy and defines whether a value is 'in scope' and can be used by a
495a54f4eaeSMogballparticular operation. Whether a value can be used by another operation in the
496a54f4eaeSMogballsame region is defined by the kind of region. A value defined in a region can be
497a54f4eaeSMogballused by an operation which has a parent in the same region, if and only if the
498a54f4eaeSMogballparent could use the value. A value defined by an argument to a region can
499a54f4eaeSMogballalways be used by any operation deeply contained in the region. A value defined
500a54f4eaeSMogballin a region can never be used outside of the region.
50162828865SStephen Neuendorffer
50262828865SStephen Neuendorffer### Control Flow and SSACFG Regions
50362828865SStephen Neuendorffer
50462828865SStephen NeuendorfferIn MLIR, control flow semantics of a region is indicated by
505d35bd986SMarkus Böck[RegionKind::SSACFG](Interfaces.md/#regionkindinterfaces). Informally, these
506a54f4eaeSMogballregions support semantics where operations in a region 'execute sequentially'.
507a54f4eaeSMogballBefore an operation executes, its operands have well-defined values. After an
508a54f4eaeSMogballoperation executes, the operands have the same values and results also have
509a54f4eaeSMogballwell-defined values. After an operation executes, the next operation in the
510a54f4eaeSMogballblock executes until the operation is the terminator operation at the end of a
511a54f4eaeSMogballblock, in which case some other operation will execute. The determination of the
512a54f4eaeSMogballnext instruction to execute is the 'passing of control flow'.
51362828865SStephen Neuendorffer
514a54f4eaeSMogballIn general, when control flow is passed to an operation, MLIR does not restrict
515a54f4eaeSMogballwhen control flow enters or exits the regions contained in that operation.
516a54f4eaeSMogballHowever, when control flow enters a region, it always begins in the first block
517a54f4eaeSMogballof the region, called the *entry* block. Terminator operations ending each block
518a54f4eaeSMogballrepresent control flow by explicitly specifying the successor blocks of the
519a54f4eaeSMogballblock. Control flow can only pass to one of the specified successor blocks as in
520a54f4eaeSMogballa `branch` operation, or back to the containing operation as in a `return`
521a54f4eaeSMogballoperation. Terminator operations without successors can only pass control back
522a54f4eaeSMogballto the containing operation. Within these restrictions, the particular semantics
523a54f4eaeSMogballof terminator operations is determined by the specific dialect operations
524a54f4eaeSMogballinvolved. Blocks (other than the entry block) that are not listed as a successor
525a54f4eaeSMogballof a terminator operation are defined to be unreachable and can be removed
526a54f4eaeSMogballwithout affecting the semantics of the containing operation.
52762828865SStephen Neuendorffer
52862828865SStephen NeuendorfferAlthough control flow always enters a region through the entry block, control
52962828865SStephen Neuendorfferflow may exit a region through any block with an appropriate terminator. The
53062828865SStephen Neuendorfferstandard dialect leverages this capability to define operations with
53162828865SStephen NeuendorfferSingle-Entry-Multiple-Exit (SEME) regions, possibly flowing through different
532a54f4eaeSMogballblocks in the region and exiting through any block with a `return` operation.
533a54f4eaeSMogballThis behavior is similar to that of a function body in most programming
534a54f4eaeSMogballlanguages. In addition, control flow may also not reach the end of a block or
535a54f4eaeSMogballregion, for example if a function call does not return.
53662828865SStephen Neuendorffer
53762828865SStephen NeuendorfferExample:
53862828865SStephen Neuendorffer
53962828865SStephen Neuendorffer```mlir
5402310ced8SRiver Riddlefunc.func @accelerator_compute(i64, i1) -> i64 { // An SSACFG region
5415b4a01d4SMehdi Amini^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a
542ace01605SRiver Riddle  cf.cond_br %cond, ^bb1, ^bb2
5435b4a01d4SMehdi Amini
5445b4a01d4SMehdi Amini^bb1:
5455b4a01d4SMehdi Amini  // This def for %value does not dominate ^bb2
5465b4a01d4SMehdi Amini  %value = "op.convert"(%a) : (i64) -> i64
547ace01605SRiver Riddle  cf.br ^bb3(%a: i64)    // Branch passes %a as the argument
5485b4a01d4SMehdi Amini
5495b4a01d4SMehdi Amini^bb2:
55062828865SStephen Neuendorffer  accelerator.launch() { // An SSACFG region
5515b4a01d4SMehdi Amini    ^bb0:
5525b4a01d4SMehdi Amini      // Region of code nested under "accelerator.launch", it can reference %a but
5535b4a01d4SMehdi Amini      // not %value.
5545b4a01d4SMehdi Amini      %new_value = "accelerator.do_something"(%a) : (i64) -> ()
5555b4a01d4SMehdi Amini  }
5565b4a01d4SMehdi Amini  // %new_value cannot be referenced outside of the region
5575b4a01d4SMehdi Amini
5585b4a01d4SMehdi Amini^bb3:
5595b4a01d4SMehdi Amini  ...
5605b4a01d4SMehdi Amini}
5615b4a01d4SMehdi Amini```
5625b4a01d4SMehdi Amini
56362828865SStephen Neuendorffer#### Operations with Multiple Regions
5645b4a01d4SMehdi Amini
56562828865SStephen NeuendorfferAn operation containing multiple regions also completely determines the
56662828865SStephen Neuendorffersemantics of those regions. In particular, when control flow is passed to an
56762828865SStephen Neuendorfferoperation, it may transfer control flow to any contained region. When control
568a54f4eaeSMogballflow exits a region and is returned to the containing operation, the containing
569a54f4eaeSMogballoperation may pass control flow to any region in the same operation. An
570a54f4eaeSMogballoperation may also pass control flow to multiple contained regions concurrently.
571a54f4eaeSMogballAn operation may also pass control flow into regions that were specified in
572a54f4eaeSMogballother operations, in particular those that defined the values or symbols the
573a54f4eaeSMogballgiven operation uses as in a call operation. This passage of control is
574a54f4eaeSMogballgenerally independent of passage of control flow through the basic blocks of the
575a54f4eaeSMogballcontaining region.
5765b4a01d4SMehdi Amini
5775b4a01d4SMehdi Amini#### Closure
5785b4a01d4SMehdi Amini
5795b4a01d4SMehdi AminiRegions allow defining an operation that creates a closure, for example by
5805b4a01d4SMehdi Amini“boxing” the body of the region into a value they produce. It remains up to the
5815b4a01d4SMehdi Aminioperation to define its semantics. Note that if an operation triggers
5825b4a01d4SMehdi Aminiasynchronous execution of the region, it is under the responsibility of the
5835b4a01d4SMehdi Aminioperation caller to wait for the region to be executed guaranteeing that any
5845b4a01d4SMehdi Aminidirectly used values remain live.
5855b4a01d4SMehdi Amini
58662828865SStephen Neuendorffer### Graph Regions
58762828865SStephen Neuendorffer
58862828865SStephen NeuendorfferIn MLIR, graph-like semantics in a region is indicated by
589d35bd986SMarkus Böck[RegionKind::Graph](Interfaces.md/#regionkindinterfaces). Graph regions are
59062828865SStephen Neuendorfferappropriate for concurrent semantics without control flow, or for modeling
59162828865SStephen Neuendorffergeneric directed graph data structures. Graph regions are appropriate for
59262828865SStephen Neuendorfferrepresenting cyclic relationships between coupled values where there is no
59362828865SStephen Neuendorfferfundamental order to the relationships. For instance, operations in a graph
59462828865SStephen Neuendorfferregion may represent independent threads of control with values representing
59562828865SStephen Neuendorfferstreams of data. As usual in MLIR, the particular semantics of a region is
59662828865SStephen Neuendorffercompletely determined by its containing operation. Graph regions may only
59762828865SStephen Neuendorffercontain a single basic block (the entry block).
59862828865SStephen Neuendorffer
599a54f4eaeSMogball**Rationale:** Currently graph regions are arbitrarily limited to a single basic
600a54f4eaeSMogballblock, although there is no particular semantic reason for this limitation. This
601a54f4eaeSMogballlimitation has been added to make it easier to stabilize the pass infrastructure
602a54f4eaeSMogballand commonly used passes for processing graph regions to properly handle
603a54f4eaeSMogballfeedback loops. Multi-block regions may be allowed in the future if use cases
604a54f4eaeSMogballthat require it arise.
60562828865SStephen Neuendorffer
60662828865SStephen NeuendorfferIn graph regions, MLIR operations naturally represent nodes, while each MLIR
60762828865SStephen Neuendorffervalue represents a multi-edge connecting a single source node and multiple
608a54f4eaeSMogballdestination nodes. All values defined in the region as results of operations are
609a54f4eaeSMogballin scope within the region and can be accessed by any other operation in the
610a54f4eaeSMogballregion. In graph regions, the order of operations within a block and the order
611a54f4eaeSMogballof blocks in a region is not semantically meaningful and non-terminator
61262828865SStephen Neuendorfferoperations may be freely reordered, for instance, by canonicalization. Other
61362828865SStephen Neuendorfferkinds of graphs, such as graphs with multiple source nodes and multiple
61462828865SStephen Neuendorfferdestination nodes, can also be represented by representing graph edges as MLIR
61562828865SStephen Neuendorfferoperations.
61662828865SStephen Neuendorffer
61762828865SStephen NeuendorfferNote that cycles can occur within a single block in a graph region, or between
61862828865SStephen Neuendorfferbasic blocks.
61962828865SStephen Neuendorffer
62062828865SStephen Neuendorffer```mlir
62162828865SStephen Neuendorffer"test.graph_region"() ({ // A Graph region
62262828865SStephen Neuendorffer  %1 = "op1"(%1, %3) : (i32, i32) -> (i32)  // OK: %1, %3 allowed here
62362828865SStephen Neuendorffer  %2 = "test.ssacfg_region"() ({
62462828865SStephen Neuendorffer     %5 = "op2"(%1, %2, %3, %4) : (i32, i32, i32, i32) -> (i32) // OK: %1, %2, %3, %4 all defined in the containing region
62562828865SStephen Neuendorffer  }) : () -> (i32)
62662828865SStephen Neuendorffer  %3 = "op2"(%1, %4) : (i32, i32) -> (i32)  // OK: %4 allowed here
62762828865SStephen Neuendorffer  %4 = "op3"(%1) : (i32) -> (i32)
62862828865SStephen Neuendorffer}) : () -> ()
62962828865SStephen Neuendorffer```
63062828865SStephen Neuendorffer
6315b4a01d4SMehdi Amini### Arguments and Results
6325b4a01d4SMehdi Amini
6335b4a01d4SMehdi AminiThe arguments of the first block of a region are treated as arguments of the
6345b4a01d4SMehdi Aminiregion. The source of these arguments is defined by the semantics of the parent
6355b4a01d4SMehdi Aminioperation. They may correspond to some of the values the operation itself uses.
6365b4a01d4SMehdi Amini
6375b4a01d4SMehdi AminiRegions produce a (possibly empty) list of values. The operation semantics
6385b4a01d4SMehdi Aminidefines the relation between the region results and the operation results.
6395b4a01d4SMehdi Amini
6405b4a01d4SMehdi Amini## Type System
6415b4a01d4SMehdi Amini
642caddfbd2SRiver RiddleEach value in MLIR has a type defined by the type system. MLIR has an open type
643caddfbd2SRiver Riddlesystem (i.e. there is no fixed list of types), and types may have
644caddfbd2SRiver Riddleapplication-specific semantics. MLIR dialects may define any number of types
645caddfbd2SRiver Riddlewith no restrictions on the abstractions they represent.
6465b4a01d4SMehdi Amini
6475b4a01d4SMehdi Amini```
64809f7a55fSRiver Riddletype ::= type-alias | dialect-type | builtin-type
6495b4a01d4SMehdi Amini
6505b4a01d4SMehdi Aminitype-list-no-parens ::=  type (`,` type)*
6515b4a01d4SMehdi Aminitype-list-parens ::= `(` `)`
6525b4a01d4SMehdi Amini                   | `(` type-list-no-parens `)`
6535b4a01d4SMehdi Amini
65462828865SStephen Neuendorffer// This is a common way to refer to a value with a specified type.
6555b4a01d4SMehdi Aminissa-use-and-type ::= ssa-use `:` type
6569a4472c5SJacques Pienaarssa-use ::= value-use
6575b4a01d4SMehdi Amini
6585b4a01d4SMehdi Amini// Non-empty list of names and types.
6595b4a01d4SMehdi Aminissa-use-and-type-list ::= ssa-use-and-type (`,` ssa-use-and-type)*
6609a4472c5SJacques Pienaar
6619a4472c5SJacques Pienaarfunction-type ::= (type | type-list-parens) `->` (type | type-list-parens)
6625b4a01d4SMehdi Amini```
6635b4a01d4SMehdi Amini
6645b4a01d4SMehdi Amini### Type Aliases
6655b4a01d4SMehdi Amini
6665b4a01d4SMehdi Amini```
667abacd363SYan Xintype-alias-def ::= `!` alias-name `=` type
668abacd363SYan Xintype-alias ::= `!` alias-name
6695b4a01d4SMehdi Amini```
6705b4a01d4SMehdi Amini
6715b4a01d4SMehdi AminiMLIR supports defining named aliases for types. A type alias is an identifier
6725b4a01d4SMehdi Aminithat can be used in the place of the type that it defines. These aliases *must*
6735b4a01d4SMehdi Aminibe defined before their uses. Alias names may not contain a '.', since those
6745b4a01d4SMehdi Amininames are reserved for [dialect types](#dialect-types).
6755b4a01d4SMehdi Amini
6765b4a01d4SMehdi AminiExample:
6775b4a01d4SMehdi Amini
6785b4a01d4SMehdi Amini```mlir
679a6cef03fSRiver Riddle!avx_m128 = vector<4 x f32>
6805b4a01d4SMehdi Amini
6815b4a01d4SMehdi Amini// Using the original type.
6825b4a01d4SMehdi Amini"foo"(%x) : vector<4 x f32> -> ()
6835b4a01d4SMehdi Amini
6845b4a01d4SMehdi Amini// Using the type alias.
6855b4a01d4SMehdi Amini"foo"(%x) : !avx_m128 -> ()
6865b4a01d4SMehdi Amini```
6875b4a01d4SMehdi Amini
6885b4a01d4SMehdi Amini### Dialect Types
6895b4a01d4SMehdi Amini
6905b4a01d4SMehdi AminiSimilarly to operations, dialects may define custom extensions to the type
6915b4a01d4SMehdi Aminisystem.
6925b4a01d4SMehdi Amini
6935b4a01d4SMehdi Amini```
6945b4a01d4SMehdi Aminidialect-namespace ::= bare-id
6955b4a01d4SMehdi Amini
696abacd363SYan Xindialect-type ::= `!` (opaque-dialect-type | pretty-dialect-type)
697ab9cdf09SRiver Riddleopaque-dialect-type ::= dialect-namespace dialect-type-body
698abacd363SYan Xinpretty-dialect-type ::= dialect-namespace `.` pretty-dialect-type-lead-ident
699ab9cdf09SRiver Riddle                                              dialect-type-body?
700abacd363SYan Xinpretty-dialect-type-lead-ident ::= `[A-Za-z][A-Za-z0-9._]*`
7015b4a01d4SMehdi Amini
702abacd363SYan Xindialect-type-body ::= `<` dialect-type-contents+ `>`
703ab9cdf09SRiver Riddledialect-type-contents ::= dialect-type-body
704abacd363SYan Xin                            | `(` dialect-type-contents+ `)`
705abacd363SYan Xin                            | `[` dialect-type-contents+ `]`
706abacd363SYan Xin                            | `{` dialect-type-contents+ `}`
707abacd363SYan Xin                            | [^\[<({\]>)}\0]+
7085b4a01d4SMehdi Amini```
7095b4a01d4SMehdi Amini
710ab9cdf09SRiver RiddleDialect types are generally specified in an opaque form, where the contents
711ab9cdf09SRiver Riddleof the type are defined within a body wrapped with the dialect namespace
712ab9cdf09SRiver Riddleand `<>`. Consider the following examples:
7135b4a01d4SMehdi Amini
7145b4a01d4SMehdi Amini```mlir
715ab9cdf09SRiver Riddle// A tensorflow string type.
716ab9cdf09SRiver Riddle!tf<string>
7175b4a01d4SMehdi Amini
718ab9cdf09SRiver Riddle// A type with complex components.
719ab9cdf09SRiver Riddle!foo<something<abcd>>
7205b4a01d4SMehdi Amini
721ab9cdf09SRiver Riddle// An even more complex type.
722ab9cdf09SRiver Riddle!foo<"a123^^^" + bar>
7235b4a01d4SMehdi Amini```
7245b4a01d4SMehdi Amini
725ab9cdf09SRiver RiddleDialect types that are simple enough may use a prettier format, which unwraps
726ab9cdf09SRiver Riddlepart of the syntax into an equivalent, but lighter weight form:
7275b4a01d4SMehdi Amini
7285b4a01d4SMehdi Amini```mlir
729ab9cdf09SRiver Riddle// A tensorflow string type.
7305b4a01d4SMehdi Amini!tf.string
7315b4a01d4SMehdi Amini
732ab9cdf09SRiver Riddle// A type with complex components.
7335b4a01d4SMehdi Amini!foo.something<abcd>
7345b4a01d4SMehdi Amini```
7355b4a01d4SMehdi Amini
7361294fa69SRiver RiddleSee [here](DefiningDialects/AttributesAndTypes.md) to learn how to define dialect types.
7375b4a01d4SMehdi Amini
73809f7a55fSRiver Riddle### Builtin Types
7395b4a01d4SMehdi Amini
740caddfbd2SRiver RiddleThe [builtin dialect](Dialects/Builtin.md) defines a set of types that are
741caddfbd2SRiver Riddledirectly usable by any other dialect in MLIR. These types cover a range from
742caddfbd2SRiver Riddleprimitive integer and floating-point types, function types, and more.
7435b4a01d4SMehdi Amini
7445e118f93SMehdi Amini## Properties
7455e118f93SMehdi Amini
7465e118f93SMehdi AminiProperties are extra data members stored directly on an Operation class. They
7475e118f93SMehdi Aminiprovide a way to store [inherent attributes](#attributes) and other arbitrary
7485e118f93SMehdi Aminidata. The semantics of the data is specific to a given operation, and may be
7495e118f93SMehdi Aminiexposed through [Interfaces](Interfaces.md) accessors and other methods.
7505e118f93SMehdi AminiProperties can always be serialized to Attribute in order to be printed
7515e118f93SMehdi Aminigenerically.
7525e118f93SMehdi Amini
7535b4a01d4SMehdi Amini## Attributes
7545b4a01d4SMehdi Amini
7555b4a01d4SMehdi AminiSyntax:
7565b4a01d4SMehdi Amini
7575b4a01d4SMehdi Amini```
7586b07a978SSean Silvaattribute-entry ::= (bare-id | string-literal) `=` attribute-value
7596b07a978SSean Silvaattribute-value ::= attribute-alias | dialect-attribute | builtin-attribute
7605b4a01d4SMehdi Amini```
7615b4a01d4SMehdi Amini
7625b4a01d4SMehdi AminiAttributes are the mechanism for specifying constant data on operations in
763042db54bSSean Silvaplaces where a variable is never allowed - e.g. the comparison predicate of a
764*73fa6685Smlevesquedion[`cmpi` operation](Dialects/ArithOps.md/#arithcmpi-arithcmpiop). Each operation has an
7656b07a978SSean Silvaattribute dictionary, which associates a set of attribute names to attribute
7666b07a978SSean Silvavalues. MLIR's builtin dialect provides a rich set of
7676b07a978SSean Silva[builtin attribute values](#builtin-attribute-values) out of the box (such as
7686b07a978SSean Silvaarrays, dictionaries, strings, etc.). Additionally, dialects can define their
7696b07a978SSean Silvaown [dialect attribute values](#dialect-attribute-values).
7705b4a01d4SMehdi Amini
7715e118f93SMehdi AminiFor dialects which haven't adopted properties yet, the top-level attribute
7725e118f93SMehdi Aminidictionary attached to an operation has special semantics. The attribute
7735e118f93SMehdi Aminientries are considered to be of two different kinds based on whether their
7745e118f93SMehdi Aminidictionary key has a dialect prefix:
7755b4a01d4SMehdi Amini
7766b07a978SSean Silva-   *inherent attributes* are inherent to the definition of an operation's
777a54f4eaeSMogball    semantics. The operation itself is expected to verify the consistency of
778a54f4eaeSMogball    these attributes. An example is the `predicate` attribute of the
779a54f4eaeSMogball    `arith.cmpi` op. These attributes must have names that do not start with a
780a54f4eaeSMogball    dialect prefix.
7815b4a01d4SMehdi Amini
7826b07a978SSean Silva-   *discardable attributes* have semantics defined externally to the operation
7836b07a978SSean Silva    itself, but must be compatible with the operations's semantics. These
7846b07a978SSean Silva    attributes must have names that start with a dialect prefix. The dialect
7856b07a978SSean Silva    indicated by the dialect prefix is expected to verify these attributes. An
7866b07a978SSean Silva    example is the `gpu.container_module` attribute.
7876b07a978SSean Silva
7886b07a978SSean SilvaNote that attribute values are allowed to themselves be dictionary attributes,
7896b07a978SSean Silvabut only the top-level dictionary attribute attached to the operation is subject
7906b07a978SSean Silvato the classification above.
7915b4a01d4SMehdi Amini
7925e118f93SMehdi AminiWhen properties are adopted, only discardable attributes are stored in the
7935e118f93SMehdi Aminitop-level dictionary, while inherent attributes are stored in the properties
7945e118f93SMehdi Aministorage.
7955e118f93SMehdi Amini
7965b4a01d4SMehdi Amini### Attribute Value Aliases
7975b4a01d4SMehdi Amini
7985b4a01d4SMehdi Amini```
799abacd363SYan Xinattribute-alias-def ::= `#` alias-name `=` attribute-value
800abacd363SYan Xinattribute-alias ::= `#` alias-name
8015b4a01d4SMehdi Amini```
8025b4a01d4SMehdi Amini
8035b4a01d4SMehdi AminiMLIR supports defining named aliases for attribute values. An attribute alias is
8045b4a01d4SMehdi Aminian identifier that can be used in the place of the attribute that it defines.
8055b4a01d4SMehdi AminiThese aliases *must* be defined before their uses. Alias names may not contain a
8065b4a01d4SMehdi Amini'.', since those names are reserved for
8075b4a01d4SMehdi Amini[dialect attributes](#dialect-attribute-values).
8085b4a01d4SMehdi Amini
8095b4a01d4SMehdi AminiExample:
8105b4a01d4SMehdi Amini
8115b4a01d4SMehdi Amini```mlir
8124268e4f4SRiver Riddle#map = affine_map<(d0) -> (d0 + 10)>
8135b4a01d4SMehdi Amini
8145b4a01d4SMehdi Amini// Using the original attribute.
8154268e4f4SRiver Riddle%b = affine.apply affine_map<(d0) -> (d0 + 10)> (%a)
8165b4a01d4SMehdi Amini
8175b4a01d4SMehdi Amini// Using the attribute alias.
8185b4a01d4SMehdi Amini%b = affine.apply #map(%a)
8195b4a01d4SMehdi Amini```
8205b4a01d4SMehdi Amini
8215b4a01d4SMehdi Amini### Dialect Attribute Values
8225b4a01d4SMehdi Amini
823ab9cdf09SRiver RiddleSimilarly to operations, dialects may define custom attribute values.
8245b4a01d4SMehdi Amini
8255b4a01d4SMehdi Amini```
826ab9cdf09SRiver Riddledialect-namespace ::= bare-id
827ab9cdf09SRiver Riddle
828abacd363SYan Xindialect-attribute ::= `#` (opaque-dialect-attribute | pretty-dialect-attribute)
829ab9cdf09SRiver Riddleopaque-dialect-attribute ::= dialect-namespace dialect-attribute-body
830abacd363SYan Xinpretty-dialect-attribute ::= dialect-namespace `.` pretty-dialect-attribute-lead-ident
831ab9cdf09SRiver Riddle                                              dialect-attribute-body?
832abacd363SYan Xinpretty-dialect-attribute-lead-ident ::= `[A-Za-z][A-Za-z0-9._]*`
833ab9cdf09SRiver Riddle
834abacd363SYan Xindialect-attribute-body ::= `<` dialect-attribute-contents+ `>`
835ab9cdf09SRiver Riddledialect-attribute-contents ::= dialect-attribute-body
836abacd363SYan Xin                            | `(` dialect-attribute-contents+ `)`
837abacd363SYan Xin                            | `[` dialect-attribute-contents+ `]`
838abacd363SYan Xin                            | `{` dialect-attribute-contents+ `}`
839abacd363SYan Xin                            | [^\[<({\]>)}\0]+
8405b4a01d4SMehdi Amini```
8415b4a01d4SMehdi Amini
842ab9cdf09SRiver RiddleDialect attributes are generally specified in an opaque form, where the contents
843ab9cdf09SRiver Riddleof the attribute are defined within a body wrapped with the dialect namespace
844ab9cdf09SRiver Riddleand `<>`. Consider the following examples:
8455b4a01d4SMehdi Amini
8465b4a01d4SMehdi Amini```mlir
847ab9cdf09SRiver Riddle// A string attribute.
848ab9cdf09SRiver Riddle#foo<string<"">>
8495b4a01d4SMehdi Amini
850ab9cdf09SRiver Riddle// A complex attribute.
851ab9cdf09SRiver Riddle#foo<"a123^^^" + bar>
8525b4a01d4SMehdi Amini```
8535b4a01d4SMehdi Amini
854ab9cdf09SRiver RiddleDialect attributes that are simple enough may use a prettier format, which unwraps
855ab9cdf09SRiver Riddlepart of the syntax into an equivalent, but lighter weight form:
8565b4a01d4SMehdi Amini
8575b4a01d4SMehdi Amini```mlir
858ab9cdf09SRiver Riddle// A string attribute.
859ab9cdf09SRiver Riddle#foo.string<"">
8605b4a01d4SMehdi Amini```
8615b4a01d4SMehdi Amini
8621294fa69SRiver RiddleSee [here](DefiningDialects/AttributesAndTypes.md) on how to define dialect attribute values.
8635b4a01d4SMehdi Amini
864c7cae0e4SRiver Riddle### Builtin Attribute Values
8655b4a01d4SMehdi Amini
866caddfbd2SRiver RiddleThe [builtin dialect](Dialects/Builtin.md) defines a set of attribute values
867caddfbd2SRiver Riddlethat are directly usable by any other dialect in MLIR. These types cover a range
868caddfbd2SRiver Riddlefrom primitive integer and floating-point values, attribute dictionaries, dense
869caddfbd2SRiver Riddlemulti-dimensional arrays, and more.
8700e0b6070SMatteo Franciolini
87169bc8c9eSManas### IR Versioning
8720e0b6070SMatteo Franciolini
8730e0b6070SMatteo FrancioliniA dialect can opt-in to handle versioning through the
8740e0b6070SMatteo Franciolini`BytecodeDialectInterface`. Few hooks are exposed to the dialect to allow
8750e0b6070SMatteo Franciolinimanaging a version encoded into the bytecode file. The version is loaded lazily
8760e0b6070SMatteo Francioliniand allows to retrieve the version information while parsing the input IR, and
8770e0b6070SMatteo Franciolinigives an opportunity to each dialect for which a version is present to perform
8780e0b6070SMatteo FrancioliniIR upgrades post-parsing through the `upgradeFromVersion` method. Custom
8790e0b6070SMatteo FrancioliniAttribute and Type encodings can also be upgraded according to the dialect
8800e0b6070SMatteo Francioliniversion using readAttribute and readType methods.
8810e0b6070SMatteo Franciolini
8820e0b6070SMatteo FrancioliniThere is no restriction on what kind of information a dialect is allowed to
8830e0b6070SMatteo Francioliniencode to model its versioning. Currently, versioning is supported only for
8840e0b6070SMatteo Franciolinibytecode formats.
885