MLIR 22.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
20namespace mlir {
21class OpBuilder;
23class RewriterBase;
24class Value;
25class ValueRange;
26class ReifyRankedShapedTypeOpInterface;
27
28namespace arith {
31} // namespace arith
32
33namespace memref {
34class AllocOp;
35class AllocaOp;
36class DeallocOp;
37
38//===----------------------------------------------------------------------===//
39// Patterns
40//===----------------------------------------------------------------------===//
41
42/// Collects a set of patterns to rewrite ops within the memref dialect.
43void populateExpandOpsPatterns(RewritePatternSet &patterns);
44
45/// Appends patterns for folding memref aliasing ops into consumer load/store
46/// ops into `patterns`.
47void 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.
63void 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.
70void 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/// ```
123FailureOr<memref::AllocOp> multiBuffer(RewriterBase &rewriter,
124 memref::AllocOp allocOp,
125 unsigned multiplier,
126 bool skipOverrideAnalysis = false);
127/// Call into `multiBuffer` with locally constructed IRRewriter.
128FailureOr<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/// Patterns for flattening multi-dimensional memref operations into
149/// one-dimensional memref operations.
151void populateFlattenMemrefOpsPatterns(RewritePatternSet &patterns);
152void populateFlattenMemrefsPatterns(RewritePatternSet &patterns);
153
154/// Build a new memref::AllocaOp whose dynamic sizes are independent of all
155/// given independencies. If the op is already independent of all
156/// independencies, the same AllocaOp result is returned.
157///
158/// Failure indicates the no suitable upper bound for the dynamic sizes could be
159/// found.
160FailureOr<Value> buildIndependentOp(OpBuilder &b, AllocaOp allocaOp,
161 ValueRange independencies);
162
163/// Build a new memref::AllocaOp whose dynamic sizes are independent of all
164/// given independencies. If the op is already independent of all
165/// independencies, the same AllocaOp result is returned.
166///
167/// The original AllocaOp is replaced with the new one, wrapped in a SubviewOp.
168/// The result type of the replacement is different from the original allocation
169/// type: it has the same shape, but a different layout map. This function
170/// updates all users that do not have a memref result or memref region block
171/// argument, and some frequently used memref dialect ops (such as
172/// memref.subview). It does not update other uses such as the init_arg of an
173/// scf.for op. Such uses are wrapped in unrealized_conversion_cast.
174///
175/// Failure indicates the no suitable upper bound for the dynamic sizes could be
176/// found.
177///
178/// Example (make independent of %iv):
179/// ```
180/// scf.for %iv = %c0 to %sz step %c1 {
181/// %0 = memref.alloca(%iv) : memref<?xf32>
182/// %1 = memref.subview %0[0][5][1] : ...
183/// linalg.generic outs(%1 : ...) ...
184/// %2 = scf.for ... iter_arg(%arg0 = %0) ...
185/// ...
186/// }
187/// ```
188///
189/// The above IR is rewritten to:
190///
191/// ```
192/// scf.for %iv = %c0 to %sz step %c1 {
193/// %0 = memref.alloca(%sz - 1) : memref<?xf32>
194/// %0_subview = memref.subview %0[0][%iv][1]
195/// : memref<?xf32> to memref<?xf32, #map>
196/// %1 = memref.subview %0_subview[0][5][1] : ...
197/// linalg.generic outs(%1 : ...) ...
198/// %cast = unrealized_conversion_cast %0_subview
199/// : memref<?xf32, #map> to memref<?xf32>
200/// %2 = scf.for ... iter_arg(%arg0 = %cast) ...
201/// ...
202/// }
203/// ```
204FailureOr<Value> replaceWithIndependentOp(RewriterBase &rewriter,
205 memref::AllocaOp allocaOp,
206 ValueRange independencies);
207
208/// Replaces the given `alloc` with the corresponding `alloca` and returns it if
209/// the following conditions are met:
210/// - the corresponding dealloc is available in the same block as the alloc;
211/// - the filter, if provided, succeeds on the alloc/dealloc pair.
212/// Otherwise returns nullptr and leaves the IR unchanged.
213memref::AllocaOp allocToAlloca(
214 RewriterBase &rewriter, memref::AllocOp alloc,
215 function_ref<bool(memref::AllocOp, memref::DeallocOp)> filter = nullptr);
216} // namespace memref
217} // namespace mlir
218
219#endif
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
This class helps build Operations.
Definition Builders.h:207
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:387
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
Converts narrow integer or float types that are not supported by the target hardware to wider types.
Converts integer types that are too wide for the target by splitting them in two halves and thus turn...
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.
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...
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 populateFlattenMemrefOpsPatterns(RewritePatternSet &patterns)
void populateResolveExtractStridedMetadataPatterns(RewritePatternSet &patterns)
Appends patterns for resolving memref.extract_strided_metadata into memref.extract_strided_metadata o...
void populateFlattenVectorOpsOnMemrefPatterns(RewritePatternSet &patterns)
Patterns for flattening multi-dimensional memref operations into one-dimensional memref operations.
void populateExpandOpsPatterns(RewritePatternSet &patterns)
Collects a set of patterns to rewrite ops within the memref dialect.
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 ...
FailureOr< Value > buildIndependentOp(OpBuilder &b, AllocaOp allocaOp, ValueRange independencies)
Build a new memref::AllocaOp whose dynamic sizes are independent of all given independencies.
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
llvm::function_ref< Fn > function_ref
Definition LLVM.h:152