MLIR 23.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.
86/// When `disableAtomicRMW` is true, the store patterns generate non-atomic
87/// read-modify-write sequences instead of atomic operations.
89 const arith::NarrowTypeEmulationConverter &typeConverter,
90 RewritePatternSet &patterns, bool disableAtomicRMW = false);
91
92/// Appends type conversions for emulating memref operations over narrow types
93/// with ops over wider types.
95 arith::NarrowTypeEmulationConverter &typeConverter);
96
97/// Transformation to do multi-buffering/array expansion to remove dependencies
98/// on the temporary allocation between consecutive loop iterations.
99/// It returns the new allocation if the original allocation was multi-buffered
100/// and returns failure() otherwise.
101/// When `skipOverrideAnalysis`, the pass will apply the transformation
102/// without checking thwt the buffer is overrided at the beginning of each
103/// iteration. This implies that user knows that there is no data carried across
104/// loop iterations. Example:
105/// ```
106/// %0 = memref.alloc() : memref<4x128xf32>
107/// scf.for %iv = %c1 to %c1024 step %c3 {
108/// memref.copy %1, %0 : memref<4x128xf32> to memref<4x128xf32>
109/// "some_use"(%0) : (memref<4x128xf32>) -> ()
110/// }
111/// ```
112/// into:
113/// ```
114/// %0 = memref.alloc() : memref<5x4x128xf32>
115/// scf.for %iv = %c1 to %c1024 step %c3 {
116/// %s = arith.subi %iv, %c1 : index
117/// %d = arith.divsi %s, %c3 : index
118/// %i = arith.remsi %d, %c5 : index
119/// %sv = memref.subview %0[%i, 0, 0] [1, 4, 128] [1, 1, 1] :
120/// memref<5x4x128xf32> to memref<4x128xf32, strided<[128, 1], offset: ?>>
121/// memref.copy %1, %sv : memref<4x128xf32> to memref<4x128xf32, strided<...>>
122/// "some_use"(%sv) : (memref<4x128xf32, strided<...>) -> ()
123/// }
124/// ```
125FailureOr<memref::AllocOp> multiBuffer(RewriterBase &rewriter,
126 memref::AllocOp allocOp,
127 unsigned multiplier,
128 bool skipOverrideAnalysis = false);
129/// Call into `multiBuffer` with locally constructed IRRewriter.
130FailureOr<memref::AllocOp> multiBuffer(memref::AllocOp allocOp,
131 unsigned multiplier,
132 bool skipOverrideAnalysis = false);
133
134/// Appends patterns for extracting address computations from the instructions
135/// with memory accesses such that these memory accesses use only a base
136/// pointer.
137///
138/// For instance,
139/// ```mlir
140/// memref.load %base[%off0, ...]
141/// ```
142///
143/// Will be rewritten in:
144/// ```mlir
145/// %new_base = memref.subview %base[%off0,...][1,...][1,...]
146/// memref.load %new_base[%c0,...]
147/// ```
149
150/// Patterns for flattening multi-dimensional memref operations into
151/// one-dimensional memref operations.
153void populateFlattenMemrefOpsPatterns(RewritePatternSet &patterns);
154void populateFlattenMemrefsPatterns(RewritePatternSet &patterns);
155
156/// Build a new memref::AllocaOp whose dynamic sizes are independent of all
157/// given independencies. If the op is already independent of all
158/// independencies, the same AllocaOp result is returned.
159///
160/// Failure indicates the no suitable upper bound for the dynamic sizes could be
161/// found.
162FailureOr<Value> buildIndependentOp(OpBuilder &b, AllocaOp allocaOp,
163 ValueRange independencies);
164
165/// Build a new memref::AllocaOp whose dynamic sizes are independent of all
166/// given independencies. If the op is already independent of all
167/// independencies, the same AllocaOp result is returned.
168///
169/// The original AllocaOp is replaced with the new one, wrapped in a SubviewOp.
170/// The result type of the replacement is different from the original allocation
171/// type: it has the same shape, but a different layout map. This function
172/// updates all users that do not have a memref result or memref region block
173/// argument, and some frequently used memref dialect ops (such as
174/// memref.subview). It does not update other uses such as the init_arg of an
175/// scf.for op. Such uses are wrapped in unrealized_conversion_cast.
176///
177/// Failure indicates the no suitable upper bound for the dynamic sizes could be
178/// found.
179///
180/// Example (make independent of %iv):
181/// ```
182/// scf.for %iv = %c0 to %sz step %c1 {
183/// %0 = memref.alloca(%iv) : memref<?xf32>
184/// %1 = memref.subview %0[0][5][1] : ...
185/// linalg.generic outs(%1 : ...) ...
186/// %2 = scf.for ... iter_arg(%arg0 = %0) ...
187/// ...
188/// }
189/// ```
190///
191/// The above IR is rewritten to:
192///
193/// ```
194/// scf.for %iv = %c0 to %sz step %c1 {
195/// %0 = memref.alloca(%sz - 1) : memref<?xf32>
196/// %0_subview = memref.subview %0[0][%iv][1]
197/// : memref<?xf32> to memref<?xf32, #map>
198/// %1 = memref.subview %0_subview[0][5][1] : ...
199/// linalg.generic outs(%1 : ...) ...
200/// %cast = unrealized_conversion_cast %0_subview
201/// : memref<?xf32, #map> to memref<?xf32>
202/// %2 = scf.for ... iter_arg(%arg0 = %cast) ...
203/// ...
204/// }
205/// ```
206FailureOr<Value> replaceWithIndependentOp(RewriterBase &rewriter,
207 memref::AllocaOp allocaOp,
208 ValueRange independencies);
209
210/// Replaces the given `alloc` with the corresponding `alloca` and returns it if
211/// the following conditions are met:
212/// - the corresponding dealloc is available in the same block as the alloc;
213/// - the filter, if provided, succeeds on the alloc/dealloc pair.
214/// Otherwise returns nullptr and leaves the IR unchanged.
215memref::AllocaOp allocToAlloca(
216 RewriterBase &rewriter, memref::AllocOp alloc,
217 function_ref<bool(memref::AllocOp, memref::DeallocOp)> filter = nullptr);
218} // namespace memref
219} // namespace mlir
220
221#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 populateMemRefNarrowTypeEmulationPatterns(const arith::NarrowTypeEmulationConverter &typeConverter, RewritePatternSet &patterns, bool disableAtomicRMW=false)
Appends patterns for emulating memref operations over narrow types with ops over wider 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 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:144