@@ -33,6 +33,10 @@ together.
33
33
34
34
Some important things to think about w.r.t. canonicalization patterns:
35
35
36
+ * The goal of canonicalization is to make subsequent analyses and
37
+ optimizations more effective. Therefore, performance improvements are not
38
+ necessary for canonicalization.
39
+
36
40
* Pass pipelines should not rely on the canonicalizer pass for correctness.
37
41
They should work correctly with all instances of the canonicalization pass
38
42
removed.
@@ -51,6 +55,61 @@ Some important things to think about w.r.t. canonicalization patterns:
51
55
* It is always good to eliminate operations entirely when possible, e.g. by
52
56
folding known identities (like "x + 0 = x").
53
57
58
+ * Canonicalization isn't a great place to put pattens with expensive running
59
+ time (i.e. have O(n) complexity) or complicated cost models.
60
+
61
+ * Canonicalize shouldn't lose the semantic of original operation: the original
62
+ information should always be recoverable from the transformed IR.
63
+
64
+ For example, a pattern that transform
65
+
66
+ ```
67
+ %0 = tensor.insert_slice %slice into
68
+ %x[0, 0, 0, 0, 0][1, 1, 1, 16, 32][1, 1, 1, 1, 1] :
69
+ tensor<16x32xf32> into tensor<1x1x1x16x32xf32>
70
+ ```
71
+
72
+ to
73
+
74
+ ```
75
+ %0 = tensor.expand_shape %slice[[0,1,2,3], [4]] :
76
+ tensor<16x32xf32> into tensor<1x1x1x16x32xf32>
77
+ ```
78
+
79
+ is not a good canonicalize pattern because it lose the destination style
80
+ semantic.
81
+
82
+
83
+ A pattern that transform (linalg.transpose is only use of %broadcast)
84
+
85
+ ```
86
+ %broadcast = linalg.broadcast
87
+ ins(%input : tensor<2x4x5xf32>)
88
+ outs(%init1 : tensor<1x2x3x4x5x6xf32>)
89
+ dimensions = [0, 2, 5]
90
+ %transpose = linalg.transpose
91
+ ins(%broadcast : tensor<1x2x3x4x5x6xf32>)
92
+ outs(%init2 : tensor<1x6x2x3x5x4xf32>)
93
+ permutation = [0, 5, 1, 2, 4, 3]
94
+ ```
95
+
96
+ to
97
+
98
+ ```
99
+ %tranpose = linalg.transpose
100
+ ins(%input : tensor<2x4x5xf32>)
101
+ outs(%tmp_init : tensor<2x5x4xf32>)
102
+ permutation = [0, 2, 1]
103
+ %broadcast = linalg.broadcast
104
+ ins(%transpose : tensor<2x5x4xf32>)
105
+ outs(%init2 : tensor<1x6x2x3x5x4xf32>)
106
+ dimensions = [0, 3, 1]
107
+ ```
108
+
109
+ is a good canonicalize pattern because this pattern always transforms the
110
+ program towards reducing the amount of computational data and keeps the semantic
111
+ of original operation.
112
+
54
113
## Globally Applied Rules
55
114
56
115
These transformations are applied to all levels of IR:
@@ -189,7 +248,7 @@ each of the operands, returning the corresponding constant attribute. These
189
248
operands are those that implement the ` ConstantLike ` trait. If any of the
190
249
operands are non-constant, a null ` Attribute ` value is provided instead. For
191
250
example, if MyOp provides three operands [ ` a ` , ` b ` , ` c ` ] , but only ` b ` is
192
- constant then ` adaptor ` will return Attribute() for ` getA() ` and ` getC() ` ,
251
+ constant then ` adaptor ` will return Attribute() for ` getA() ` and ` getC() ` ,
193
252
and b-value for ` getB() ` .
194
253
195
254
Also above, is the use of ` OpFoldResult ` . This class represents the possible
0 commit comments