xref: /llvm-project-15.0.7/mlir/docs/LangRef.md (revision 8a42bf24)
1# MLIR Specification
2
3MLIR (Multi-Level IR) is a compiler intermediate representation with
4similarities to traditional three-address SSA representations (like
5[LLVM IR](http://llvm.org/docs/LangRef.html) or
6[SIL](https://github.com/apple/swift/blob/master/docs/SIL.rst)), but which
7introduces notions from polyhedral loop optimization as first-class concepts.
8This hybrid design is optimized to represent, analyze, and transform high level
9dataflow graphs as well as target-specific code generated for high performance
10data parallel systems. Beyond its representational capabilities, its single
11continuous design provides a framework to lower from dataflow graphs to
12high-performance target-specific code.
13
14This document defines and describes the key concepts in MLIR, and is intended to
15be a dry reference document - the [rationale documentation](Rationale.md),
16[glossary](../getting_started/Glossary.md), and other content are hosted elsewhere.
17
18MLIR is designed to be used in three different forms: a human-readable textual
19form suitable for debugging, an in-memory form suitable for programmatic
20transformations and analysis, and a compact serialized form suitable for storage
21and transport. The different forms all describe the same semantic content. This
22document describes the human-readable textual form.
23
24[TOC]
25
26## High-Level Structure
27
28MLIR is an
29[SSA-based](https://en.wikipedia.org/wiki/Static_single_assignment_form) IR,
30which means that values are defined before use and have scope defined by their
31dominance relations. Operations may produce zero or more results, and each is a
32distinct SSA value with its own type defined by the [type system](#type-system).
33
34The unit of code in MLIR is an [Operation](#operations). Operations allow for
35representing many different concepts: allocating buffers, producing views to
36transform them, target-independent arithmetic, target-specific operations, and
37even arbitrary user-defined high-level operations including the
38[Module](#module) and [Function](#functions) operations. Operations may contain
39[Regions](#regions) that represent a Control Flow Graph (CFG) of
40[Blocks](#blocks), that contain operations and end with a
41[terminator operation](#terminator-operations) (like branches).
42
43Here's an example of an MLIR module:
44
45```mlir
46// Compute A*B using an implementation of multiply kernel and print the
47// result using a TensorFlow op. The dimensions of A and B are partially
48// known. The shapes are assumed to match.
49func @mul(%A: tensor<100x?xf32>, %B: tensor<?x50xf32>) -> (tensor<100x50xf32>) {
50  // Compute the inner dimension of %A using the dim operation.
51  %n = dim %A, 1 : tensor<100x?xf32>
52
53  // Allocate addressable "buffers" and copy tensors %A and %B into them.
54  %A_m = alloc(%n) : memref<100x?xf32>
55  tensor_store %A to %A_m : memref<100x?xf32>
56
57  %B_m = alloc(%n) : memref<?x50xf32>
58  tensor_store %B to %B_m : memref<?x50xf32>
59
60  // Call function @multiply passing memrefs as arguments,
61  // and getting returned the result of the multiplication.
62  %C_m = call @multiply(%A_m, %B_m)
63          : (memref<100x?xf32>, memref<?x50xf32>) -> (memref<100x50xf32>)
64
65  dealloc %A_m : memref<100x?xf32>
66  dealloc %B_m : memref<?x50xf32>
67
68  // Load the buffer data into a higher level "tensor" value.
69  %C = tensor_load %C_m : memref<100x50xf32>
70  dealloc %C_m : memref<100x50xf32>
71
72  // Call TensorFlow built-in function to print the result tensor.
73  "tf.Print"(%C){message: "mul result"}
74                  : (tensor<100x50xf32) -> (tensor<100x50xf32>)
75
76  return %C : tensor<100x50xf32>
77}
78
79// A function that multiplies two memrefs and returns the result.
80func @multiply(%A: memref<100x?xf32>, %B: memref<?x50xf32>)
81          -> (memref<100x50xf32>)  {
82  // Compute the inner dimension of %A.
83  %n = dim %A, 1 : memref<100x?xf32>
84
85  // Allocate memory for the multiplication result.
86  %C = alloc() : memref<100x50xf32>
87
88  // Multiplication loop nest.
89  affine.for %i = 0 to 100 {
90     affine.for %j = 0 to 50 {
91        store 0 to %C[%i, %j] : memref<100x50xf32>
92        affine.for %k = 0 to %n {
93           %a_v  = load %A[%i, %k] : memref<100x?xf32>
94           %b_v  = load %B[%k, %j] : memref<?x50xf32>
95           %prod = mulf %a_v, %b_v : f32
96           %c_v  = load %C[%i, %j] : memref<100x50xf32>
97           %sum  = addf %c_v, %prod : f32
98           store %sum, %C[%i, %j] : memref<100x50xf32>
99        }
100     }
101  }
102  return %C : memref<100x50xf32>
103}
104```
105
106## Notation
107
108MLIR has a simple and unambiguous grammar, allowing it to reliably round-trip
109through a textual form. This is important for development of the compiler - e.g.
110for understanding the state of code as it is being transformed and writing test
111cases.
112
113This document describes the grammar using
114[Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form).
115
116This is the EBNF grammar used in this document, presented in yellow boxes.
117
118```
119alternation ::= expr0 | expr1 | expr2  // Either expr0 or expr1 or expr2.
120sequence    ::= expr0 expr1 expr2      // Sequence of expr0 expr1 expr2.
121repetition0 ::= expr*  // 0 or more occurrences.
122repetition1 ::= expr+  // 1 or more occurrences.
123optionality ::= expr?  // 0 or 1 occurrence.
124grouping    ::= (expr) // Everything inside parens is grouped together.
125literal     ::= `abcd` // Matches the literal `abcd`.
126```
127
128Code examples are presented in blue boxes.
129
130```mlir
131// This is an example use of the grammar above:
132// This matches things like: ba, bana, boma, banana, banoma, bomana...
133example ::= `b` (`an` | `om`)* `a`
134```
135
136### Common syntax
137
138The following core grammar productions are used in this document:
139
140```
141// TODO: Clarify the split between lexing (tokens) and parsing (grammar).
142digit     ::= [0-9]
143hex_digit ::= [0-9a-fA-F]
144letter    ::= [a-zA-Z]
145id-punct  ::= [$._-]
146
147integer-literal ::= decimal-literal | hexadecimal-literal
148decimal-literal ::= digit+
149hexadecimal-literal ::= `0x` hex_digit+
150float-literal ::= [-+]?[0-9]+[.][0-9]*([eE][-+]?[0-9]+)?
151string-literal  ::= `"` [^"\n\f\v\r]* `"`   TODO define escaping rules
152```
153
154Not listed here, but MLIR does support comments. They use standard BCPL syntax,
155starting with a `//` and going until the end of the line.
156
157### Identifiers and keywords
158
159Syntax:
160
161```
162// Identifiers
163bare-id ::= (letter|[_]) (letter|digit|[_$.])*
164bare-id-list ::= bare-id (`,` bare-id)*
165ssa-id ::= `%` suffix-id
166suffix-id ::= (digit+ | ((letter|id-punct) (letter|id-punct|digit)*))
167
168symbol-ref-id ::= `@` (suffix-id | string-literal)
169ssa-id-list ::= ssa-id (`,` ssa-id)*
170
171// Uses of an SSA value, e.g. in an operand list to an operation.
172ssa-use ::= ssa-id
173ssa-use-list ::= ssa-use (`,` ssa-use)*
174```
175
176Identifiers name entities such as SSA values, types and functions, and are
177chosen by the writer of MLIR code. Identifiers may be descriptive (e.g.
178`%batch_size`, `@matmul`), or may be non-descriptive when they are
179auto-generated (e.g. `%23`, `@func42`). Identifier names for SSA values may be
180used in an MLIR text file but are not persisted as part of the IR - the printer
181will give them anonymous names like `%42`.
182
183MLIR guarantees identifiers never collide with keywords by prefixing identifiers
184with a sigil (e.g. `%`, `#`, `@`, `^`, `!`). In certain unambiguous contexts
185(e.g. affine expressions), identifiers are not prefixed, for brevity. New
186keywords may be added to future versions of MLIR without danger of collision
187with existing identifiers.
188
189The scope of SSA values is defined based on the standard definition of
190[dominance](https://en.wikipedia.org/wiki/Dominator_\(graph_theory\)). Argument
191identifiers in mapping functions are in scope for the mapping body. Function
192identifiers and mapping identifiers are visible across the entire module.
193
194## Dialects
195
196Dialects are the mechanism by which to engage with and extend the MLIR
197ecosystem. They allow for defining new [operations](#operations), as well as
198[attributes](#attributes) and [types](#type-system). Each dialect is given a
199unique `namespace` that is prefixed to each defined attribute/operation/type.
200For example, the [Affine dialect](Dialects/Affine.md) defines the namespace:
201`affine`.
202
203MLIR allows for multiple dialects, even those outside of the main tree, to
204co-exist together within one module. Dialects are produced and consumed by
205certain passes. MLIR provides a [framework](DialectConversion.md) to convert
206between, and within, different dialects.
207
208A few of the dialects supported by MLIR:
209
210*   [Affine dialect](Dialects/Affine.md)
211*   [GPU dialect](Dialects/GPU.md)
212*   [LLVM dialect](Dialects/LLVM.md)
213*   [SPIR-V dialect](Dialects/SPIR-V.md)
214*   [Standard dialect](Dialects/Standard.md)
215*   [Vector dialect](Dialects/Vector.md)
216
217### Target specific operations
218
219Dialects provide a modular way in which targets can expose target-specific
220operations directly through to MLIR. As an example, some targets go through
221LLVM. LLVM has a rich set of intrinsics for certain target-independent
222operations (e.g. addition with overflow check) as well as providing access to
223target-specific operations for the targets it supports (e.g. vector permutation
224operations). LLVM intrinsics in MLIR are represented via operations that start
225with an "llvm." name.
226
227Example:
228
229```mlir
230// LLVM: %x = call {i16, i1} @llvm.sadd.with.overflow.i16(i16 %a, i16 %b)
231%x:2 = "llvm.sadd.with.overflow.i16"(%a, %b) : (i16, i16) -> (i16, i1)
232```
233
234These operations only work when targeting LLVM as a backend (e.g. for CPUs and
235GPUs), and are required to align with the LLVM definition of these intrinsics.
236
237## Operations
238
239Syntax:
240
241```
242operation         ::= op-result-list? (generic-operation | custom-operation)
243                      trailing-location?
244generic-operation ::= string-literal `(` ssa-use-list? `)`  successor-list?
245                      (`(` region-list `)`)? attribute-dict? `:` function-type
246custom-operation  ::= bare-id custom-operation-format
247op-result-list    ::= op-result (`,` op-result)* `=`
248op-result         ::= ssa-id (`:` integer-literal)
249successor-list    ::= successor (`,` successor)*
250successor         ::= caret-id (`:` bb-arg-list)?
251region-list       ::= region (`,` region)*
252trailing-location ::= (`loc` `(` location `)`)?
253```
254
255MLIR introduces a uniform concept called _operations_ to enable describing many
256different levels of abstractions and computations. Operations in MLIR are fully
257extensible (there is no fixed list of operations) and have application-specific
258semantics. For example, MLIR supports
259[target-independent operations](Dialects/Standard.md#memory-operations),
260[affine operations](Dialects/Affine.md), and
261[target-specific machine operations](#target-specific-operations).
262
263The internal representation of an operation is simple: an operation is
264identified by a unique string (e.g. `dim`, `tf.Conv2d`, `x86.repmovsb`,
265`ppc.eieio`, etc), can return zero or more results, take zero or more SSA
266operands, may have zero or more attributes, may have zero or more successors,
267and zero or more enclosed [regions](#regions). The generic printing form
268includes all these elements literally, with a function type to indicate the
269types of the results and operands.
270
271Example:
272
273```mlir
274// An operation that produces two results.
275// The results of %result can be accessed via the <name> `#` <opNo> syntax.
276%result:2 = "foo_div"() : () -> (f32, i32)
277
278// Pretty form that defines a unique name for each result.
279%foo, %bar = "foo_div"() : () -> (f32, i32)
280
281// Invoke a TensorFlow function called tf.scramble with two inputs
282// and an attribute "fruit".
283%2 = "tf.scramble"(%result#0, %bar) {fruit: "banana"} : (f32, i32) -> f32
284```
285
286In addition to the basic syntax above, dialects may register known operations.
287This allows those dialects to support _custom assembly form_ for parsing and
288printing operations. In the operation sets listed below, we show both forms.
289
290### Terminator Operations
291
292These are a special category of operations that *must* terminate a block, e.g.
293[branches](Dialects/Standard.md#terminator-operations). These operations may
294also have a list of successors ([blocks](#blocks) and their arguments).
295
296Example:
297
298```mlir
299// Branch to ^bb1 or ^bb2 depending on the condition %cond.
300// Pass value %v to ^bb2, but not to ^bb1.
301"cond_br"(%cond)[^bb1, ^bb2(%v : index)] : (i1) -> ()
302```
303
304### Module
305
306```
307module ::= `module` symbol-ref-id? (`attributes` attribute-dict)? region
308```
309
310An MLIR module represents an opaque top-level container operation. It contains a
311single region containing a single block that is comprised of any operations.
312Operations within this region must not implicitly capture values defined above
313it. Modules have an optional symbol name that can be used to refer to them in
314operations.
315
316### Functions
317
318An MLIR Function is an operation with a name containing one [region](#regions).
319The region of a function is not allowed to implicitly capture values defined
320outside of the function, and all external references must use function arguments
321or attributes that establish a symbolic connection (e.g. symbols referenced by
322name via a string attribute like [SymbolRefAttr](#symbol-reference-attribute)):
323
324```
325function ::= `func` function-signature function-attributes? function-body?
326
327function-signature ::= symbol-ref-id `(` argument-list `)`
328                       (`->` function-result-list)?
329
330argument-list ::= (named-argument (`,` named-argument)*) | /*empty*/
331argument-list ::= (type attribute-dict? (`,` type attribute-dict?)*) | /*empty*/
332named-argument ::= ssa-id `:` type attribute-dict?
333
334function-result-list ::= function-result-list-parens
335                       | non-function-type
336function-result-list-parens ::= `(` `)`
337                              | `(` function-result-list-no-parens `)`
338function-result-list-no-parens ::= function-result (`,` function-result)*
339function-result ::= type attribute-dict?
340
341function-attributes ::= `attributes` attribute-dict
342function-body ::= region
343```
344
345An external function declaration (used when referring to a function declared in
346some other module) has no body. While the MLIR textual form provides a nice
347inline syntax for function arguments, they are internally represented as "block
348arguments" to the first block in the region.
349
350Only dialect attribute names may be specified in the attribute dictionaries for
351function arguments, results, or the function itself.
352
353Examples:
354
355```mlir
356// External function definitions.
357func @abort()
358func @scribble(i32, i64, memref<? x 128 x f32, #layout_map0>) -> f64
359
360// A function that returns its argument twice:
361func @count(%x: i64) -> (i64, i64)
362  attributes {fruit: "banana"} {
363  return %x, %x: i64, i64
364}
365
366// A function with an argument attribute
367func @example_fn_arg(%x: i32 {swift.self = unit})
368
369// A function with a result attribute
370func @example_fn_result() -> (f64 {dialectName.attrName = 0 : i64})
371
372// A function with an attribute
373func @example_fn_attr() attributes {dialectName.attrName = false}
374```
375
376## Blocks
377
378Syntax:
379
380```
381block           ::= block-label operation+
382block-label     ::= block-id block-arg-list? `:`
383block-id        ::= caret-id
384caret-id        ::= `^` suffix-id
385ssa-id-and-type ::= ssa-id `:` type
386
387// Non-empty list of names and types.
388ssa-id-and-type-list ::= ssa-id-and-type (`,` ssa-id-and-type)*
389
390block-arg-list ::= `(` ssa-id-and-type-list? `)`
391```
392
393A [block](https://en.wikipedia.org/wiki/Basic_block) is a sequential list of
394operations without control flow (a call or entering an op's region is not
395considered control flow for this purpose) that are executed from top to bottom.
396The last operation in a block is a
397[terminator operation](#terminator-operations), which ends the block.
398
399Blocks in MLIR take a list of block arguments, which represent SSA PHI nodes in
400a functional notation. The arguments are defined by the block, and values are
401provided for these block arguments by branches that go to the block.
402
403Here is a simple example function showing branches, returns, and block
404arguments:
405
406```mlir
407func @simple(i64, i1) -> i64 {
408^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a
409  cond_br %cond, ^bb1, ^bb2
410
411^bb1:
412  br ^bb3(%a: i64)    // Branch passes %a as the argument
413
414^bb2:
415  %b = addi %a, %a : i64
416  br ^bb3(%b: i64)    // Branch passes %b as the argument
417
418// ^bb3 receives an argument, named %c, from predecessors
419// and passes it on to bb4 twice.
420^bb3(%c: i64):
421  br ^bb4(%c, %c : i64, i64)
422
423^bb4(%d : i64, %e : i64):
424  %0 = addi %d, %e : i64
425  return %0 : i64
426}
427```
428
429**Context:** The "block argument" representation eliminates a number of special
430cases from the IR compared to traditional "PHI nodes are operations" SSA IRs
431(like LLVM). For example, the
432[parallel copy semantics](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.524.5461&rep=rep1&type=pdf)
433of SSA is immediately apparent, and function arguments are no longer a special
434case: they become arguments to the entry block
435[[more rationale](Rationale.md#block-arguments-vs-phi-nodes)].
436
437## Regions
438
439### Definition
440
441A region is a CFG of MLIR [Blocks](#blocks). Regions serve to group semantically
442connected blocks, where the semantics is not imposed by the IR. Instead, the
443containing operation defines the semantics of the regions it contains. Regions
444do not have a name or an address, only the blocks contained in a region do.
445Regions are meaningless outside of the containing entity and have no type or
446attributes.
447
448The first block in the region cannot be a successor of any other block. The
449syntax for the region is as follows:
450
451```
452region ::= `{` block* `}`
453```
454
455The function body is an example of a region: it consists of a CFG of blocks and
456has additional semantic restrictions that other types of regions may not have
457(block terminators must either branch to a different block, or return from a
458function where the types of the `return` arguments must match the result types
459of the function signature).
460
461### Control and Value Scoping
462
463Regions provide nested control isolation: it is impossible to branch to a block
464within a region from outside it or to branch from within a region to a block
465outside it. Similarly, it provides a natural scoping for value visibility: SSA
466values defined in a region don't escape to the enclosing region, if any. By
467default, a region can reference values defined outside of the region whenever it
468would have been legal to use them as operands to the enclosing operation.
469
470Example:
471
472```mlir
473func @accelerator_compute(i64, i1) -> i64 {
474^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a
475  cond_br %cond, ^bb1, ^bb2
476
477^bb1:
478  // This def for %value does not dominate ^bb2
479  %value = "op.convert"(%a) : (i64) -> i64
480  br ^bb3(%a: i64)    // Branch passes %a as the argument
481
482^bb2:
483  "accelerator.launch"() {
484    ^bb0:
485      // Region of code nested under "accelerator.launch", it can reference %a but
486      // not %value.
487      %new_value = "accelerator.do_something"(%a) : (i64) -> ()
488  }
489  // %new_value cannot be referenced outside of the region
490
491^bb3:
492  ...
493}
494```
495
496This can be further restricted using the custom verifier associated with the
497enclosing operation, for example, disallowing references to values defined
498outside the region completely.
499
500### Control Flow
501
502Regions are Single-Entry-Multiple-Exit (SEME). This means that control can only
503flow into the first block of the region, but can flow out of the region at the
504end of any of the contained blocks (This behavior is similar to that of a
505function body in most programming languages). A terminator of a block within a
506region may transfer the control flow to another block in this region, or return
507it to the immediately enclosing op. The semantics of the enclosing op defines
508where the control flow is transmitted next. It may, for example, enter a region
509of the same op, including the same region that returned the control flow.
510
511The enclosing operation determines the way in which control is transmitted into
512the entry block of a Region. The successor to a region’s exit points may not
513necessarily exist: for example a call to a function that does not return.
514Concurrent or asynchronous execution of regions is unspecified. Operations may
515define specific rules of execution, e.g. sequential loops or switch cases.
516
517A Region may also enter another region within the enclosing operation. If an
518operation has multiple regions, the semantics of the operation defines into
519which regions the control flows and in which order, if any. An operation may
520transmit control into regions that were specified in other operations, in
521particular those that defined the values the given operation uses. Thus such
522operations can be treated opaquely in the enclosing control flow graph,
523providing a level of control flow isolation similar to that of the call
524operation.
525
526#### Closure
527
528Regions allow defining an operation that creates a closure, for example by
529“boxing” the body of the region into a value they produce. It remains up to the
530operation to define its semantics. Note that if an operation triggers
531asynchronous execution of the region, it is under the responsibility of the
532operation caller to wait for the region to be executed guaranteeing that any
533directly used values remain live.
534
535### Arguments and Results
536
537The arguments of the first block of a region are treated as arguments of the
538region. The source of these arguments is defined by the semantics of the parent
539operation. They may correspond to some of the values the operation itself uses.
540
541Regions produce a (possibly empty) list of values. The operation semantics
542defines the relation between the region results and the operation results.
543
544## Type System
545
546Each SSA value in MLIR has a type defined by the type system below. There are a
547number of primitive types (like integers) and also aggregate types for tensors
548and memory buffers. MLIR [standard types](#standard-types) do not include
549structures, arrays, or dictionaries.
550
551MLIR has an open type system (i.e. there is no fixed list of types), and types
552may have application-specific semantics. For example, MLIR supports a set of
553[dialect types](#dialect-types).
554
555```
556type ::= type-alias | dialect-type | standard-type
557
558type-list-no-parens ::=  type (`,` type)*
559type-list-parens ::= `(` `)`
560                   | `(` type-list-no-parens `)`
561
562// This is a common way to refer to an SSA value with a specified type.
563ssa-use-and-type ::= ssa-use `:` type
564
565// Non-empty list of names and types.
566ssa-use-and-type-list ::= ssa-use-and-type (`,` ssa-use-and-type)*
567```
568
569### Type Aliases
570
571```
572type-alias-def ::= '!' alias-name '=' 'type' type
573type-alias ::= '!' alias-name
574```
575
576MLIR supports defining named aliases for types. A type alias is an identifier
577that can be used in the place of the type that it defines. These aliases *must*
578be defined before their uses. Alias names may not contain a '.', since those
579names are reserved for [dialect types](#dialect-types).
580
581Example:
582
583```mlir
584!avx_m128 = type vector<4 x f32>
585
586// Using the original type.
587"foo"(%x) : vector<4 x f32> -> ()
588
589// Using the type alias.
590"foo"(%x) : !avx_m128 -> ()
591```
592
593### Dialect Types
594
595Similarly to operations, dialects may define custom extensions to the type
596system.
597
598```
599dialect-namespace ::= bare-id
600
601opaque-dialect-item ::= dialect-namespace '<' string-literal '>'
602
603pretty-dialect-item ::= dialect-namespace '.' pretty-dialect-item-lead-ident
604                                              pretty-dialect-item-body?
605
606pretty-dialect-item-lead-ident ::= '[A-Za-z][A-Za-z0-9._]*'
607pretty-dialect-item-body ::= '<' pretty-dialect-item-contents+ '>'
608pretty-dialect-item-contents ::= pretty-dialect-item-body
609                              | '(' pretty-dialect-item-contents+ ')'
610                              | '[' pretty-dialect-item-contents+ ']'
611                              | '{' pretty-dialect-item-contents+ '}'
612                              | '[^[<({>\])}\0]+'
613
614dialect-type ::= '!' opaque-dialect-item
615dialect-type ::= '!' pretty-dialect-item
616```
617
618Dialect types can be specified in a verbose form, e.g. like this:
619
620```mlir
621// LLVM type that wraps around llvm IR types.
622!llvm<"i32*">
623
624// Tensor flow string type.
625!tf.string
626
627// Complex type
628!foo<"something<abcd>">
629
630// Even more complex type
631!foo<"something<a%%123^^^>>>">
632```
633
634Dialect types that are simple enough can use the pretty format, which is a
635lighter weight syntax that is equivalent to the above forms:
636
637```mlir
638// Tensor flow string type.
639!tf.string
640
641// Complex type
642!foo.something<abcd>
643```
644
645Sufficiently complex dialect types are required to use the verbose form for
646generality. For example, the more complex type shown above wouldn't be valid in
647the lighter syntax: `!foo.something<a%%123^^^>>>` because it contains characters
648that are not allowed in the lighter syntax, as well as unbalanced `<>`
649characters.
650
651See [here](DefiningAttributesAndTypes.md) to learn how to define dialect types.
652
653### Standard Types
654
655Standard types are a core set of [dialect types](#dialect-types) that are
656defined in a builtin dialect and thus available to all users of MLIR.
657
658```
659standard-type ::=     complex-type
660                    | float-type
661                    | function-type
662                    | index-type
663                    | integer-type
664                    | memref-type
665                    | none-type
666                    | tensor-type
667                    | tuple-type
668                    | vector-type
669```
670
671#### Complex Type
672
673Syntax:
674
675```
676complex-type ::= `complex` `<` type `>`
677```
678
679The value of `complex` type represents a complex number with a parameterized
680element type, which is composed of a real and imaginary value of that element
681type. The element must be a floating point or integer scalar type.
682
683Examples:
684
685```mlir
686complex<f32>
687complex<i32>
688```
689
690#### Floating Point Types
691
692Syntax:
693
694```
695// Floating point.
696float-type ::= `f16` | `bf16` | `f32` | `f64`
697```
698
699MLIR supports float types of certain widths that are widely used as indicated
700above.
701
702#### Function Type
703
704Syntax:
705
706```
707// MLIR functions can return multiple values.
708function-result-type ::= type-list-parens
709                       | non-function-type
710
711function-type ::= type-list-parens `->` function-result-type
712```
713
714MLIR supports first-class functions: for example, the
715[`constant` operation](Dialects/Standard.md#constant-operation) produces the
716address of a function as an SSA value. This SSA value may be passed to and
717returned from functions, merged across control flow boundaries with
718[block arguments](#blocks), and called with the
719[`call_indirect` operation](Dialects/Standard.md#call-indirect-operation).
720
721Function types are also used to indicate the arguments and results of
722[operations](#operations).
723
724#### Index Type
725
726Syntax:
727
728```
729// Target word-sized integer.
730index-type ::= `index`
731```
732
733The `index` type is a signless integer whose size is equal to the natural
734machine word of the target ([rationale](Rationale.md#signless-types)) and is
735used by the affine constructs in MLIR. Unlike fixed-size integers, it cannot be
736used as an element of vector, tensor or memref type
737([rationale](Rationale.md#index-type-disallowed-in-vectortensormemref-types)).
738
739**Rationale:** integers of platform-specific bit widths are practical to express
740sizes, dimensionalities and subscripts.
741
742#### Integer Type
743
744Syntax:
745
746```
747// Sized integers like i1, i4, i8, i16, i32.
748signed-integer-type ::= `si` [1-9][0-9]*
749unsigned-integer-type ::= `ui` [1-9][0-9]*
750signless-integer-type ::= `i` [1-9][0-9]*
751integer-type ::= signed-integer-type |
752                 unsigned-integer-type |
753                 signless-integer-type
754```
755
756MLIR supports arbitrary precision integer types. Integer types have a designated
757width and may have signedness semantics.
758
759**Rationale:** low precision integers (like `i2`, `i4` etc) are useful for
760low-precision inference chips, and arbitrary precision integers are useful for
761hardware synthesis (where a 13 bit multiplier is a lot cheaper/smaller than a 16
762bit one).
763
764TODO: Need to decide on a representation for quantized integers
765([initial thoughts](Rationale.md#quantized-integer-operations)).
766
767#### Memref Type
768
769Syntax:
770
771```
772memref-type ::= ranked-memref-type | unranked-memref-type
773
774ranked-memref-type ::= `memref` `<` dimension-list-ranked tensor-memref-element-type
775                      (`,` layout-specification)? |
776                      (`,` memory-space)? `>`
777
778unranked-memref-type ::= `memref` `<*x` tensor-memref-element-type
779                         (`,` memory-space)? `>`
780
781stride-list ::= `[` (dimension (`,` dimension)*)? `]`
782strided-layout ::= `offset:` dimension `,` `strides: ` stride-list
783layout-specification ::= semi-affine-map | strided-layout
784memory-space ::= integer-literal /* | TODO: address-space-id */
785```
786
787A `memref` type is a reference to a region of memory (similar to a buffer
788pointer, but more powerful). The buffer pointed to by a memref can be allocated,
789aliased and deallocated. A memref can be used to read and write data from/to the
790memory region which it references. Memref types use the same shape specifier as
791tensor types. Note that `memref<f32>`, `memref<0 x f32>`, `memref<1 x 0 x f32>`,
792and `memref<0 x 1 x f32>` are all different types.
793
794A `memref` is allowed to have an unknown rank (e.g. `memref<*xf32>`). The
795purpose of unranked memrefs is to allow external library functions to receive
796memref arguments of any rank without versioning the functions based on the rank.
797Other uses of this type are disallowed or will have undefined behavior.
798
799##### Codegen of Unranked Memref
800
801Using unranked memref in codegen besides the case mentioned above is highly
802discouraged. Codegen is concerned with generating loop nests and specialized
803instructions for high-performance, unranked memref is concerned with hiding the
804rank and thus, the number of enclosing loops required to iterate over the data.
805However, if there is a need to code-gen unranked memref, one possible path is to
806cast into a static ranked type based on the dynamic rank. Another possible path
807is to emit a single while loop conditioned on a linear index and perform
808delinearization of the linear index to a dynamic array containing the (unranked)
809indices. While this is possible, it is expected to not be a good idea to perform
810this during codegen as the cost of the translations is expected to be
811prohibitive and optimizations at this level are not expected to be worthwhile.
812If expressiveness is the main concern, irrespective of performance, passing
813unranked memrefs to an external C++ library and implementing rank-agnostic logic
814there is expected to be significantly simpler.
815
816Unranked memrefs may provide expressiveness gains in the future and help bridge
817the gap with unranked tensors. Unranked memrefs will not be expected to be
818exposed to codegen but one may query the rank of an unranked memref (a special
819op will be needed for this purpose) and perform a switch and cast to a ranked
820memref as a prerequisite to codegen.
821
822Example:
823
824```mlir
825// With static ranks, we need a function for each possible argument type
826%A = alloc() : memref<16x32xf32> %B = alloc() :
827memref<16x32x64xf32> call @helper_2D(%A) : (memref<16x32xf32>)->() call
828@helper_3D(%B) : (memref<16x32x64xf32>)->()
829
830// With unknown rank, the functions can be unified under one unranked type
831%A = alloc() : memref<16x32xf32>
832%B = alloc() : memref<16x32x64xf32>
833// Remove rank info
834%A_u = memref_cast %A : memref<16x32xf32> -> memref<*xf32>
835%B_u = memref_cast %B : memref<16x32x64xf32> -> memref<*xf32>
836// call same function with dynamic ranks
837call @helper(%A_u) : (memref<*xf32>)->()
838call @helper(%B_u) : (memref<*xf32>)->()
839```
840
841The core syntax and representation of a layout specification is a
842[semi-affine map](Dialects/Affine.md#semi-affine-maps). Additionally, syntactic
843sugar is supported to make certain layout specifications more intuitive to read.
844For the moment, a `memref` supports parsing a strided form which is converted to
845a semi-affine map automatically.
846
847The memory space of a memref is specified by a target-specific integer index. If
848no memory space is specified, then the default memory space (0) is used. The
849default space is target specific but always at index 0.
850
851TODO: MLIR will eventually have target-dialects which allow symbolic use of
852memory hierarchy names (e.g. L3, L2, L1, ...) but we have not spec'd the details
853of that mechanism yet. Until then, this document pretends that it is valid to
854refer to these memories by `bare-id`.
855
856The notionally dynamic value of a memref value includes the address of the
857buffer allocated, as well as the symbols referred to by the shape, layout map,
858and index maps.
859
860Examples of memref static type
861
862```mlir
863// Identity index/layout map
864#identity = affine_map<(d0, d1) -> (d0, d1)>
865
866// Column major layout.
867#col_major = affine_map<(d0, d1, d2) -> (d2, d1, d0)>
868
869// A 2-d tiled layout with tiles of size 128 x 256.
870#tiled_2d_128x256 = affine_map<(d0, d1) -> (d0 div 128, d1 div 256, d0 mod 128, d1 mod 256)>
871
872// A tiled data layout with non-constant tile sizes.
873#tiled_dynamic = affine_map<(d0, d1)[s0, s1] -> (d0 floordiv s0, d1 floordiv s1,
874                             d0 mod s0, d1 mod s1)>
875
876// A layout that yields a padding on two at either end of the minor dimension.
877#padded = affine_map<(d0, d1) -> (d0, (d1 + 2) floordiv 2, (d1 + 2) mod 2)>
878
879
880// The dimension list "16x32" defines the following 2D index space:
881//
882//   { (i, j) : 0 <= i < 16, 0 <= j < 32 }
883//
884memref<16x32xf32, #identity, memspace0>
885
886// The dimension list "16x4x?" defines the following 3D index space:
887//
888//   { (i, j, k) : 0 <= i < 16, 0 <= j < 4, 0 <= k < N }
889//
890// where N is a symbol which represents the runtime value of the size of
891// the third dimension.
892//
893// %N here binds to the size of the third dimension.
894%A = alloc(%N) : memref<16x4x?xf32, #col_major, memspace0>
895
896// A 2-d dynamic shaped memref that also has a dynamically sized tiled layout.
897// The memref index space is of size %M x %N, while %B1 and %B2 bind to the
898// symbols s0, s1 respectively of the layout map #tiled_dynamic. Data tiles of
899// size %B1 x %B2 in the logical space will be stored contiguously in memory.
900// The allocation size will be (%M ceildiv %B1) * %B1 * (%N ceildiv %B2) * %B2
901// f32 elements.
902%T = alloc(%M, %N) [%B1, %B2] : memref<?x?xf32, #tiled_dynamic>
903
904// A memref that has a two-element padding at either end. The allocation size
905// will fit 16 * 64 float elements of data.
906%P = alloc() : memref<16x64xf32, #padded>
907
908// Affine map with symbol 's0' used as offset for the first dimension.
909#imapS = affine_map<(d0, d1) [s0] -> (d0 + s0, d1)>
910// Allocate memref and bind the following symbols:
911// '%n' is bound to the dynamic second dimension of the memref type.
912// '%o' is bound to the symbol 's0' in the affine map of the memref type.
913%n = ...
914%o = ...
915%A = alloc (%n)[%o] : <16x?xf32, #imapS>
916```
917
918##### Index Space
919
920A memref dimension list defines an index space within which the memref can be
921indexed to access data.
922
923##### Index
924
925Data is accessed through a memref type using a multidimensional index into the
926multidimensional index space defined by the memref's dimension list.
927
928Examples
929
930```mlir
931// Allocates a memref with 2D index space:
932//   { (i, j) : 0 <= i < 16, 0 <= j < 32 }
933%A = alloc() : memref<16x32xf32, #imapA, memspace0>
934
935// Loads data from memref '%A' using a 2D index: (%i, %j)
936%v = load %A[%i, %j] : memref<16x32xf32, #imapA, memspace0>
937```
938
939##### Index Map
940
941An index map is a one-to-one
942[semi-affine map](Dialects/Affine.md#semi-affine-maps) that transforms a
943multidimensional index from one index space to another. For example, the
944following figure shows an index map which maps a 2-dimensional index from a 2x2
945index space to a 3x3 index space, using symbols `S0` and `S1` as offsets.
946
947![Index Map Example](/includes/img/index-map.svg)
948
949The number of domain dimensions and range dimensions of an index map can be
950different, but must match the number of dimensions of the input and output index
951spaces on which the map operates. The index space is always non-negative and
952integral. In addition, an index map must specify the size of each of its range
953dimensions onto which it maps. Index map symbols must be listed in order with
954symbols for dynamic dimension sizes first, followed by other required symbols.
955
956##### Layout Map
957
958A layout map is a [semi-affine map](Dialects/Affine.md#semi-affine-maps) which
959encodes logical to physical index space mapping, by mapping input dimensions to
960their ordering from most-major (slowest varying) to most-minor (fastest
961varying). Therefore, an identity layout map corresponds to a row-major layout.
962Identity layout maps do not contribute to the MemRef type identification and are
963discarded on construction. That is, a type with an explicit identity map is
964`memref<?x?xf32, (i,j)->(i,j)>` is strictly the same as the one without layout
965maps, `memref<?x?xf32>`.
966
967Layout map examples:
968
969```mlir
970// MxN matrix stored in row major layout in memory:
971#layout_map_row_major = (i, j) -> (i, j)
972
973// MxN matrix stored in column major layout in memory:
974#layout_map_col_major = (i, j) -> (j, i)
975
976// MxN matrix stored in a 2-d blocked/tiled layout with 64x64 tiles.
977#layout_tiled = (i, j) -> (i floordiv 64, j floordiv 64, i mod 64, j mod 64)
978```
979
980##### Affine Map Composition
981
982A memref specifies a semi-affine map composition as part of its type. A
983semi-affine map composition is a composition of semi-affine maps beginning with
984zero or more index maps, and ending with a layout map. The composition must be
985conformant: the number of dimensions of the range of one map, must match the
986number of dimensions of the domain of the next map in the composition.
987
988The semi-affine map composition specified in the memref type, maps from accesses
989used to index the memref in load/store operations to other index spaces (i.e.
990logical to physical index mapping). Each of the
991[semi-affine maps](Dialects/Affine.md) and thus its composition is required to
992be one-to-one.
993
994The semi-affine map composition can be used in dependence analysis, memory
995access pattern analysis, and for performance optimizations like vectorization,
996copy elision and in-place updates. If an affine map composition is not specified
997for the memref, the identity affine map is assumed.
998
999##### Strided MemRef
1000
1001A memref may specify strides as part of its type. A stride specification is a
1002list of integer values that are either static or `?` (dynamic case). Strides
1003encode the distance, in number of elements, in (linear) memory between
1004successive entries along a particular dimension. A stride specification is
1005syntactic sugar for an equivalent strided memref representation using
1006semi-affine maps. For example, `memref<42x16xf32, offset: 33 strides: [1, 64]>`
1007specifies a non-contiguous memory region of `42` by `16` `f32` elements such
1008that:
1009
10101.  the minimal size of the enclosing memory region must be `33 + 42 * 1 + 16 *
1011    64 = 1066` elements;
10122.  the address calculation for accessing element `(i, j)` computes `33 + i +
1013    64 * j`
10143.  the distance between two consecutive elements along the outer dimension is
1015    `1` element and the distance between two consecutive elements along the
1016    outer dimension is `64` elements.
1017
1018This corresponds to a column major view of the memory region and is internally
1019represented as the type `memref<42x16xf32, (i, j) -> (33 + i + 64 * j)>`.
1020
1021The specification of strides must not alias: given an n-D strided memref,
1022indices `(i1, ..., in)` and `(j1, ..., jn)` may not refer to the same memory
1023address unless `i1 == j1, ..., in == jn`.
1024
1025Strided memrefs represent a view abstraction over preallocated data. They are
1026constructed with special ops, yet to be introduced. Strided memrefs are a
1027special subclass of memrefs with generic semi-affine map and correspond to a
1028normalized memref descriptor when lowering to LLVM.
1029
1030#### None Type
1031
1032Syntax:
1033
1034```
1035none-type ::= `none`
1036```
1037
1038The `none` type is a unit type, i.e. a type with exactly one possible value,
1039where its value does not have a defined dynamic representation.
1040
1041#### Tensor Type
1042
1043Syntax:
1044
1045```
1046tensor-type ::= `tensor` `<` dimension-list tensor-memref-element-type `>`
1047tensor-memref-element-type ::= vector-element-type | vector-type | complex-type
1048
1049// memref requires a known rank, but tensor does not.
1050dimension-list ::= dimension-list-ranked | (`*` `x`)
1051dimension-list-ranked ::= (dimension `x`)*
1052dimension ::= `?` | decimal-literal
1053```
1054
1055SSA values of tensor type represents aggregate N-dimensional data values, and
1056have a known element type. It may have an unknown rank (indicated by `*`) or may
1057have a fixed rank with a list of dimensions. Each dimension may be a static
1058non-negative decimal constant or be dynamically determined (indicated by `?`).
1059
1060The runtime representation of the MLIR tensor type is intentionally abstracted -
1061you cannot control layout or get a pointer to the data. For low level buffer
1062access, MLIR has a [`memref` type](#memref-type). This abstracted runtime
1063representation holds both the tensor data values as well as information about
1064the (potentially dynamic) shape of the tensor. The
1065[`dim` operation](Dialects/Standard.md#dim-operation) returns the size of a
1066dimension from a value of tensor type.
1067
1068Note: hexadecimal integer literals are not allowed in tensor type declarations
1069to avoid confusion between `0xf32` and `0 x f32`. Zero sizes are allowed in
1070tensors and treated as other sizes, e.g., `tensor<0 x 1 x i32>` and `tensor<1 x
10710 x i32>` are different types. Since zero sizes are not allowed in some other
1072types, such tensors should be optimized away before lowering tensors to vectors.
1073
1074Examples:
1075
1076```mlir
1077// Tensor with unknown rank.
1078tensor<* x f32>
1079
1080// Known rank but unknown dimensions.
1081tensor<? x ? x ? x ? x f32>
1082
1083// Partially known dimensions.
1084tensor<? x ? x 13 x ? x f32>
1085
1086// Full static shape.
1087tensor<17 x 4 x 13 x 4 x f32>
1088
1089// Tensor with rank zero. Represents a scalar.
1090tensor<f32>
1091
1092// Zero-element dimensions are allowed.
1093tensor<0 x 42 x f32>
1094
1095// Zero-element tensor of f32 type (hexadecimal literals not allowed here).
1096tensor<0xf32>
1097```
1098
1099#### Tuple Type
1100
1101Syntax:
1102
1103```
1104tuple-type ::= `tuple` `<` (type ( `,` type)*)? `>`
1105```
1106
1107The value of `tuple` type represents a fixed-size collection of elements, where
1108each element may be of a different type.
1109
1110**Rationale:** Though this type is first class in the type system, MLIR provides
1111no standard operations for operating on `tuple` types
1112([rationale](Rationale.md#tuple-types)).
1113
1114Examples:
1115
1116```mlir
1117// Empty tuple.
1118tuple<>
1119
1120// Single element
1121tuple<f32>
1122
1123// Many elements.
1124tuple<i32, f32, tensor<i1>, i5>
1125```
1126
1127#### Vector Type
1128
1129Syntax:
1130
1131```
1132vector-type ::= `vector` `<` static-dimension-list vector-element-type `>`
1133vector-element-type ::= float-type | integer-type
1134
1135static-dimension-list ::= (decimal-literal `x`)+
1136```
1137
1138The vector type represents a SIMD style vector, used by target-specific
1139operation sets like AVX. While the most common use is for 1D vectors (e.g.
1140vector<16 x f32>) we also support multidimensional registers on targets that
1141support them (like TPUs).
1142
1143Vector shapes must be positive decimal integers.
1144
1145Note: hexadecimal integer literals are not allowed in vector type declarations,
1146`vector<0x42xi32>` is invalid because it is interpreted as a 2D vector with
1147shape `(0, 42)` and zero shapes are not allowed.
1148
1149## Attributes
1150
1151Syntax:
1152
1153```
1154attribute-dict ::= `{` `}`
1155                 | `{` attribute-entry (`,` attribute-entry)* `}`
1156attribute-entry ::= dialect-attribute-entry | dependent-attribute-entry
1157dialect-attribute-entry ::= dialect-namespace `.` bare-id `=` attribute-value
1158dependent-attribute-entry ::= dependent-attribute-name `=` attribute-value
1159dependent-attribute-name ::= ((letter|[_]) (letter|digit|[_$])*)
1160                           | string-literal
1161```
1162
1163Attributes are the mechanism for specifying constant data on operations in
1164places where a variable is never allowed - e.g. the index of a
1165[`dim` operation](Dialects/Standard.md#dim-operation), or the stride of a
1166convolution. They consist of a name and a concrete attribute value. The set of
1167expected attributes, their structure, and their interpretation are all
1168contextually dependent on what they are attached to.
1169
1170There are two main classes of attributes: dependent and dialect. Dependent
1171attributes derive their structure and meaning from what they are attached to;
1172e.g., the meaning of the `index` attribute on a `dim` operation is defined by
1173the `dim` operation. Dialect attributes, on the other hand, derive their context
1174and meaning from a specific dialect. An example of a dialect attribute may be a
1175`swift.self` function argument attribute that indicates an argument is the
1176self/context parameter. The context of this attribute is defined by the `swift`
1177dialect and not the function argument.
1178
1179Attribute values are represented by the following forms:
1180
1181```
1182attribute-value ::= attribute-alias | dialect-attribute | standard-attribute
1183```
1184
1185### Attribute Value Aliases
1186
1187```
1188attribute-alias ::= '#' alias-name '=' attribute-value
1189attribute-alias ::= '#' alias-name
1190```
1191
1192MLIR supports defining named aliases for attribute values. An attribute alias is
1193an identifier that can be used in the place of the attribute that it defines.
1194These aliases *must* be defined before their uses. Alias names may not contain a
1195'.', since those names are reserved for
1196[dialect attributes](#dialect-attribute-values).
1197
1198Example:
1199
1200```mlir
1201#map = affine_map<(d0) -> (d0 + 10)>
1202
1203// Using the original attribute.
1204%b = affine.apply affine_map<(d0) -> (d0 + 10)> (%a)
1205
1206// Using the attribute alias.
1207%b = affine.apply #map(%a)
1208```
1209
1210### Dialect Attribute Values
1211
1212Similarly to operations, dialects may define custom attribute values. The
1213syntactic structure of these values is identical to custom dialect type values,
1214except that dialect attributes values are distinguished with a leading '#',
1215while dialect types are distinguished with a leading '!'.
1216
1217```
1218dialect-attribute ::= '#' opaque-dialect-item
1219dialect-attribute ::= '#' pretty-dialect-item
1220```
1221
1222Dialect attributes can be specified in a verbose form, e.g. like this:
1223
1224```mlir
1225// Complex attribute
1226#foo<"something<abcd>">
1227
1228// Even more complex attribute
1229#foo<"something<a%%123^^^>>>">
1230```
1231
1232Dialect attributes that are simple enough can use the pretty format, which is a
1233lighter weight syntax that is equivalent to the above forms:
1234
1235```mlir
1236// Complex attribute
1237#foo.something<abcd>
1238```
1239
1240Sufficiently complex dialect attributes are required to use the verbose form for
1241generality. For example, the more complex type shown above wouldn't be valid in
1242the lighter syntax: `#foo.something<a%%123^^^>>>` because it contains characters
1243that are not allowed in the lighter syntax, as well as unbalanced `<>`
1244characters.
1245
1246See [here](DefiningAttributesAndTypes.md) to learn how to define dialect
1247attribute values.
1248
1249### Standard Attribute Values
1250
1251Standard attributes are a core set of
1252[dialect attributes](#dialect-attribute-values) that are defined in a builtin
1253dialect and thus available to all users of MLIR.
1254
1255```
1256standard-attribute ::=   affine-map-attribute
1257                       | array-attribute
1258                       | bool-attribute
1259                       | dictionary-attribute
1260                       | elements-attribute
1261                       | float-attribute
1262                       | integer-attribute
1263                       | integer-set-attribute
1264                       | string-attribute
1265                       | symbol-ref-attribute
1266                       | type-attribute
1267                       | unit-attribute
1268```
1269
1270#### AffineMap Attribute
1271
1272Syntax:
1273
1274```
1275affine-map-attribute ::= `affine_map` `<` affine-map `>`
1276```
1277
1278An affine-map attribute is an attribute that represents an affine-map object.
1279
1280#### Array Attribute
1281
1282Syntax:
1283
1284```
1285array-attribute ::= `[` (attribute-value (`,` attribute-value)*)? `]`
1286```
1287
1288An array attribute is an attribute that represents a collection of attribute
1289values.
1290
1291#### Boolean Attribute
1292
1293Syntax:
1294
1295```
1296bool-attribute ::= bool-literal
1297```
1298
1299A boolean attribute is a literal attribute that represents a one-bit boolean
1300value, true or false.
1301
1302#### Dictionary Attribute
1303
1304Syntax:
1305
1306```
1307dictionary-attribute ::= `{` (attribute-entry (`,` attribute-entry)*)? `}`
1308```
1309
1310A dictionary attribute is an attribute that represents a sorted collection of
1311named attribute values. The elements are sorted by name, and each name must be
1312unique within the collection.
1313
1314#### Elements Attributes
1315
1316Syntax:
1317
1318```
1319elements-attribute ::= dense-elements-attribute
1320                     | opaque-elements-attribute
1321                     | sparse-elements-attribute
1322```
1323
1324An elements attribute is a literal attribute that represents a constant
1325[vector](#vector-type) or [tensor](#tensor-type) value.
1326
1327##### Dense Elements Attribute
1328
1329Syntax:
1330
1331```
1332dense-elements-attribute ::= `dense` `<` attribute-value `>` `:`
1333                             ( tensor-type | vector-type )
1334```
1335
1336A dense elements attribute is an elements attribute where the storage for the
1337constant vector or tensor value has been packed to the element bitwidth. The
1338element type of the vector or tensor constant must be of integer, index, or
1339floating point type.
1340
1341##### Opaque Elements Attribute
1342
1343Syntax:
1344
1345```
1346opaque-elements-attribute ::= `opaque` `<` dialect-namespace  `,`
1347                              hex-string-literal `>` `:`
1348                              ( tensor-type | vector-type )
1349```
1350
1351An opaque elements attribute is an elements attribute where the content of the
1352value is opaque. The representation of the constant stored by this elements
1353attribute is only understood, and thus decodable, by the dialect that created
1354it.
1355
1356Note: The parsed string literal must be in hexadecimal form.
1357
1358##### Sparse Elements Attribute
1359
1360Syntax:
1361
1362```
1363sparse-elements-attribute ::= `sparse` `<` attribute-value `,` attribute-value
1364                              `>` `:` ( tensor-type | vector-type )
1365```
1366
1367A sparse elements attribute is an elements attribute that represents a sparse
1368vector or tensor object. This is where very few of the elements are non-zero.
1369
1370The attribute uses COO (coordinate list) encoding to represent the sparse
1371elements of the elements attribute. The indices are stored via a 2-D tensor of
137264-bit integer elements with shape [N, ndims], which specifies the indices of
1373the elements in the sparse tensor that contains non-zero values. The element
1374values are stored via a 1-D tensor with shape [N], that supplies the
1375corresponding values for the indices.
1376
1377Example:
1378
1379```mlir
1380  sparse<[[0, 0], [1, 2]], [1, 5]> : tensor<3x4xi32>
1381
1382// This represents the following tensor:
1383///  [[1, 0, 0, 0],
1384///   [0, 0, 5, 0],
1385///   [0, 0, 0, 0]]
1386```
1387
1388#### Float Attribute
1389
1390Syntax:
1391
1392```
1393float-attribute ::= (float-literal (`:` float-type)?)
1394                  | (hexadecimal-literal `:` float-type)
1395```
1396
1397A float attribute is a literal attribute that represents a floating point value
1398of the specified [float type](#floating-point-types). It can be represented in
1399the hexadecimal form where the hexadecimal value is interpreted as bits of the
1400underlying binary representation. This form is useful for representing infinity
1401and NaN floating point values. To avoid confusion with integer attributes,
1402hexadecimal literals _must_ be followed by a float type to define a float
1403attribute.
1404
1405Examples:
1406
1407```
140842.0         // float attribute defaults to f64 type
140942.0 : f32   // float attribute of f32 type
14100x7C00 : f16 // positive infinity
14110x7CFF : f16 // NaN (one of possible values)
141242 : f32     // Error: expected integer type
1413```
1414
1415#### Integer Attribute
1416
1417Syntax:
1418
1419```
1420integer-attribute ::= integer-literal ( `:` (index-type | integer-type) )?
1421```
1422
1423An integer attribute is a literal attribute that represents an integral value of
1424the specified integer or index type. The default type for this attribute, if one
1425is not specified, is a 64-bit integer.
1426
1427##### Integer Set Attribute
1428
1429Syntax:
1430
1431```
1432integer-set-attribute ::= `affine_set` `<` integer-set `>`
1433```
1434
1435An integer-set attribute is an attribute that represents an integer-set object.
1436
1437#### String Attribute
1438
1439Syntax:
1440
1441```
1442string-attribute ::= string-literal (`:` type)?
1443```
1444
1445A string attribute is an attribute that represents a string literal value.
1446
1447#### Symbol Reference Attribute
1448
1449Syntax:
1450
1451```
1452symbol-ref-attribute ::= symbol-ref-id (`::` symbol-ref-id)*
1453```
1454
1455A symbol reference attribute is a literal attribute that represents a named
1456reference to an operation that is nested within an operation with the
1457`OpTrait::SymbolTable` trait. As such, this reference is given meaning by the
1458nearest parent operation containing the `OpTrait::SymbolTable` trait. It may
1459optionally contain a set of nested references that further resolve to a symbol
1460nested within a different symbol table.
1461
1462This attribute can only be held internally by
1463[array attributes](#array-attribute) and
1464[dictionary attributes](#dictionary-attribute)(including the top-level operation
1465attribute dictionary), i.e. no other attribute kinds such as Locations or
1466extended attribute kinds.
1467
1468**Rationale:** Given that MLIR models global accesses with symbol references, to
1469enable efficient multi-threading, it becomes difficult to effectively reason
1470about their uses. By restricting the places that can legally hold a symbol
1471reference, we can always opaquely reason about a symbols usage characteristics.
1472
1473See [`Symbols And SymbolTables`](SymbolsAndSymbolTables.md) for more
1474information.
1475
1476#### Type Attribute
1477
1478Syntax:
1479
1480```
1481type-attribute ::= type
1482```
1483
1484A type attribute is an attribute that represents a [type object](#type-system).
1485
1486#### Unit Attribute
1487
1488```
1489unit-attribute ::= `unit`
1490```
1491
1492A unit attribute is an attribute that represents a value of `unit` type. The
1493`unit` type allows only one value forming a singleton set. This attribute value
1494is used to represent attributes that only have meaning from their existence.
1495
1496One example of such an attribute could be the `swift.self` attribute. This
1497attribute indicates that a function parameter is the self/context parameter. It
1498could be represented as a [boolean attribute](#boolean-attribute)(true or
1499false), but a value of false doesn't really bring any value. The parameter
1500either is the self/context or it isn't.
1501
1502```mlir
1503// A unit attribute defined with the `unit` value specifier.
1504func @verbose_form(i1) attributes {dialectName.unitAttr = unit}
1505
1506// A unit attribute can also be defined without the value specifier.
1507func @simple_form(i1) attributes {dialectName.unitAttr}
1508```
1509