MLIR 23.0.0git
Passes.h
Go to the documentation of this file.
1#ifndef MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_PASSES_H
2#define MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_PASSES_H
3
9namespace mlir {
10class FunctionOpInterface;
11class MemRefType;
12class ModuleOp;
13class RewritePatternSet;
14class OpBuilder;
15class SymbolTable;
17namespace func {
18class FuncOp;
19} // namespace func
20
21namespace bufferization {
23
24/// Maps from symbol table to its corresponding dealloc helper function.
26
27//===----------------------------------------------------------------------===//
28// Passes
29//===----------------------------------------------------------------------===//
30
31#define GEN_PASS_DECL
32#include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
33
34/// Adds the conversion pattern of the `bufferization.dealloc` operation to the
35/// given pattern set for use in other transformation passes.
37 RewritePatternSet &patterns, const DeallocHelperMap &deallocHelperFuncMap);
38
39/// Construct the library function needed for the fully generic
40/// `bufferization.dealloc` lowering implemented in the LowerDeallocations pass.
41/// The function can then be called at bufferization dealloc sites to determine
42/// aliasing and ownership.
43///
44/// The generated function takes two memrefs of indices and three memrefs of
45/// booleans as arguments:
46/// * The first argument A should contain the result of the
47/// extract_aligned_pointer_as_index operation applied to the memrefs to be
48/// deallocated
49/// * The second argument B should contain the result of the
50/// extract_aligned_pointer_as_index operation applied to the memrefs to be
51/// retained
52/// * The third argument C should contain the conditions as passed directly
53/// to the deallocation operation.
54/// * The fourth argument D is used to pass results to the caller. Those
55/// represent the condition under which the memref at the corresponding
56/// position in A should be deallocated.
57/// * The fifth argument E is used to pass results to the caller. It
58/// provides the ownership value corresponding the the memref at the same
59/// position in B
60///
61/// This helper function is supposed to be called once for each
62/// `bufferization.dealloc` operation to determine the deallocation need and new
63/// ownership indicator for the retained values, but does not perform the
64/// deallocation itself.
65///
66/// Generated code:
67/// ```
68/// func.func @dealloc_helper(
69/// %dyn_dealloc_base_pointer_list: memref<?xindex>,
70/// %dyn_retain_base_pointer_list: memref<?xindex>,
71/// %dyn_cond_list: memref<?xi1>,
72/// %dyn_dealloc_cond_out: memref<?xi1>,
73/// %dyn_ownership_out: memref<?xi1>) {
74/// %c0 = arith.constant 0 : index
75/// %c1 = arith.constant 1 : index
76/// %true = arith.constant true
77/// %false = arith.constant false
78/// %num_dealloc_memrefs = memref.dim %dyn_dealloc_base_pointer_list, %c0
79/// %num_retain_memrefs = memref.dim %dyn_retain_base_pointer_list, %c0
80/// // Zero initialize result buffer.
81/// scf.for %i = %c0 to %num_retain_memrefs step %c1 {
82/// memref.store %false, %dyn_ownership_out[%i] : memref<?xi1>
83/// }
84/// scf.for %i = %c0 to %num_dealloc_memrefs step %c1 {
85/// %dealloc_bp = memref.load %dyn_dealloc_base_pointer_list[%i]
86/// %cond = memref.load %dyn_cond_list[%i]
87/// // Check for aliasing with retained memrefs.
88/// %does_not_alias_retained = scf.for %j = %c0 to %num_retain_memrefs
89/// step %c1 iter_args(%does_not_alias_aggregated = %true) -> (i1) {
90/// %retain_bp = memref.load %dyn_retain_base_pointer_list[%j]
91/// %does_alias = arith.cmpi eq, %retain_bp, %dealloc_bp : index
92/// scf.if %does_alias {
93/// %curr_ownership = memref.load %dyn_ownership_out[%j]
94/// %updated_ownership = arith.ori %curr_ownership, %cond : i1
95/// memref.store %updated_ownership, %dyn_ownership_out[%j]
96/// }
97/// %does_not_alias = arith.cmpi ne, %retain_bp, %dealloc_bp : index
98/// %updated_aggregate = arith.andi %does_not_alias_aggregated,
99/// %does_not_alias : i1
100/// scf.yield %updated_aggregate : i1
101/// }
102/// // Check for aliasing with dealloc memrefs in the list before the
103/// // current one, i.e.,
104/// // `fix i, forall j < i: check_aliasing(%dyn_dealloc_base_pointer[j],
105/// // %dyn_dealloc_base_pointer[i])`
106/// %does_not_alias_any = scf.for %j = %c0 to %i step %c1
107/// iter_args(%does_not_alias_agg = %does_not_alias_retained) -> (i1) {
108/// %prev_dealloc_bp = memref.load %dyn_dealloc_base_pointer_list[%j]
109/// %does_not_alias = arith.cmpi ne, %prev_dealloc_bp, %dealloc_bp
110/// %updated_alias_agg = arith.andi %does_not_alias_agg, %does_not_alias
111/// scf.yield %updated_alias_agg : i1
112/// }
113/// %dealloc_cond = arith.andi %does_not_alias_any, %cond : i1
114/// memref.store %dealloc_cond, %dyn_dealloc_cond_out[%i] : memref<?xi1>
115/// }
116/// return
117/// }
118/// ```
119func::FuncOp buildDeallocationLibraryFunction(OpBuilder &builder, Location loc,
120 SymbolTable &symbolTable);
121
122/// Run the ownership-based buffer deallocation.
123LogicalResult
124deallocateBuffersOwnershipBased(FunctionOpInterface op,
126 SymbolTableCollection &symbolTables);
127
128// Options struct for BufferResultsToOutParams pass.
129// Note: defined only here, not in tablegen.
131 /// Allocator function: Generate a memref allocation with the given type.
132 /// Since `promoteBufferResultsToOutParams` doesn't allow dynamically shaped
133 /// results, we don't allow passing a range of values for dynamic dims.
134 using AllocationFn = std::function<FailureOr<Value>(OpBuilder &, Location,
135 MemRefType, ValueRange)>;
136
137 /// Memcpy function: Generate a memcpy between two memrefs.
138 using MemCpyFn =
139 std::function<LogicalResult(OpBuilder &, Location, Value, Value)>;
140
141 // Filter function; returns true if the function should be converted.
142 // Defaults to true, i.e. all functions are converted.
143 std::function<bool(func::FuncOp *)> filterFn = [](func::FuncOp *func) {
144 return true;
145 };
146
147 /// Allocation function; used to allocate a memref.
148 /// Default memref.alloc is used
150 MemRefType type, ValueRange dynamicSizes) {
151 return memref::AllocOp::create(builder, loc, type, dynamicSizes)
152 .getResult();
153 };
154
155 /// Memcpy function; used to create a copy between two memrefs.
156 /// Default memref.copy is used.
157 MemCpyFn memCpyFn = [](OpBuilder &builder, Location loc, Value from,
158 Value to) {
159 memref::CopyOp::create(builder, loc, from, to);
160 return success();
161 };
162
163 /// If true, the pass adds a "bufferize.result" attribute to each output
164 /// parameter.
165 bool addResultAttribute = false;
166
167 /// If true, the pass eliminates the memref.alloc and memcpy if the returned
168 /// memref is allocated in the current function.
169 bool hoistStaticAllocs = false;
170
171 /// If true, the pass eliminates the memref.alloc and memcpy if the returned
172 /// memref is allocated in the current function and has dynamic shape.
173 bool hoistDynamicAllocs = false;
174
175 /// If true, the pass modifies the function signatures of public functions.
177};
178
179/// Replace buffers that are returned from a function with an out parameter.
180/// Also update all call sites.
181LogicalResult
182promoteBufferResultsToOutParams(ModuleOp module,
184
185/// Options for dropping equivalent memref buffer results.
187 /// If true, signatures of public functions are modified.
189};
190
191/// Drop all memref function results that are equivalent to a function argument.
192LogicalResult dropEquivalentBufferResults(
194
195/// Creates a pass that promotes heap-based allocations to stack-based ones.
196/// Only buffers smaller with `isSmallAlloc(alloc) == true` are promoted.
197std::unique_ptr<Pass>
198createPromoteBuffersToStackPass(std::function<bool(Value)> isSmallAlloc);
199
200//===----------------------------------------------------------------------===//
201// Registration
202//===----------------------------------------------------------------------===//
203
204/// Generate the code for registering passes.
205#define GEN_PASS_REGISTRATION
206#include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
207
208} // namespace bufferization
209} // namespace mlir
210
211#endif // MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_PASSES_H
return success()
static llvm::ManagedStatic< PassManagerOptions > options
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
This class helps build Operations.
Definition Builders.h:209
This class represents a collection of SymbolTables.
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
LogicalResult deallocateBuffersOwnershipBased(FunctionOpInterface op, DeallocationOptions options, SymbolTableCollection &symbolTables)
Run the ownership-based buffer deallocation.
std::unique_ptr<::mlir::Pass > createPromoteBuffersToStackPass()
LogicalResult promoteBufferResultsToOutParams(ModuleOp module, const BufferResultsToOutParamsOpts &options)
Replace buffers that are returned from a function with an out parameter.
void populateBufferizationDeallocLoweringPattern(RewritePatternSet &patterns, const DeallocHelperMap &deallocHelperFuncMap)
Adds the conversion pattern of the bufferization.dealloc operation to the given pattern set for use i...
LogicalResult dropEquivalentBufferResults(ModuleOp module, DropBufferResultsOpts options=DropBufferResultsOpts())
Drop all memref function results that are equivalent to a function argument.
llvm::DenseMap< Operation *, func::FuncOp > DeallocHelperMap
Maps from symbol table to its corresponding dealloc helper function.
Definition Passes.h:25
func::FuncOp buildDeallocationLibraryFunction(OpBuilder &builder, Location loc, SymbolTable &symbolTable)
Construct the library function needed for the fully generic bufferization.dealloc lowering implemente...
Include the generated interface declarations.
bool hoistDynamicAllocs
If true, the pass eliminates the memref.alloc and memcpy if the returned memref is allocated in the c...
Definition Passes.h:173
bool modifyPublicFunctions
If true, the pass modifies the function signatures of public functions.
Definition Passes.h:176
MemCpyFn memCpyFn
Memcpy function; used to create a copy between two memrefs.
Definition Passes.h:157
bool hoistStaticAllocs
If true, the pass eliminates the memref.alloc and memcpy if the returned memref is allocated in the c...
Definition Passes.h:169
std::function< LogicalResult(OpBuilder &, Location, Value, Value)> MemCpyFn
Memcpy function: Generate a memcpy between two memrefs.
Definition Passes.h:138
std::function< FailureOr< Value >(OpBuilder &, Location, MemRefType, ValueRange)> AllocationFn
Allocator function: Generate a memref allocation with the given type.
Definition Passes.h:134
AllocationFn allocationFn
Allocation function; used to allocate a memref.
Definition Passes.h:149
bool addResultAttribute
If true, the pass adds a "bufferize.result" attribute to each output parameter.
Definition Passes.h:165
std::function< bool(func::FuncOp *)> filterFn
Definition Passes.h:143
Options for BufferDeallocationOpInterface-based buffer deallocation.
Options for dropping equivalent memref buffer results.
Definition Passes.h:186
bool modifyPublicFunctions
If true, signatures of public functions are modified.
Definition Passes.h:188
Options for analysis-enabled bufferization.