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