|
| 1 | +# 'irdl' Dialect |
| 2 | + |
| 3 | +[TOC] |
| 4 | + |
| 5 | +## Basics |
| 6 | + |
| 7 | +The IRDL (*Intermediate Representation Definition Language*) dialect allows |
| 8 | +defining MLIR dialects as MLIR programs. Nested operations are used to |
| 9 | +represent dialect structure: dialects contain operations, types and |
| 10 | +attributes, themselves containing type parameters, operands, results, etc. |
| 11 | +Each of those concepts are mapped to MLIR operations in the IRDL dialect, as |
| 12 | +shown in the example dialect below: |
| 13 | + |
| 14 | +```mlir |
| 15 | +irdl.dialect @cmath { |
| 16 | + irdl.type @complex { |
| 17 | + %0 = irdl.is f32 |
| 18 | + %1 = irdl.is f64 |
| 19 | + %2 = irdl.any_of(%0, %1) |
| 20 | + irdl.parameters(%2) |
| 21 | + } |
| 22 | +
|
| 23 | + irdl.operation @mul { |
| 24 | + %0 = irdl.is f32 |
| 25 | + %1 = irdl.is f64 |
| 26 | + %2 = irdl.any_of(%0, %1) |
| 27 | + %3 = irdl.parametric @cmath::@complex<%2> |
| 28 | + irdl.operands(%3, %3) |
| 29 | + irdl.results(%3) |
| 30 | + } |
| 31 | +} |
| 32 | +``` |
| 33 | + |
| 34 | +This program defines a `cmath` dialect that defines a `complex` type, and |
| 35 | +a `mul` operation. Both express constraints over their parameters using |
| 36 | +SSA constraint operations. Informally, one can see those SSA values as |
| 37 | +constraint variables that evaluate to a single type at constraint |
| 38 | +evaluation. For example, the result of the `irdl.any_of` stored in `%2` |
| 39 | +in the `mul` operation will collapse into either `f32` or `f64` for the |
| 40 | +entirety of this instance of `mul` constraint evaluation. As such, |
| 41 | +both operands and the result of `mul` must be of equal type (and not just |
| 42 | +satisfy the same constraint). For more information, see |
| 43 | +[constraints and combinators](#constraints-and-combinators). |
| 44 | + |
| 45 | +In order to simplify the dialect, IRDL variables are handles over |
| 46 | +`mlir::Attribute`. In order to support manipulating `mlir::Type`, |
| 47 | +IRDL wraps all types in an `mlir::TypeAttr` attribute. |
| 48 | + |
| 49 | +## Principles |
| 50 | + |
| 51 | +The core principles of IRDL are the following, in no particular order: |
| 52 | + |
| 53 | +- **Portability.** IRDL dialects should be self-contained, such that dialects |
| 54 | + can be easily distributed with minimal assumptions on which compiler |
| 55 | + infrastructure (or which commit of MLIR) is used. |
| 56 | +- **Introspection.** The IRDL dialect definition mechanism should strive |
| 57 | + towards offering as much introspection abilities as possible. Dialects |
| 58 | + should be as easy to manipulate, generate, and analyze as possible. |
| 59 | +- **Runtime declaration support**. The specification of IRDL dialects should |
| 60 | + offer the ability to have them be loaded at runtime, via dynamic registration |
| 61 | + or JIT compilation. Compatibility with dynamic workflows should not hinder |
| 62 | + the ability to compile IRDL dialects into ahead-of-time declarations. |
| 63 | +- **Reliability.** Concepts in IRDL should be consistent and predictable, with |
| 64 | + as much focus on high-level simplicity as possible. Consequently, IRDL |
| 65 | + definitions that verify should work out of the box, and those that do not |
| 66 | + verify should provide clear and understandable errors in all circumstances. |
| 67 | + |
| 68 | +While IRDL simplifies IR definition, it remains an IR itself and thus does not |
| 69 | +require to be comfortably user-writeable. |
| 70 | + |
| 71 | +## Constraints and combinators |
| 72 | + |
| 73 | +Attribute, type and operation verifiers are expressed in terms of constraint |
| 74 | +variables. Constraint variables are defined as the results of constraint |
| 75 | +operations (like `irdl.is` or constraint combinators). |
| 76 | + |
| 77 | +Constraint variables act as variables: as such, matching against the same |
| 78 | +constraint variable multiple times can only succeed if the matching type or |
| 79 | +attribute is the same as the one that previously matched. In the following |
| 80 | +example: |
| 81 | + |
| 82 | +```mlir |
| 83 | +irdl.type @foo { |
| 84 | + %ty = irdl.any_type |
| 85 | + irdl.parameters(param1: %ty, param2: %ty) |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +only types with two equal parameters will successfully match (`foo<i32, i32>` |
| 90 | +would match while `foo<i32, i64>` would fail, even though both i32 and i64 |
| 91 | +individually satisfy the `irdl.any_type` constraint). This constraint variable |
| 92 | +mechanism allows to easily express a requirement on type or attribute equality. |
| 93 | + |
| 94 | +To declare more complex verifiers, IRDL provides constraint-combinator |
| 95 | +operations such as `irdl.any_of`, `irdl.all_of` or `irdl.parametric`. These |
| 96 | +combinators can be used to combine constraint variables into new constraint |
| 97 | +variables. Like all uses of constraint variables, their constraint variable |
| 98 | +operands enforce equality of matched types of attributes as explained in the |
| 99 | +previous paragraph. |
| 100 | + |
| 101 | +## Motivating use cases |
| 102 | + |
| 103 | +To illustrate the rationale behind IRDL, the following list describes examples |
| 104 | +of intended use cases for IRDL, in no particular order: |
| 105 | + |
| 106 | +- **Fuzzer generation.** With declarative verifier definitions, it is possible |
| 107 | + to compile IRDL dialects into compiler fuzzers that generate only programs |
| 108 | + passing verifiers. |
| 109 | +- **Portable dialects between compiler infrastructures.** Some compiler |
| 110 | + infrastructures are independent from MLIR but are otherwise IR-compatible. |
| 111 | + Portable IRDL dialects allow to share the dialect definitions between MLIR |
| 112 | + and other compiler infrastructures without needing to maintain multiple |
| 113 | + potentially out-of-sync definitions. |
| 114 | +- **Dialect simplification.** Because IRDL definitions can easily be |
| 115 | + mechanically modified, it is possible to simplify the definition of dialects |
| 116 | + based on which operations are actually used, leading to smaller compilers. |
| 117 | +- **SMT analysis.** Because IRDL dialect definitions are declarative, their |
| 118 | + definition can be lowered to alternative representations like SMT, allowing |
| 119 | + analysis of the behavior of transforms taking verifiers into account. |
| 120 | + |
| 121 | +## Operations |
| 122 | + |
| 123 | +[include "Dialects/IRDLOps.md"] |
0 commit comments