River Riddle | 55de49a | 2020-04-11 18:38:05 | [diff] [blame] | 1 | # MLIR Language Reference |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 2 | |
Mehdi Amini | 90b5a38 | 2019-07-18 17:34:19 | [diff] [blame] | 3 | MLIR (Multi-Level IR) is a compiler intermediate representation with |
| 4 | similarities to traditional three-address SSA representations (like |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 5 | [LLVM IR](http://llvm.org/docs/LangRef.html) or |
Quinn Pham | c71fbdd | 2021-11-03 19:41:24 | [diff] [blame] | 6 | [SIL](https://github.com/apple/swift/blob/main/docs/SIL.rst)), but which |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 7 | introduces notions from polyhedral loop optimization as first-class concepts. |
| 8 | This hybrid design is optimized to represent, analyze, and transform high level |
| 9 | dataflow graphs as well as target-specific code generated for high performance |
| 10 | data parallel systems. Beyond its representational capabilities, its single |
| 11 | continuous design provides a framework to lower from dataflow graphs to |
| 12 | high-performance target-specific code. |
| 13 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 14 | This document defines and describes the key concepts in MLIR, and is intended to |
| 15 | be a dry reference document - the |
| 16 | [rationale documentation](Rationale/Rationale.md), |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 17 | [glossary](../getting_started/Glossary.md), and other content are hosted |
| 18 | elsewhere. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 19 | |
| 20 | MLIR is designed to be used in three different forms: a human-readable textual |
| 21 | form suitable for debugging, an in-memory form suitable for programmatic |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 22 | transformations and analysis, and a compact serialized form suitable for storage |
| 23 | and transport. The different forms all describe the same semantic content. This |
| 24 | document describes the human-readable textual form. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 25 | |
| 26 | [TOC] |
| 27 | |
River Riddle | 465ef55 | 2019-04-05 15:19:42 | [diff] [blame] | 28 | ## High-Level Structure |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 29 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 30 | MLIR is fundamentally based on a graph-like data structure of nodes, called |
| 31 | *Operations*, and edges, called *Values*. Each Value is the result of exactly |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 32 | one Operation or Block Argument, and has a *Value Type* defined by the |
| 33 | [type system](#type-system). [Operations](#operations) are contained in |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 34 | [Blocks](#blocks) and Blocks are contained in [Regions](#regions). Operations |
| 35 | are also ordered within their containing block and Blocks are ordered in their |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 36 | containing region, although this order may or may not be semantically meaningful |
| 37 | in a given [kind of region](Interfaces.md/#regionkindinterfaces)). Operations |
| 38 | may also contain regions, enabling hierarchical structures to be represented. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 39 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 40 | Operations can represent many different concepts, from higher-level concepts |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 41 | like function definitions, function calls, buffer allocations, view or slices of |
| 42 | buffers, and process creation, to lower-level concepts like target-independent |
| 43 | arithmetic, target-specific instructions, configuration registers, and logic |
| 44 | gates. These different concepts are represented by different operations in MLIR |
| 45 | and the set of operations usable in MLIR can be arbitrarily extended. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 46 | |
| 47 | MLIR also provides an extensible framework for transformations on operations, |
| 48 | using familiar concepts of compiler [Passes](Passes.md). Enabling an arbitrary |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 49 | set of passes on an arbitrary set of operations results in a significant scaling |
| 50 | challenge, since each transformation must potentially take into account the |
| 51 | semantics of any operation. MLIR addresses this complexity by allowing operation |
| 52 | semantics to be described abstractly using [Traits](Traits.md) and |
| 53 | [Interfaces](Interfaces.md), enabling transformations to operate on operations |
| 54 | more generically. Traits often describe verification constraints on valid IR, |
| 55 | enabling complex invariants to be captured and checked. (see |
| 56 | [Op vs Operation](Tutorials/Toy/Ch-2.md/#op-vs-operation-using-mlir-operations)) |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 57 | |
| 58 | One obvious application of MLIR is to represent an |
| 59 | [SSA-based](https://en.wikipedia.org/wiki/Static_single_assignment_form) IR, |
River Riddle | caddfbd | 2021-03-20 01:19:16 | [diff] [blame] | 60 | like the LLVM core IR, with appropriate choice of operation types to define |
| 61 | Modules, Functions, Branches, Memory Allocation, and verification constraints to |
| 62 | ensure the SSA Dominance property. MLIR includes a collection of dialects which |
| 63 | defines just such structures. However, MLIR is intended to be general enough to |
| 64 | represent other compiler-like data structures, such as Abstract Syntax Trees in |
| 65 | a language frontend, generated instructions in a target-specific backend, or |
| 66 | circuits in a High-Level Synthesis tool. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 67 | |
| 68 | Here's an example of an MLIR module: |
| 69 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 70 | ```mlir |
Chris Lattner | 8ebd64b | 2019-01-02 20:32:30 | [diff] [blame] | 71 | // Compute A*B using an implementation of multiply kernel and print the |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 72 | // result using a TensorFlow op. The dimensions of A and B are partially |
| 73 | // known. The shapes are assumed to match. |
Chris Lattner | 8ebd64b | 2019-01-02 20:32:30 | [diff] [blame] | 74 | func @mul(%A: tensor<100x?xf32>, %B: tensor<?x50xf32>) -> (tensor<100x50xf32>) { |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 75 | // Compute the inner dimension of %A using the dim operation. |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 76 | %n = memref.dim %A, 1 : tensor<100x?xf32> |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 77 | |
| 78 | // Allocate addressable "buffers" and copy tensors %A and %B into them. |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 79 | %A_m = memref.alloc(%n) : memref<100x?xf32> |
| 80 | memref.tensor_store %A to %A_m : memref<100x?xf32> |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 81 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 82 | %B_m = memref.alloc(%n) : memref<?x50xf32> |
| 83 | memref.tensor_store %B to %B_m : memref<?x50xf32> |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 84 | |
River Riddle | 6f7470a | 2019-02-06 00:29:25 | [diff] [blame] | 85 | // Call function @multiply passing memrefs as arguments, |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 86 | // and getting returned the result of the multiplication. |
| 87 | %C_m = call @multiply(%A_m, %B_m) |
| 88 | : (memref<100x?xf32>, memref<?x50xf32>) -> (memref<100x50xf32>) |
| 89 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 90 | memref.dealloc %A_m : memref<100x?xf32> |
| 91 | memref.dealloc %B_m : memref<?x50xf32> |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 92 | |
| 93 | // Load the buffer data into a higher level "tensor" value. |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 94 | %C = memref.tensor_load %C_m : memref<100x50xf32> |
| 95 | memref.dealloc %C_m : memref<100x50xf32> |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 96 | |
| 97 | // Call TensorFlow built-in function to print the result tensor. |
| 98 | "tf.Print"(%C){message: "mul result"} |
| 99 | : (tensor<100x50xf32) -> (tensor<100x50xf32>) |
| 100 | |
| 101 | return %C : tensor<100x50xf32> |
| 102 | } |
| 103 | |
Chris Lattner | 8ebd64b | 2019-01-02 20:32:30 | [diff] [blame] | 104 | // A function that multiplies two memrefs and returns the result. |
| 105 | func @multiply(%A: memref<100x?xf32>, %B: memref<?x50xf32>) |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 106 | -> (memref<100x50xf32>) { |
| 107 | // Compute the inner dimension of %A. |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 108 | %n = memref.dim %A, 1 : memref<100x?xf32> |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 109 | |
| 110 | // Allocate memory for the multiplication result. |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 111 | %C = memref.alloc() : memref<100x50xf32> |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 112 | |
| 113 | // Multiplication loop nest. |
River Riddle | 832567b | 2019-03-25 17:14:34 | [diff] [blame] | 114 | affine.for %i = 0 to 100 { |
| 115 | affine.for %j = 0 to 50 { |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 116 | memref.store 0 to %C[%i, %j] : memref<100x50xf32> |
River Riddle | 832567b | 2019-03-25 17:14:34 | [diff] [blame] | 117 | affine.for %k = 0 to %n { |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 118 | %a_v = memref.load %A[%i, %k] : memref<100x?xf32> |
| 119 | %b_v = memref.load %B[%k, %j] : memref<?x50xf32> |
| 120 | %prod = arith.mulf %a_v, %b_v : f32 |
| 121 | %c_v = memref.load %C[%i, %j] : memref<100x50xf32> |
| 122 | %sum = arith.addf %c_v, %prod : f32 |
| 123 | memref.store %sum, %C[%i, %j] : memref<100x50xf32> |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 124 | } |
| 125 | } |
| 126 | } |
| 127 | return %C : memref<100x50xf32> |
| 128 | } |
| 129 | ``` |
| 130 | |
River Riddle | 465ef55 | 2019-04-05 15:19:42 | [diff] [blame] | 131 | ## Notation |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 132 | |
| 133 | MLIR has a simple and unambiguous grammar, allowing it to reliably round-trip |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 134 | through a textual form. This is important for development of the compiler - e.g. |
| 135 | for understanding the state of code as it is being transformed and writing test |
| 136 | cases. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 137 | |
| 138 | This document describes the grammar using |
| 139 | [Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form). |
| 140 | |
| 141 | This is the EBNF grammar used in this document, presented in yellow boxes. |
| 142 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 143 | ``` |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 144 | alternation ::= expr0 | expr1 | expr2 // Either expr0 or expr1 or expr2. |
| 145 | sequence ::= expr0 expr1 expr2 // Sequence of expr0 expr1 expr2. |
| 146 | repetition0 ::= expr* // 0 or more occurrences. |
| 147 | repetition1 ::= expr+ // 1 or more occurrences. |
| 148 | optionality ::= expr? // 0 or 1 occurrence. |
| 149 | grouping ::= (expr) // Everything inside parens is grouped together. |
| 150 | literal ::= `abcd` // Matches the literal `abcd`. |
| 151 | ``` |
| 152 | |
| 153 | Code examples are presented in blue boxes. |
| 154 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 155 | ```mlir |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 156 | // This is an example use of the grammar above: |
| 157 | // This matches things like: ba, bana, boma, banana, banoma, bomana... |
| 158 | example ::= `b` (`an` | `om`)* `a` |
| 159 | ``` |
| 160 | |
River Riddle | 465ef55 | 2019-04-05 15:19:42 | [diff] [blame] | 161 | ### Common syntax |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 162 | |
| 163 | The following core grammar productions are used in this document: |
| 164 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 165 | ``` |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 166 | // TODO: Clarify the split between lexing (tokens) and parsing (grammar). |
| 167 | digit ::= [0-9] |
| 168 | hex_digit ::= [0-9a-fA-F] |
| 169 | letter ::= [a-zA-Z] |
| 170 | id-punct ::= [$._-] |
| 171 | |
Alex Zinenko | 99b19c1 | 2019-02-07 16:36:50 | [diff] [blame] | 172 | integer-literal ::= decimal-literal | hexadecimal-literal |
| 173 | decimal-literal ::= digit+ |
| 174 | hexadecimal-literal ::= `0x` hex_digit+ |
Andrew Anderson | a50f871 | 2019-11-26 01:53:20 | [diff] [blame] | 175 | float-literal ::= [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)? |
River Riddle | 9db53a1 | 2020-07-07 08:35:23 | [diff] [blame] | 176 | string-literal ::= `"` [^"\n\f\v\r]* `"` TODO: define escaping rules |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 177 | ``` |
| 178 | |
| 179 | Not listed here, but MLIR does support comments. They use standard BCPL syntax, |
| 180 | starting with a `//` and going until the end of the line. |
| 181 | |
Siddharth Bhat | 357f2d9 | 2022-01-21 11:32:39 | [diff] [blame] | 182 | |
| 183 | ### Top level Productions |
| 184 | |
| 185 | ``` |
| 186 | // Top level production |
| 187 | toplevel := (operation | attribute-alias-def | type-alias-def)* |
| 188 | ``` |
| 189 | |
| 190 | The production `toplevel` is the top level production that is parsed by any parsing |
| 191 | consuming the MLIR syntax. [Operations](#operations), |
| 192 | [Attribute alises](#attribute-value-aliases), and [Type aliases](#type-aliases) |
| 193 | can be declared on the toplevel. |
| 194 | |
River Riddle | 465ef55 | 2019-04-05 15:19:42 | [diff] [blame] | 195 | ### Identifiers and keywords |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 196 | |
| 197 | Syntax: |
| 198 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 199 | ``` |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 200 | // Identifiers |
River Riddle | 3b3e11d | 2019-02-27 00:43:12 | [diff] [blame] | 201 | bare-id ::= (letter|[_]) (letter|digit|[_$.])* |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 202 | bare-id-list ::= bare-id (`,` bare-id)* |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 203 | value-id ::= `%` suffix-id |
River Riddle | 31b3e22 | 2019-12-04 20:05:52 | [diff] [blame] | 204 | suffix-id ::= (digit+ | ((letter|id-punct) (letter|id-punct|digit)*)) |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 205 | |
River Riddle | 31b3e22 | 2019-12-04 20:05:52 | [diff] [blame] | 206 | symbol-ref-id ::= `@` (suffix-id | string-literal) |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 207 | value-id-list ::= value-id (`,` value-id)* |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 208 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 209 | // Uses of value, e.g. in an operand list to an operation. |
| 210 | value-use ::= value-id |
| 211 | value-use-list ::= value-use (`,` value-use)* |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 212 | ``` |
| 213 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 214 | Identifiers name entities such as values, types and functions, and are chosen by |
| 215 | the writer of MLIR code. Identifiers may be descriptive (e.g. `%batch_size`, |
| 216 | `@matmul`), or may be non-descriptive when they are auto-generated (e.g. `%23`, |
| 217 | `@func42`). Identifier names for values may be used in an MLIR text file but are |
| 218 | not persisted as part of the IR - the printer will give them anonymous names |
| 219 | like `%42`. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 220 | |
| 221 | MLIR guarantees identifiers never collide with keywords by prefixing identifiers |
Chris Lattner | 3f93d93 | 2019-04-06 02:36:42 | [diff] [blame] | 222 | with a sigil (e.g. `%`, `#`, `@`, `^`, `!`). In certain unambiguous contexts |
| 223 | (e.g. affine expressions), identifiers are not prefixed, for brevity. New |
| 224 | keywords may be added to future versions of MLIR without danger of collision |
| 225 | with existing identifiers. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 226 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 227 | Value identifiers are only [in scope](#value-scoping) for the (nested) region in |
| 228 | which they are defined and cannot be accessed or referenced outside of that |
| 229 | region. Argument identifiers in mapping functions are in scope for the mapping |
| 230 | body. Particular operations may further limit which identifiers are in scope in |
| 231 | their regions. For instance, the scope of values in a region with |
| 232 | [SSA control flow semantics](#control-flow-and-ssacfg-regions) is constrained |
| 233 | according to the standard definition of |
| 234 | [SSA dominance](https://en.wikipedia.org/wiki/Dominator_\(graph_theory\)). |
| 235 | Another example is the [IsolatedFromAbove trait](Traits.md/#isolatedfromabove), |
| 236 | which restricts directly accessing values defined in containing regions. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 237 | |
| 238 | Function identifiers and mapping identifiers are associated with |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 239 | [Symbols](SymbolsAndSymbolTables.md) and have scoping rules dependent on symbol |
| 240 | attributes. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 241 | |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 242 | ## Dialects |
| 243 | |
Lucy Fox | 9d7039b | 2019-11-15 17:48:54 | [diff] [blame] | 244 | Dialects are the mechanism by which to engage with and extend the MLIR |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 245 | ecosystem. They allow for defining new [operations](#operations), as well as |
| 246 | [attributes](#attributes) and [types](#type-system). Each dialect is given a |
| 247 | unique `namespace` that is prefixed to each defined attribute/operation/type. |
| 248 | For example, the [Affine dialect](Dialects/Affine.md) defines the namespace: |
| 249 | `affine`. |
| 250 | |
| 251 | MLIR allows for multiple dialects, even those outside of the main tree, to |
| 252 | co-exist together within one module. Dialects are produced and consumed by |
| 253 | certain passes. MLIR provides a [framework](DialectConversion.md) to convert |
Lucy Fox | 9d7039b | 2019-11-15 17:48:54 | [diff] [blame] | 254 | between, and within, different dialects. |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 255 | |
| 256 | A few of the dialects supported by MLIR: |
| 257 | |
| 258 | * [Affine dialect](Dialects/Affine.md) |
River Riddle | 23aa5a7 | 2022-02-26 22:49:54 | [diff] [blame^] | 259 | * [Func dialect](Dialects/Func.md) |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 260 | * [GPU dialect](Dialects/GPU.md) |
| 261 | * [LLVM dialect](Dialects/LLVM.md) |
| 262 | * [SPIR-V dialect](Dialects/SPIR-V.md) |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 263 | * [Vector dialect](Dialects/Vector.md) |
| 264 | |
| 265 | ### Target specific operations |
| 266 | |
| 267 | Dialects provide a modular way in which targets can expose target-specific |
| 268 | operations directly through to MLIR. As an example, some targets go through |
| 269 | LLVM. LLVM has a rich set of intrinsics for certain target-independent |
| 270 | operations (e.g. addition with overflow check) as well as providing access to |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 271 | target-specific operations for the targets it supports (e.g. vector permutation |
| 272 | operations). LLVM intrinsics in MLIR are represented via operations that start |
| 273 | with an "llvm." name. |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 274 | |
| 275 | Example: |
| 276 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 277 | ```mlir |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 278 | // LLVM: %x = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %a, i16 %b) |
| 279 | %x:2 = "llvm.sadd.with.overflow.i16"(%a, %b) : (i16, i16) -> (i16, i1) |
| 280 | ``` |
| 281 | |
| 282 | These operations only work when targeting LLVM as a backend (e.g. for CPUs and |
| 283 | GPUs), and are required to align with the LLVM definition of these intrinsics. |
| 284 | |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 285 | ## Operations |
| 286 | |
| 287 | Syntax: |
| 288 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 289 | ``` |
Geoffrey Martin-Noble | 22411d8 | 2021-04-06 04:32:23 | [diff] [blame] | 290 | operation ::= op-result-list? (generic-operation | custom-operation) |
| 291 | trailing-location? |
| 292 | generic-operation ::= string-literal `(` value-use-list? `)` successor-list? |
| 293 | region-list? dictionary-attribute? `:` function-type |
| 294 | custom-operation ::= bare-id custom-operation-format |
| 295 | op-result-list ::= op-result (`,` op-result)* `=` |
| 296 | op-result ::= value-id (`:` integer-literal) |
| 297 | successor-list ::= `[` successor (`,` successor)* `]` |
| 298 | successor ::= caret-id (`:` bb-arg-list)? |
| 299 | region-list ::= `(` region (`,` region)* `)` |
| 300 | dictionary-attribute ::= `{` (attribute-entry (`,` attribute-entry)*)? `}` |
| 301 | trailing-location ::= (`loc` `(` location `)`)? |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 302 | ``` |
| 303 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 304 | MLIR introduces a uniform concept called *operations* to enable describing many |
| 305 | different levels of abstractions and computations. Operations in MLIR are fully |
| 306 | extensible (there is no fixed list of operations) and have application-specific |
| 307 | semantics. For example, MLIR supports |
| 308 | [target-independent operations](Dialects/Standard.md#memory-operations), |
| 309 | [affine operations](Dialects/Affine.md), and |
| 310 | [target-specific machine operations](#target-specific-operations). |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 311 | |
| 312 | The internal representation of an operation is simple: an operation is |
| 313 | identified by a unique string (e.g. `dim`, `tf.Conv2d`, `x86.repmovsb`, |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 314 | `ppc.eieio`, etc), can return zero or more results, take zero or more operands, |
| 315 | has a dictionary of [attributes](#attributes), has zero or more successors, and |
| 316 | zero or more enclosed [regions](#regions). The generic printing form includes |
| 317 | all these elements literally, with a function type to indicate the types of the |
| 318 | results and operands. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 319 | |
| 320 | Example: |
| 321 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 322 | ```mlir |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 323 | // An operation that produces two results. |
| 324 | // The results of %result can be accessed via the <name> `#` <opNo> syntax. |
| 325 | %result:2 = "foo_div"() : () -> (f32, i32) |
| 326 | |
| 327 | // Pretty form that defines a unique name for each result. |
| 328 | %foo, %bar = "foo_div"() : () -> (f32, i32) |
| 329 | |
| 330 | // Invoke a TensorFlow function called tf.scramble with two inputs |
| 331 | // and an attribute "fruit". |
Sean Silva | 6b07a97 | 2021-02-05 00:17:45 | [diff] [blame] | 332 | %2 = "tf.scramble"(%result#0, %bar) {fruit = "banana"} : (f32, i32) -> f32 |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 333 | ``` |
| 334 | |
| 335 | In addition to the basic syntax above, dialects may register known operations. |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 336 | This allows those dialects to support *custom assembly form* for parsing and |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 337 | printing operations. In the operation sets listed below, we show both forms. |
| 338 | |
River Riddle | caddfbd | 2021-03-20 01:19:16 | [diff] [blame] | 339 | ### Builtin Operations |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 340 | |
River Riddle | caddfbd | 2021-03-20 01:19:16 | [diff] [blame] | 341 | The [builtin dialect](Dialects/Builtin.md) defines a select few operations that |
| 342 | are widely applicable by MLIR dialects, such as a universal conversion cast |
| 343 | operation that simplifies inter/intra dialect conversion. This dialect also |
| 344 | defines a top-level `module` operation, that represents a useful IR container. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 345 | |
| 346 | ## Blocks |
| 347 | |
| 348 | Syntax: |
| 349 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 350 | ``` |
River Riddle | 31b3e22 | 2019-12-04 20:05:52 | [diff] [blame] | 351 | block ::= block-label operation+ |
| 352 | block-label ::= block-id block-arg-list? `:` |
| 353 | block-id ::= caret-id |
| 354 | caret-id ::= `^` suffix-id |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 355 | value-id-and-type ::= value-id `:` type |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 356 | |
| 357 | // Non-empty list of names and types. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 358 | value-id-and-type-list ::= value-id-and-type (`,` value-id-and-type)* |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 359 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 360 | block-arg-list ::= `(` value-id-and-type-list? `)` |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 361 | ``` |
| 362 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 363 | A *Block* is a list of operations. In |
| 364 | [SSACFG regions](#control-flow-and-ssacfg-regions), each block represents a |
| 365 | compiler [basic block](https://en.wikipedia.org/wiki/Basic_block) where |
| 366 | instructions inside the block are executed in order and terminator operations |
| 367 | implement control flow branches between basic blocks. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 368 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 369 | A region with a single block may not include a |
| 370 | [terminator operation](#terminator-operations). The enclosing op can opt-out of |
| 371 | this requirement with the `NoTerminator` trait. The top-level `ModuleOp` is an |
| 372 | example of such operation which defined this trait and whose block body does not |
| 373 | have a terminator. |
Mehdi Amini | 973ddb7 | 2021-03-11 23:58:02 | [diff] [blame] | 374 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 375 | Blocks in MLIR take a list of block arguments, notated in a function-like way. |
| 376 | Block arguments are bound to values specified by the semantics of individual |
| 377 | operations. Block arguments of the entry block of a region are also arguments to |
| 378 | the region and the values bound to these arguments are determined by the |
| 379 | semantics of the containing operation. Block arguments of other blocks are |
| 380 | determined by the semantics of terminator operations, e.g. Branches, which have |
| 381 | the block as a successor. In regions with |
| 382 | [control flow](#control-flow-and-ssacfg-regions), MLIR leverages this structure |
| 383 | to implicitly represent the passage of control-flow dependent values without the |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 384 | complex nuances of PHI nodes in traditional SSA representations. Note that |
| 385 | values which are not control-flow dependent can be referenced directly and do |
| 386 | not need to be passed through block arguments. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 387 | |
| 388 | Here is a simple example function showing branches, returns, and block |
| 389 | arguments: |
| 390 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 391 | ```mlir |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 392 | func @simple(i64, i1) -> i64 { |
| 393 | ^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a |
River Riddle | ace0160 | 2022-02-04 04:59:43 | [diff] [blame] | 394 | cf.cond_br %cond, ^bb1, ^bb2 |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 395 | |
| 396 | ^bb1: |
River Riddle | ace0160 | 2022-02-04 04:59:43 | [diff] [blame] | 397 | cf.br ^bb3(%a: i64) // Branch passes %a as the argument |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 398 | |
| 399 | ^bb2: |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 400 | %b = arith.addi %a, %a : i64 |
River Riddle | ace0160 | 2022-02-04 04:59:43 | [diff] [blame] | 401 | cf.br ^bb3(%b: i64) // Branch passes %b as the argument |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 402 | |
| 403 | // ^bb3 receives an argument, named %c, from predecessors |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 404 | // and passes it on to bb4 along with %a. %a is referenced |
| 405 | // directly from its defining operation and is not passed through |
| 406 | // an argument of ^bb3. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 407 | ^bb3(%c: i64): |
River Riddle | ace0160 | 2022-02-04 04:59:43 | [diff] [blame] | 408 | cf.br ^bb4(%c, %a : i64, i64) |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 409 | |
| 410 | ^bb4(%d : i64, %e : i64): |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 411 | %0 = arith.addi %d, %e : i64 |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 412 | return %0 : i64 // Return is also a terminator. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 413 | } |
| 414 | ``` |
| 415 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 416 | **Context:** The "block argument" representation eliminates a number of special |
| 417 | cases from the IR compared to traditional "PHI nodes are operations" SSA IRs |
| 418 | (like LLVM). For example, the |
| 419 | [parallel copy semantics](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.524.5461&rep=rep1&type=pdf) |
| 420 | of SSA is immediately apparent, and function arguments are no longer a special |
| 421 | case: they become arguments to the entry block |
| 422 | [[more rationale](Rationale/Rationale.md/#block-arguments-vs-phi-nodes)]. Blocks |
| 423 | are also a fundamental concept that cannot be represented by operations because |
| 424 | values defined in an operation cannot be accessed outside the operation. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 425 | |
| 426 | ## Regions |
| 427 | |
| 428 | ### Definition |
| 429 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 430 | A region is an ordered list of MLIR [Blocks](#blocks). The semantics within a |
| 431 | region is not imposed by the IR. Instead, the containing operation defines the |
| 432 | semantics of the regions it contains. MLIR currently defines two kinds of |
| 433 | regions: [SSACFG regions](#control-flow-and-ssacfg-regions), which describe |
| 434 | control flow between blocks, and [Graph regions](#graph-regions), which do not |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 435 | require control flow between block. The kinds of regions within an operation are |
| 436 | described using the [RegionKindInterface](Interfaces.md/#regionkindinterfaces). |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 437 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 438 | Regions do not have a name or an address, only the blocks contained in a region |
| 439 | do. Regions must be contained within operations and have no type or attributes. |
| 440 | The first block in the region is a special block called the 'entry block'. The |
| 441 | arguments to the entry block are also the arguments of the region itself. The |
| 442 | entry block cannot be listed as a successor of any other block. The syntax for a |
| 443 | region is as follows: |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 444 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 445 | ``` |
Siddharth Bhat | 24a37a3 | 2022-02-17 10:10:19 | [diff] [blame] | 446 | region ::= `{` entry-block? block* `}` |
| 447 | entry-block ::= operation+ |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 448 | ``` |
| 449 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 450 | A function body is an example of a region: it consists of a CFG of blocks and |
| 451 | has additional semantic restrictions that other types of regions may not have. |
| 452 | For example, in a function body, block terminators must either branch to a |
| 453 | different block, or return from a function where the types of the `return` |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 454 | arguments must match the result types of the function signature. Similarly, the |
| 455 | function arguments must match the types and count of the region arguments. In |
Markus Böck | 286a7a4 | 2021-10-29 07:19:11 | [diff] [blame] | 456 | general, operations with regions can define these correspondences arbitrarily. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 457 | |
Siddharth Bhat | 24a37a3 | 2022-02-17 10:10:19 | [diff] [blame] | 458 | An *entry block* is a block with no label and no arguments that may occur at |
| 459 | the beginning of a region. It enables a common pattern of using a region to |
| 460 | open a new scope. |
| 461 | |
| 462 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 463 | ### Value Scoping |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 464 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 465 | Regions provide hierarchical encapsulation of programs: it is impossible to |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 466 | reference, i.e. branch to, a block which is not in the same region as the source |
| 467 | of the reference, i.e. a terminator operation. Similarly, regions provides a |
| 468 | natural scoping for value visibility: values defined in a region don't escape to |
| 469 | the enclosing region, if any. By default, operations inside a region can |
| 470 | reference values defined outside of the region whenever it would have been legal |
| 471 | for operands of the enclosing operation to reference those values, but this can |
| 472 | be restricted using traits, such as |
Markus Böck | d35bd98 | 2021-05-24 16:40:39 | [diff] [blame] | 473 | [OpTrait::IsolatedFromAbove](Traits.md/#isolatedfromabove), or a custom |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 474 | verifier. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 475 | |
| 476 | Example: |
| 477 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 478 | ```mlir |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 479 | "any_op"(%a) ({ // if %a is in-scope in the containing region... |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 480 | // then %a is in-scope here too. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 481 | %new_value = "another_op"(%a) : (i64) -> (i64) |
| 482 | }) : (i64) -> (i64) |
| 483 | ``` |
| 484 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 485 | MLIR defines a generalized 'hierarchical dominance' concept that operates across |
| 486 | hierarchy and defines whether a value is 'in scope' and can be used by a |
| 487 | particular operation. Whether a value can be used by another operation in the |
| 488 | same region is defined by the kind of region. A value defined in a region can be |
| 489 | used by an operation which has a parent in the same region, if and only if the |
| 490 | parent could use the value. A value defined by an argument to a region can |
| 491 | always be used by any operation deeply contained in the region. A value defined |
| 492 | in a region can never be used outside of the region. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 493 | |
| 494 | ### Control Flow and SSACFG Regions |
| 495 | |
| 496 | In MLIR, control flow semantics of a region is indicated by |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 497 | [RegionKind::SSACFG](Interfaces.md/#regionkindinterfaces). Informally, these |
| 498 | regions support semantics where operations in a region 'execute sequentially'. |
| 499 | Before an operation executes, its operands have well-defined values. After an |
| 500 | operation executes, the operands have the same values and results also have |
| 501 | well-defined values. After an operation executes, the next operation in the |
| 502 | block executes until the operation is the terminator operation at the end of a |
| 503 | block, in which case some other operation will execute. The determination of the |
| 504 | next instruction to execute is the 'passing of control flow'. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 505 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 506 | In general, when control flow is passed to an operation, MLIR does not restrict |
| 507 | when control flow enters or exits the regions contained in that operation. |
| 508 | However, when control flow enters a region, it always begins in the first block |
| 509 | of the region, called the *entry* block. Terminator operations ending each block |
| 510 | represent control flow by explicitly specifying the successor blocks of the |
| 511 | block. Control flow can only pass to one of the specified successor blocks as in |
| 512 | a `branch` operation, or back to the containing operation as in a `return` |
| 513 | operation. Terminator operations without successors can only pass control back |
| 514 | to the containing operation. Within these restrictions, the particular semantics |
| 515 | of terminator operations is determined by the specific dialect operations |
| 516 | involved. Blocks (other than the entry block) that are not listed as a successor |
| 517 | of a terminator operation are defined to be unreachable and can be removed |
| 518 | without affecting the semantics of the containing operation. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 519 | |
| 520 | Although control flow always enters a region through the entry block, control |
| 521 | flow may exit a region through any block with an appropriate terminator. The |
| 522 | standard dialect leverages this capability to define operations with |
| 523 | Single-Entry-Multiple-Exit (SEME) regions, possibly flowing through different |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 524 | blocks in the region and exiting through any block with a `return` operation. |
| 525 | This behavior is similar to that of a function body in most programming |
| 526 | languages. In addition, control flow may also not reach the end of a block or |
| 527 | region, for example if a function call does not return. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 528 | |
| 529 | Example: |
| 530 | |
| 531 | ```mlir |
| 532 | func @accelerator_compute(i64, i1) -> i64 { // An SSACFG region |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 533 | ^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a |
River Riddle | ace0160 | 2022-02-04 04:59:43 | [diff] [blame] | 534 | cf.cond_br %cond, ^bb1, ^bb2 |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 535 | |
| 536 | ^bb1: |
| 537 | // This def for %value does not dominate ^bb2 |
| 538 | %value = "op.convert"(%a) : (i64) -> i64 |
River Riddle | ace0160 | 2022-02-04 04:59:43 | [diff] [blame] | 539 | cf.br ^bb3(%a: i64) // Branch passes %a as the argument |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 540 | |
| 541 | ^bb2: |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 542 | accelerator.launch() { // An SSACFG region |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 543 | ^bb0: |
Kazuaki Ishizaki | a2bce65 | 2019-09-25 18:57:13 | [diff] [blame] | 544 | // Region of code nested under "accelerator.launch", it can reference %a but |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 545 | // not %value. |
| 546 | %new_value = "accelerator.do_something"(%a) : (i64) -> () |
| 547 | } |
| 548 | // %new_value cannot be referenced outside of the region |
Kazuaki Ishizaki | a2bce65 | 2019-09-25 18:57:13 | [diff] [blame] | 549 | |
| 550 | ^bb3: |
| 551 | ... |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 552 | } |
| 553 | ``` |
| 554 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 555 | #### Operations with Multiple Regions |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 556 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 557 | An operation containing multiple regions also completely determines the |
| 558 | semantics of those regions. In particular, when control flow is passed to an |
| 559 | operation, it may transfer control flow to any contained region. When control |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 560 | flow exits a region and is returned to the containing operation, the containing |
| 561 | operation may pass control flow to any region in the same operation. An |
| 562 | operation may also pass control flow to multiple contained regions concurrently. |
| 563 | An operation may also pass control flow into regions that were specified in |
| 564 | other operations, in particular those that defined the values or symbols the |
| 565 | given operation uses as in a call operation. This passage of control is |
| 566 | generally independent of passage of control flow through the basic blocks of the |
| 567 | containing region. |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 568 | |
| 569 | #### Closure |
| 570 | |
| 571 | Regions allow defining an operation that creates a closure, for example by |
| 572 | “boxing” the body of the region into a value they produce. It remains up to the |
| 573 | operation to define its semantics. Note that if an operation triggers |
| 574 | asynchronous execution of the region, it is under the responsibility of the |
| 575 | operation caller to wait for the region to be executed guaranteeing that any |
| 576 | directly used values remain live. |
| 577 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 578 | ### Graph Regions |
| 579 | |
| 580 | In MLIR, graph-like semantics in a region is indicated by |
Markus Böck | d35bd98 | 2021-05-24 16:40:39 | [diff] [blame] | 581 | [RegionKind::Graph](Interfaces.md/#regionkindinterfaces). Graph regions are |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 582 | appropriate for concurrent semantics without control flow, or for modeling |
| 583 | generic directed graph data structures. Graph regions are appropriate for |
| 584 | representing cyclic relationships between coupled values where there is no |
| 585 | fundamental order to the relationships. For instance, operations in a graph |
| 586 | region may represent independent threads of control with values representing |
| 587 | streams of data. As usual in MLIR, the particular semantics of a region is |
| 588 | completely determined by its containing operation. Graph regions may only |
| 589 | contain a single basic block (the entry block). |
| 590 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 591 | **Rationale:** Currently graph regions are arbitrarily limited to a single basic |
| 592 | block, although there is no particular semantic reason for this limitation. This |
| 593 | limitation has been added to make it easier to stabilize the pass infrastructure |
| 594 | and commonly used passes for processing graph regions to properly handle |
| 595 | feedback loops. Multi-block regions may be allowed in the future if use cases |
| 596 | that require it arise. |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 597 | |
| 598 | In graph regions, MLIR operations naturally represent nodes, while each MLIR |
| 599 | value represents a multi-edge connecting a single source node and multiple |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 600 | destination nodes. All values defined in the region as results of operations are |
| 601 | in scope within the region and can be accessed by any other operation in the |
| 602 | region. In graph regions, the order of operations within a block and the order |
| 603 | of blocks in a region is not semantically meaningful and non-terminator |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 604 | operations may be freely reordered, for instance, by canonicalization. Other |
| 605 | kinds of graphs, such as graphs with multiple source nodes and multiple |
| 606 | destination nodes, can also be represented by representing graph edges as MLIR |
| 607 | operations. |
| 608 | |
| 609 | Note that cycles can occur within a single block in a graph region, or between |
| 610 | basic blocks. |
| 611 | |
| 612 | ```mlir |
| 613 | "test.graph_region"() ({ // A Graph region |
| 614 | %1 = "op1"(%1, %3) : (i32, i32) -> (i32) // OK: %1, %3 allowed here |
| 615 | %2 = "test.ssacfg_region"() ({ |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 616 | %5 = "op2"(%1, %2, %3, %4) : (i32, i32, i32, i32) -> (i32) // OK: %1, %2, %3, %4 all defined in the containing region |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 617 | }) : () -> (i32) |
| 618 | %3 = "op2"(%1, %4) : (i32, i32) -> (i32) // OK: %4 allowed here |
| 619 | %4 = "op3"(%1) : (i32) -> (i32) |
| 620 | }) : () -> () |
| 621 | ``` |
| 622 | |
River Riddle | f772d2c | 2019-08-23 17:08:42 | [diff] [blame] | 623 | ### Arguments and Results |
| 624 | |
| 625 | The arguments of the first block of a region are treated as arguments of the |
| 626 | region. The source of these arguments is defined by the semantics of the parent |
| 627 | operation. They may correspond to some of the values the operation itself uses. |
| 628 | |
| 629 | Regions produce a (possibly empty) list of values. The operation semantics |
| 630 | defines the relation between the region results and the operation results. |
| 631 | |
River Riddle | 9fc1657 | 2019-08-22 23:43:06 | [diff] [blame] | 632 | ## Type System |
| 633 | |
River Riddle | caddfbd | 2021-03-20 01:19:16 | [diff] [blame] | 634 | Each value in MLIR has a type defined by the type system. MLIR has an open type |
| 635 | system (i.e. there is no fixed list of types), and types may have |
| 636 | application-specific semantics. MLIR dialects may define any number of types |
| 637 | with no restrictions on the abstractions they represent. |
River Riddle | 9fc1657 | 2019-08-22 23:43:06 | [diff] [blame] | 638 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 639 | ``` |
River Riddle | 09f7a55 | 2020-12-04 01:22:29 | [diff] [blame] | 640 | type ::= type-alias | dialect-type | builtin-type |
River Riddle | 9fc1657 | 2019-08-22 23:43:06 | [diff] [blame] | 641 | |
| 642 | type-list-no-parens ::= type (`,` type)* |
| 643 | type-list-parens ::= `(` `)` |
| 644 | | `(` type-list-no-parens `)` |
| 645 | |
Stephen Neuendorffer | 6282886 | 2020-05-15 17:33:13 | [diff] [blame] | 646 | // This is a common way to refer to a value with a specified type. |
River Riddle | 9fc1657 | 2019-08-22 23:43:06 | [diff] [blame] | 647 | ssa-use-and-type ::= ssa-use `:` type |
| 648 | |
| 649 | // Non-empty list of names and types. |
| 650 | ssa-use-and-type-list ::= ssa-use-and-type (`,` ssa-use-and-type)* |
| 651 | ``` |
| 652 | |
| 653 | ### Type Aliases |
| 654 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 655 | ``` |
River Riddle | 9fc1657 | 2019-08-22 23:43:06 | [diff] [blame] | 656 | type-alias-def ::= '!' alias-name '=' 'type' type |
| 657 | type-alias ::= '!' alias-name |
| 658 | ``` |
| 659 | |
| 660 | MLIR supports defining named aliases for types. A type alias is an identifier |
| 661 | that can be used in the place of the type that it defines. These aliases *must* |
| 662 | be defined before their uses. Alias names may not contain a '.', since those |
| 663 | names are reserved for [dialect types](#dialect-types). |
| 664 | |
| 665 | Example: |
| 666 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 667 | ```mlir |
River Riddle | 9fc1657 | 2019-08-22 23:43:06 | [diff] [blame] | 668 | !avx_m128 = type vector<4 x f32> |
| 669 | |
| 670 | // Using the original type. |
| 671 | "foo"(%x) : vector<4 x f32> -> () |
| 672 | |
| 673 | // Using the type alias. |
| 674 | "foo"(%x) : !avx_m128 -> () |
| 675 | ``` |
| 676 | |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 677 | ### Dialect Types |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 678 | |
| 679 | Similarly to operations, dialects may define custom extensions to the type |
River Riddle | 9fc1657 | 2019-08-22 23:43:06 | [diff] [blame] | 680 | system. |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 681 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 682 | ``` |
Andrew Anderson | a50f871 | 2019-11-26 01:53:20 | [diff] [blame] | 683 | dialect-namespace ::= bare-id |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 684 | |
Andrew Anderson | a50f871 | 2019-11-26 01:53:20 | [diff] [blame] | 685 | opaque-dialect-item ::= dialect-namespace '<' string-literal '>' |
| 686 | |
| 687 | pretty-dialect-item ::= dialect-namespace '.' pretty-dialect-item-lead-ident |
| 688 | pretty-dialect-item-body? |
| 689 | |
| 690 | pretty-dialect-item-lead-ident ::= '[A-Za-z][A-Za-z0-9._]*' |
| 691 | pretty-dialect-item-body ::= '<' pretty-dialect-item-contents+ '>' |
| 692 | pretty-dialect-item-contents ::= pretty-dialect-item-body |
| 693 | | '(' pretty-dialect-item-contents+ ')' |
| 694 | | '[' pretty-dialect-item-contents+ ']' |
| 695 | | '{' pretty-dialect-item-contents+ '}' |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 696 | | '[^[<({>\])}\0]+' |
Andrew Anderson | a50f871 | 2019-11-26 01:53:20 | [diff] [blame] | 697 | |
| 698 | dialect-type ::= '!' opaque-dialect-item |
| 699 | dialect-type ::= '!' pretty-dialect-item |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 700 | ``` |
| 701 | |
| 702 | Dialect types can be specified in a verbose form, e.g. like this: |
| 703 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 704 | ```mlir |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 705 | // LLVM type that wraps around llvm IR types. |
| 706 | !llvm<"i32*"> |
| 707 | |
| 708 | // Tensor flow string type. |
| 709 | !tf.string |
| 710 | |
| 711 | // Complex type |
| 712 | !foo<"something<abcd>"> |
| 713 | |
| 714 | // Even more complex type |
| 715 | !foo<"something<a%%123^^^>>>"> |
| 716 | ``` |
| 717 | |
| 718 | Dialect types that are simple enough can use the pretty format, which is a |
| 719 | lighter weight syntax that is equivalent to the above forms: |
| 720 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 721 | ```mlir |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 722 | // Tensor flow string type. |
| 723 | !tf.string |
| 724 | |
| 725 | // Complex type |
| 726 | !foo.something<abcd> |
| 727 | ``` |
| 728 | |
| 729 | Sufficiently complex dialect types are required to use the verbose form for |
| 730 | generality. For example, the more complex type shown above wouldn't be valid in |
| 731 | the lighter syntax: `!foo.something<a%%123^^^>>>` because it contains characters |
| 732 | that are not allowed in the lighter syntax, as well as unbalanced `<>` |
| 733 | characters. |
| 734 | |
River Riddle | caddfbd | 2021-03-20 01:19:16 | [diff] [blame] | 735 | See [here](Tutorials/DefiningAttributesAndTypes.md) to learn how to define |
| 736 | dialect types. |
River Riddle | 986f930 | 2019-08-22 22:53:41 | [diff] [blame] | 737 | |
River Riddle | 09f7a55 | 2020-12-04 01:22:29 | [diff] [blame] | 738 | ### Builtin Types |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 739 | |
River Riddle | caddfbd | 2021-03-20 01:19:16 | [diff] [blame] | 740 | The [builtin dialect](Dialects/Builtin.md) defines a set of types that are |
| 741 | directly usable by any other dialect in MLIR. These types cover a range from |
| 742 | primitive integer and floating-point types, function types, and more. |
River Riddle | 1316db3 | 2019-04-28 01:35:04 | [diff] [blame] | 743 | |
River Riddle | 465ef55 | 2019-04-05 15:19:42 | [diff] [blame] | 744 | ## Attributes |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 745 | |
| 746 | Syntax: |
| 747 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 748 | ``` |
Sean Silva | 6b07a97 | 2021-02-05 00:17:45 | [diff] [blame] | 749 | attribute-entry ::= (bare-id | string-literal) `=` attribute-value |
| 750 | attribute-value ::= attribute-alias | dialect-attribute | builtin-attribute |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 751 | ``` |
| 752 | |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 753 | Attributes are the mechanism for specifying constant data on operations in |
Sean Silva | 042db54 | 2021-02-04 21:27:25 | [diff] [blame] | 754 | places where a variable is never allowed - e.g. the comparison predicate of a |
Sean Silva | 6b07a97 | 2021-02-05 00:17:45 | [diff] [blame] | 755 | [`cmpi` operation](Dialects/Standard.md#stdcmpi-cmpiop). Each operation has an |
| 756 | attribute dictionary, which associates a set of attribute names to attribute |
| 757 | values. MLIR's builtin dialect provides a rich set of |
| 758 | [builtin attribute values](#builtin-attribute-values) out of the box (such as |
| 759 | arrays, dictionaries, strings, etc.). Additionally, dialects can define their |
| 760 | own [dialect attribute values](#dialect-attribute-values). |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 761 | |
Sean Silva | 6b07a97 | 2021-02-05 00:17:45 | [diff] [blame] | 762 | The top-level attribute dictionary attached to an operation has special |
| 763 | semantics. The attribute entries are considered to be of two different kinds |
| 764 | based on whether their dictionary key has a dialect prefix: |
River Riddle | a495f96 | 2019-03-03 06:34:18 | [diff] [blame] | 765 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 766 | - *inherent attributes* are inherent to the definition of an operation's |
| 767 | semantics. The operation itself is expected to verify the consistency of |
| 768 | these attributes. An example is the `predicate` attribute of the |
| 769 | `arith.cmpi` op. These attributes must have names that do not start with a |
| 770 | dialect prefix. |
Alex Zinenko | 1321f6a | 2018-10-24 16:47:36 | [diff] [blame] | 771 | |
Mogball | a54f4ea | 2021-10-12 23:14:57 | [diff] [blame] | 772 | - *discardable attributes* have semantics defined externally to the operation |
| 773 | itself, but must be compatible with the operations's semantics. These |
| 774 | attributes must have names that start with a dialect prefix. The dialect |
| 775 | indicated by the dialect prefix is expected to verify these attributes. An |
| 776 | example is the `gpu.container_module` attribute. |
Sean Silva | 6b07a97 | 2021-02-05 00:17:45 | [diff] [blame] | 777 | |
| 778 | Note that attribute values are allowed to themselves be dictionary attributes, |
| 779 | but only the top-level dictionary attribute attached to the operation is subject |
| 780 | to the classification above. |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 781 | |
| 782 | ### Attribute Value Aliases |
| 783 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 784 | ``` |
Sean Silva | 042db54 | 2021-02-04 21:27:25 | [diff] [blame] | 785 | attribute-alias-def ::= '#' alias-name '=' attribute-value |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 786 | attribute-alias ::= '#' alias-name |
| 787 | ``` |
| 788 | |
| 789 | MLIR supports defining named aliases for attribute values. An attribute alias is |
| 790 | an identifier that can be used in the place of the attribute that it defines. |
| 791 | These aliases *must* be defined before their uses. Alias names may not contain a |
| 792 | '.', since those names are reserved for |
| 793 | [dialect attributes](#dialect-attribute-values). |
| 794 | |
| 795 | Example: |
| 796 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 797 | ```mlir |
River Riddle | 4268e4f | 2020-01-13 21:12:37 | [diff] [blame] | 798 | #map = affine_map<(d0) -> (d0 + 10)> |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 799 | |
| 800 | // Using the original attribute. |
River Riddle | 4268e4f | 2020-01-13 21:12:37 | [diff] [blame] | 801 | %b = affine.apply affine_map<(d0) -> (d0 + 10)> (%a) |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 802 | |
| 803 | // Using the attribute alias. |
| 804 | %b = affine.apply #map(%a) |
| 805 | ``` |
| 806 | |
| 807 | ### Dialect Attribute Values |
| 808 | |
Andrew Anderson | a50f871 | 2019-11-26 01:53:20 | [diff] [blame] | 809 | Similarly to operations, dialects may define custom attribute values. The |
| 810 | syntactic structure of these values is identical to custom dialect type values, |
Uday Bondhugula | b276bf5 | 2020-12-02 20:42:01 | [diff] [blame] | 811 | except that dialect attribute values are distinguished with a leading '#', while |
| 812 | dialect types are distinguished with a leading '!'. |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 813 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 814 | ``` |
Uday Bondhugula | b276bf5 | 2020-12-02 20:42:01 | [diff] [blame] | 815 | dialect-attribute-value ::= '#' opaque-dialect-item |
| 816 | dialect-attribute-value ::= '#' pretty-dialect-item |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 817 | ``` |
| 818 | |
Uday Bondhugula | b276bf5 | 2020-12-02 20:42:01 | [diff] [blame] | 819 | Dialect attribute values can be specified in a verbose form, e.g. like this: |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 820 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 821 | ```mlir |
Uday Bondhugula | b276bf5 | 2020-12-02 20:42:01 | [diff] [blame] | 822 | // Complex attribute value. |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 823 | #foo<"something<abcd>"> |
| 824 | |
Uday Bondhugula | b276bf5 | 2020-12-02 20:42:01 | [diff] [blame] | 825 | // Even more complex attribute value. |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 826 | #foo<"something<a%%123^^^>>>"> |
| 827 | ``` |
| 828 | |
Uday Bondhugula | b276bf5 | 2020-12-02 20:42:01 | [diff] [blame] | 829 | Dialect attribute values that are simple enough can use the pretty format, which |
| 830 | is a lighter weight syntax that is equivalent to the above forms: |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 831 | |
Alex Zinenko | ac48733 | 2019-12-10 11:00:29 | [diff] [blame] | 832 | ```mlir |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 833 | // Complex attribute |
| 834 | #foo.something<abcd> |
| 835 | ``` |
| 836 | |
Uday Bondhugula | b276bf5 | 2020-12-02 20:42:01 | [diff] [blame] | 837 | Sufficiently complex dialect attribute values are required to use the verbose |
| 838 | form for generality. For example, the more complex type shown above would not be |
| 839 | valid in the lighter syntax: `#foo.something<a%%123^^^>>>` because it contains |
| 840 | characters that are not allowed in the lighter syntax, as well as unbalanced |
| 841 | `<>` characters. |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 842 | |
Uday Bondhugula | b276bf5 | 2020-12-02 20:42:01 | [diff] [blame] | 843 | See [here](Tutorials/DefiningAttributesAndTypes.md) on how to define dialect |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 844 | attribute values. |
| 845 | |
River Riddle | c7cae0e | 2020-12-04 01:22:57 | [diff] [blame] | 846 | ### Builtin Attribute Values |
River Riddle | fc86c57 | 2019-08-23 00:51:06 | [diff] [blame] | 847 | |
River Riddle | caddfbd | 2021-03-20 01:19:16 | [diff] [blame] | 848 | The [builtin dialect](Dialects/Builtin.md) defines a set of attribute values |
| 849 | that are directly usable by any other dialect in MLIR. These types cover a range |
| 850 | from primitive integer and floating-point values, attribute dictionaries, dense |
| 851 | multi-dimensional arrays, and more. |