annotate mlir/docs/Canonicalization.md @ 194:f2ef29ba5fe2

try to remove setjmp.h start
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 22 Mar 2021 18:10:23 +0900
parents 0572611fdcc8
children 2e18cbf3894f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
1 # Operation Canonicalization
150
anatofuz
parents:
diff changeset
2
anatofuz
parents:
diff changeset
3 Canonicalization is an important part of compiler IR design: it makes it easier
anatofuz
parents:
diff changeset
4 to implement reliable compiler transformations and to reason about what is
anatofuz
parents:
diff changeset
5 better or worse in the code, and it forces interesting discussions about the
anatofuz
parents:
diff changeset
6 goals of a particular level of IR. Dan Gohman wrote
anatofuz
parents:
diff changeset
7 [an article](https://sunfishcode.github.io/blog/2018/10/22/Canonicalization.html)
anatofuz
parents:
diff changeset
8 exploring these issues; it is worth reading if you're not familiar with these
anatofuz
parents:
diff changeset
9 concepts.
anatofuz
parents:
diff changeset
10
anatofuz
parents:
diff changeset
11 Most compilers have canonicalization passes, and sometimes they have many
anatofuz
parents:
diff changeset
12 different ones (e.g. instcombine, dag combine, etc in LLVM). Because MLIR is a
anatofuz
parents:
diff changeset
13 multi-level IR, we can provide a single canonicalization infrastructure and
anatofuz
parents:
diff changeset
14 reuse it across many different IRs that it represents. This document describes
anatofuz
parents:
diff changeset
15 the general approach, global canonicalizations performed, and provides sections
anatofuz
parents:
diff changeset
16 to capture IR-specific rules for reference.
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 ## General Design
anatofuz
parents:
diff changeset
19
anatofuz
parents:
diff changeset
20 MLIR has a single canonicalization pass, which iteratively applies
anatofuz
parents:
diff changeset
21 canonicalization transformations in a greedy way until the IR converges. These
anatofuz
parents:
diff changeset
22 transformations are defined by the operations themselves, which allows each
anatofuz
parents:
diff changeset
23 dialect to define its own set of operations and canonicalizations together.
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 Some important things to think about w.r.t. canonicalization patterns:
anatofuz
parents:
diff changeset
26
anatofuz
parents:
diff changeset
27 * Repeated applications of patterns should converge. Unstable or cyclic
anatofuz
parents:
diff changeset
28 rewrites will cause infinite loops in the canonicalizer.
anatofuz
parents:
diff changeset
29
anatofuz
parents:
diff changeset
30 * It is generally better to canonicalize towards operations that have fewer
anatofuz
parents:
diff changeset
31 uses of a value when the operands are duplicated, because some patterns only
anatofuz
parents:
diff changeset
32 match when a value has a single user. For example, it is generally good to
anatofuz
parents:
diff changeset
33 canonicalize "x + x" into "x * 2", because this reduces the number of uses
anatofuz
parents:
diff changeset
34 of x by one.
anatofuz
parents:
diff changeset
35
anatofuz
parents:
diff changeset
36 * It is always good to eliminate operations entirely when possible, e.g. by
anatofuz
parents:
diff changeset
37 folding known identities (like "x + 0 = x").
anatofuz
parents:
diff changeset
38
anatofuz
parents:
diff changeset
39 ## Globally Applied Rules
anatofuz
parents:
diff changeset
40
anatofuz
parents:
diff changeset
41 These transformations are applied to all levels of IR:
anatofuz
parents:
diff changeset
42
anatofuz
parents:
diff changeset
43 * Elimination of operations that have no side effects and have no uses.
anatofuz
parents:
diff changeset
44
anatofuz
parents:
diff changeset
45 * Constant folding - e.g. "(addi 1, 2)" to "3". Constant folding hooks are
anatofuz
parents:
diff changeset
46 specified by operations.
anatofuz
parents:
diff changeset
47
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
48 * Move constant operands to commutative operators to the right side - e.g.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
49 "(addi 4, x)" to "(addi x, 4)".
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
50
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
51 * `constant-like` operations are uniqued and hoisted into the entry block of
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
52 the first parent barrier region. This is a region that is either isolated
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
53 from above, e.g. the entry block of a function, or one marked as a barrier
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
54 via the `shouldMaterializeInto` method on the `OpFolderDialectInterface`.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
55
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
56 ## Defining Canonicalizations
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
57
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
58 Two mechanisms are available with which to define canonicalizations;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
59 `getCanonicalizationPatterns` and `fold`.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
60
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
61 ### Canonicalizing with `getCanonicalizationPatterns`
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
62
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
63 This mechanism allows for providing canonicalizations as a set of
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
64 `RewritePattern`s, either imperatively defined in C++ or declaratively as
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
65 [Declarative Rewrite Rules](DeclarativeRewrites.md). The pattern rewrite
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
66 infrastructure allows for expressing many different types of canonicalizations.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
67 These transformations may be as simple as replacing a multiplication with a
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
68 shift, or even replacing a conditional branch with an unconditional one.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
69
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
70 In [ODS](OpDefinitions.md), an operation can set the `hasCanonicalizer` bit to
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
71 generate a declaration for the `getCanonicalizationPatterns` method.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
72
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
73 ```tablegen
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
74 def MyOp : ... {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
75 let hasCanonicalizer = 1;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
76 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
77 ```
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
78
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
79 Canonicalization patterns can then be provided in the source file:
150
anatofuz
parents:
diff changeset
80
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
81 ```c++
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
82 void MyOp::getCanonicalizationPatterns(OwningRewritePatternList &patterns,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
83 MLIRContext *context) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
84 patterns.insert<...>(...);
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
85 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
86 ```
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
87
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
88 See the [quickstart guide](Tutorials/QuickstartRewrites.md) for information on
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
89 defining operation rewrites.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
90
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
91 ### Canonicalizing with `fold`
150
anatofuz
parents:
diff changeset
92
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
93 The `fold` mechanism is an intentionally limited, but powerful mechanism that
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
94 allows for applying canonicalizations in many places throughout the compiler.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
95 For example, outside of the canonicalizer pass, `fold` is used within the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
96 [dialect conversion infrastructure](#DialectConversion.md) as a legalization
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
97 mechanism, and can be invoked directly anywhere with an `OpBuilder` via
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
98 `OpBuilder::createOrFold`.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
99
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
100 `fold` has the restriction that no new operations may be created, and only the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
101 root operation may be replaced. It allows for updating an operation in-place, or
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
102 returning a set of pre-existing values (or attributes) to replace the operation
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
103 with. This ensures that the `fold` method is a truly "local" transformation, and
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
104 can be invoked without the need for a pattern rewriter.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
105
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
106 In [ODS](OpDefinitions.md), an operation can set the `hasFolder` bit to generate
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
107 a declaration for the `fold` method. This method takes on a different form,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
108 depending on the structure of the operation.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
109
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
110 ```tablegen
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
111 def MyOp : ... {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
112 let hasFolder = 1;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
113 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
114 ```
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
115
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
116 If the operation has a single result the following will be generated:
150
anatofuz
parents:
diff changeset
117
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
118 ```c++
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
119 /// Implementations of this hook can only perform the following changes to the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
120 /// operation:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
121 ///
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
122 /// 1. They can leave the operation alone and without changing the IR, and
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
123 /// return nullptr.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
124 /// 2. They can mutate the operation in place, without changing anything else
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
125 /// in the IR. In this case, return the operation itself.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
126 /// 3. They can return an existing value or attribute that can be used instead
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
127 /// of the operation. The caller will remove the operation and use that
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
128 /// result instead.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
129 ///
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
130 OpFoldResult MyOp::fold(ArrayRef<Attribute> operands) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
131 ...
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
132 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
133 ```
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
134
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
135 Otherwise, the following is generated:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
136
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
137 ```c++
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
138 /// Implementations of this hook can only perform the following changes to the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
139 /// operation:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
140 ///
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
141 /// 1. They can leave the operation alone and without changing the IR, and
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
142 /// return failure.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
143 /// 2. They can mutate the operation in place, without changing anything else
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
144 /// in the IR. In this case, return success.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
145 /// 3. They can return a list of existing values or attribute that can be used
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
146 /// instead of the operation. In this case, fill in the results list and
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
147 /// return success. The results list must correspond 1-1 with the results of
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
148 /// the operation, partial folding is not supported. The caller will remove
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
149 /// the operation and use those results instead.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
150 ///
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
151 LogicalResult MyOp::fold(ArrayRef<Attribute> operands,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
152 SmallVectorImpl<OpFoldResult> &results) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
153 ...
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
154 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
155 ```
150
anatofuz
parents:
diff changeset
156
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
157 In the above, for each method an `ArrayRef<Attribute>` is provided that
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
158 corresponds to the constant attribute value of each of the operands. These
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
159 operands are those that implement the `ConstantLike` trait. If any of the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
160 operands are non-constant, a null `Attribute` value is provided instead. For
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
161 example, if MyOp provides three operands [`a`, `b`, `c`], but only `b` is
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
162 constant then `operands` will be of the form [Attribute(), b-value,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
163 Attribute()].
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
164
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
165 Also above, is the use of `OpFoldResult`. This class represents the possible
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
166 result of folding an operation result: either an SSA `Value`, or an
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
167 `Attribute`(for a constant result). If an SSA `Value` is provided, it *must*
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
168 correspond to an existing value. The `fold` methods are not permitted to
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
169 generate new `Value`s. There are no specific restrictions on the form of the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
170 `Attribute` value returned, but it is important to ensure that the `Attribute`
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
171 representation of a specific `Type` is consistent.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
172
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
173 #### Generating Constants from Attributes
150
anatofuz
parents:
diff changeset
174
173
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
175 When a `fold` method returns an `Attribute` as the result, it signifies that
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
176 this result is "constant". The `Attribute` is the constant representation of the
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
177 value. Users of the `fold` method, such as the canonicalizer pass, will take
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
178 these `Attribute`s and materialize constant operations in the IR to represent
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
179 them. To enable this materialization, the dialect of the operation must
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
180 implement the `materializeConstant` hook. This hook takes in an `Attribute`
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
181 value, generally returned by `fold`, and produces a "constant-like" operation
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
182 that materializes that value.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
183
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
184 In [ODS](OpDefinitions.md), a dialect can set the `hasConstantMaterializer` bit
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
185 to generate a declaration for the `materializeConstant` method.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
186
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
187 ```tablegen
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
188 def MyDialect_Dialect : ... {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
189 let hasConstantMaterializer = 1;
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
190 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
191 ```
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
192
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
193 Constants can then be materialized in the source file:
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
194
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
195 ```c++
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
196 /// Hook to materialize a single constant operation from a given attribute value
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
197 /// with the desired resultant type. This method should use the provided builder
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
198 /// to create the operation without changing the insertion position. The
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
199 /// generated operation is expected to be constant-like. On success, this hook
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
200 /// should return the value generated to represent the constant value.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
201 /// Otherwise, it should return nullptr on failure.
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
202 Operation *MyDialect::materializeConstant(OpBuilder &builder, Attribute value,
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
203 Type type, Location loc) {
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
204 ...
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
205 }
0572611fdcc8 reorgnization done
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
206 ```