MLIR  21.0.0git
Transforms.h
Go to the documentation of this file.
1 //===- Transforms.h - MemRef Dialect transformations ------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// This header declares functions that assist transformations in the MemRef
10 /// dialect.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_DIALECT_MEMREF_TRANSFORMS_TRANSFORMS_H
15 #define MLIR_DIALECT_MEMREF_TRANSFORMS_TRANSFORMS_H
16 
17 #include "mlir/Support/LLVM.h"
18 #include "llvm/ADT/STLFunctionalExtras.h"
19 
20 namespace mlir {
21 class OpBuilder;
22 class RewritePatternSet;
23 class RewriterBase;
24 class Value;
25 class ValueRange;
26 class ReifyRankedShapedTypeOpInterface;
27 
28 namespace arith {
29 class WideIntEmulationConverter;
30 class NarrowTypeEmulationConverter;
31 } // namespace arith
32 
33 namespace memref {
34 class AllocOp;
35 class AllocaOp;
36 class DeallocOp;
37 
38 //===----------------------------------------------------------------------===//
39 // Patterns
40 //===----------------------------------------------------------------------===//
41 
42 /// Collects a set of patterns to rewrite ops within the memref dialect.
43 void populateExpandOpsPatterns(RewritePatternSet &patterns);
44 
45 /// Appends patterns for folding memref aliasing ops into consumer load/store
46 /// ops into `patterns`.
47 void populateFoldMemRefAliasOpPatterns(RewritePatternSet &patterns);
48 
49 /// Appends patterns that resolve `memref.dim` operations with values that are
50 /// defined by operations that implement the
51 /// `ReifyRankedShapedTypeOpInterface`, in terms of shapes of its input
52 /// operands.
54  RewritePatternSet &patterns);
55 
56 /// Appends patterns that resolve `memref.dim` operations with values that are
57 /// defined by operations that implement the `InferShapedTypeOpInterface`, in
58 /// terms of shapes of its input operands.
60 
61 /// Appends patterns for expanding memref operations that modify the metadata
62 /// (sizes, offset, strides) of a memref into easier to analyze constructs.
63 void populateExpandStridedMetadataPatterns(RewritePatternSet &patterns);
64 
65 /// Appends patterns for resolving `memref.extract_strided_metadata` into
66 /// `memref.extract_strided_metadata` of its source.
68 
69 /// Appends patterns for expanding `memref.realloc` operations.
70 void populateExpandReallocPatterns(RewritePatternSet &patterns,
71  bool emitDeallocs = true);
72 
73 /// Appends patterns for emulating wide integer memref operations with ops over
74 /// narrower integer types.
76  const arith::WideIntEmulationConverter &typeConverter,
77  RewritePatternSet &patterns);
78 
79 /// Appends type conversions for emulating wide integer memref operations with
80 /// ops over narrowe integer types.
82  arith::WideIntEmulationConverter &typeConverter);
83 
84 /// Appends patterns for emulating memref operations over narrow types with ops
85 /// over wider types.
87  const arith::NarrowTypeEmulationConverter &typeConverter,
88  RewritePatternSet &patterns);
89 
90 /// Appends type conversions for emulating memref operations over narrow types
91 /// with ops over wider types.
93  arith::NarrowTypeEmulationConverter &typeConverter);
94 
95 /// Transformation to do multi-buffering/array expansion to remove dependencies
96 /// on the temporary allocation between consecutive loop iterations.
97 /// It returns the new allocation if the original allocation was multi-buffered
98 /// and returns failure() otherwise.
99 /// When `skipOverrideAnalysis`, the pass will apply the transformation
100 /// without checking thwt the buffer is overrided at the beginning of each
101 /// iteration. This implies that user knows that there is no data carried across
102 /// loop iterations. Example:
103 /// ```
104 /// %0 = memref.alloc() : memref<4x128xf32>
105 /// scf.for %iv = %c1 to %c1024 step %c3 {
106 /// memref.copy %1, %0 : memref<4x128xf32> to memref<4x128xf32>
107 /// "some_use"(%0) : (memref<4x128xf32>) -> ()
108 /// }
109 /// ```
110 /// into:
111 /// ```
112 /// %0 = memref.alloc() : memref<5x4x128xf32>
113 /// scf.for %iv = %c1 to %c1024 step %c3 {
114 /// %s = arith.subi %iv, %c1 : index
115 /// %d = arith.divsi %s, %c3 : index
116 /// %i = arith.remsi %d, %c5 : index
117 /// %sv = memref.subview %0[%i, 0, 0] [1, 4, 128] [1, 1, 1] :
118 /// memref<5x4x128xf32> to memref<4x128xf32, strided<[128, 1], offset: ?>>
119 /// memref.copy %1, %sv : memref<4x128xf32> to memref<4x128xf32, strided<...>>
120 /// "some_use"(%sv) : (memref<4x128xf32, strided<...>) -> ()
121 /// }
122 /// ```
123 FailureOr<memref::AllocOp> multiBuffer(RewriterBase &rewriter,
124  memref::AllocOp allocOp,
125  unsigned multiplier,
126  bool skipOverrideAnalysis = false);
127 /// Call into `multiBuffer` with locally constructed IRRewriter.
128 FailureOr<memref::AllocOp> multiBuffer(memref::AllocOp allocOp,
129  unsigned multiplier,
130  bool skipOverrideAnalysis = false);
131 
132 /// Appends patterns for extracting address computations from the instructions
133 /// with memory accesses such that these memory accesses use only a base
134 /// pointer.
135 ///
136 /// For instance,
137 /// ```mlir
138 /// memref.load %base[%off0, ...]
139 /// ```
140 ///
141 /// Will be rewritten in:
142 /// ```mlir
143 /// %new_base = memref.subview %base[%off0,...][1,...][1,...]
144 /// memref.load %new_base[%c0,...]
145 /// ```
147 
148 void populateFlattenMemrefsPatterns(RewritePatternSet &patterns);
149 
150 /// Build a new memref::AllocaOp whose dynamic sizes are independent of all
151 /// given independencies. If the op is already independent of all
152 /// independencies, the same AllocaOp result is returned.
153 ///
154 /// Failure indicates the no suitable upper bound for the dynamic sizes could be
155 /// found.
156 FailureOr<Value> buildIndependentOp(OpBuilder &b, AllocaOp allocaOp,
157  ValueRange independencies);
158 
159 /// Build a new memref::AllocaOp whose dynamic sizes are independent of all
160 /// given independencies. If the op is already independent of all
161 /// independencies, the same AllocaOp result is returned.
162 ///
163 /// The original AllocaOp is replaced with the new one, wrapped in a SubviewOp.
164 /// The result type of the replacement is different from the original allocation
165 /// type: it has the same shape, but a different layout map. This function
166 /// updates all users that do not have a memref result or memref region block
167 /// argument, and some frequently used memref dialect ops (such as
168 /// memref.subview). It does not update other uses such as the init_arg of an
169 /// scf.for op. Such uses are wrapped in unrealized_conversion_cast.
170 ///
171 /// Failure indicates the no suitable upper bound for the dynamic sizes could be
172 /// found.
173 ///
174 /// Example (make independent of %iv):
175 /// ```
176 /// scf.for %iv = %c0 to %sz step %c1 {
177 /// %0 = memref.alloca(%iv) : memref<?xf32>
178 /// %1 = memref.subview %0[0][5][1] : ...
179 /// linalg.generic outs(%1 : ...) ...
180 /// %2 = scf.for ... iter_arg(%arg0 = %0) ...
181 /// ...
182 /// }
183 /// ```
184 ///
185 /// The above IR is rewritten to:
186 ///
187 /// ```
188 /// scf.for %iv = %c0 to %sz step %c1 {
189 /// %0 = memref.alloca(%sz - 1) : memref<?xf32>
190 /// %0_subview = memref.subview %0[0][%iv][1]
191 /// : memref<?xf32> to memref<?xf32, #map>
192 /// %1 = memref.subview %0_subview[0][5][1] : ...
193 /// linalg.generic outs(%1 : ...) ...
194 /// %cast = unrealized_conversion_cast %0_subview
195 /// : memref<?xf32, #map> to memref<?xf32>
196 /// %2 = scf.for ... iter_arg(%arg0 = %cast) ...
197 /// ...
198 /// }
199 /// ```
200 FailureOr<Value> replaceWithIndependentOp(RewriterBase &rewriter,
201  memref::AllocaOp allocaOp,
202  ValueRange independencies);
203 
204 /// Replaces the given `alloc` with the corresponding `alloca` and returns it if
205 /// the following conditions are met:
206 /// - the corresponding dealloc is available in the same block as the alloc;
207 /// - the filter, if provided, succeeds on the alloc/dealloc pair.
208 /// Otherwise returns nullptr and leaves the IR unchanged.
209 memref::AllocaOp allocToAlloca(
210  RewriterBase &rewriter, memref::AllocOp alloc,
211  function_ref<bool(memref::AllocOp, memref::DeallocOp)> filter = nullptr);
212 } // namespace memref
213 } // namespace mlir
214 
215 #endif
This class helps build Operations.
Definition: Builders.h:205
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
Definition: PatternMatch.h:358
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:387
void populateFoldMemRefAliasOpPatterns(RewritePatternSet &patterns)
Appends patterns for folding memref aliasing ops into consumer load/store ops into patterns.
void populateMemRefWideIntEmulationPatterns(const arith::WideIntEmulationConverter &typeConverter, RewritePatternSet &patterns)
Appends patterns for emulating wide integer memref operations with ops over narrower integer types.
FailureOr< Value > buildIndependentOp(OpBuilder &b, AllocaOp allocaOp, ValueRange independencies)
Build a new memref::AllocaOp whose dynamic sizes are independent of all given independencies.
void populateResolveRankedShapedTypeResultDimsPatterns(RewritePatternSet &patterns)
Appends patterns that resolve memref.dim operations with values that are defined by operations that i...
FailureOr< Value > replaceWithIndependentOp(RewriterBase &rewriter, memref::AllocaOp allocaOp, ValueRange independencies)
Build a new memref::AllocaOp whose dynamic sizes are independent of all given independencies.
void populateMemRefNarrowTypeEmulationConversions(arith::NarrowTypeEmulationConverter &typeConverter)
Appends type conversions for emulating memref operations over narrow types with ops over wider types.
FailureOr< memref::AllocOp > multiBuffer(RewriterBase &rewriter, memref::AllocOp allocOp, unsigned multiplier, bool skipOverrideAnalysis=false)
Transformation to do multi-buffering/array expansion to remove dependencies on the temporary allocati...
Definition: MultiBuffer.cpp:98
void populateMemRefWideIntEmulationConversions(arith::WideIntEmulationConverter &typeConverter)
Appends type conversions for emulating wide integer memref operations with ops over narrowe integer t...
void populateFlattenMemrefsPatterns(RewritePatternSet &patterns)
void populateResolveExtractStridedMetadataPatterns(RewritePatternSet &patterns)
Appends patterns for resolving memref.extract_strided_metadata into memref.extract_strided_metadata o...
void populateExpandOpsPatterns(RewritePatternSet &patterns)
Collects a set of patterns to rewrite ops within the memref dialect.
Definition: ExpandOps.cpp:109
void populateResolveShapedTypeResultDimsPatterns(RewritePatternSet &patterns)
Appends patterns that resolve memref.dim operations with values that are defined by operations that i...
void populateMemRefNarrowTypeEmulationPatterns(const arith::NarrowTypeEmulationConverter &typeConverter, RewritePatternSet &patterns)
Appends patterns for emulating memref operations over narrow types with ops over wider types.
void populateExtractAddressComputationsPatterns(RewritePatternSet &patterns)
Appends patterns for extracting address computations from the instructions with memory accesses such ...
void populateExpandReallocPatterns(RewritePatternSet &patterns, bool emitDeallocs=true)
Appends patterns for expanding memref.realloc operations.
memref::AllocaOp allocToAlloca(RewriterBase &rewriter, memref::AllocOp alloc, function_ref< bool(memref::AllocOp, memref::DeallocOp)> filter=nullptr)
Replaces the given alloc with the corresponding alloca and returns it if the following conditions are...
void populateExpandStridedMetadataPatterns(RewritePatternSet &patterns)
Appends patterns for expanding memref operations that modify the metadata (sizes, offset,...
Include the generated interface declarations.
const FrozenRewritePatternSet & patterns