MLIR  18.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 
4 #include "mlir/Pass/Pass.h"
5 
6 namespace mlir {
7 class FunctionOpInterface;
8 class ModuleOp;
9 class RewritePatternSet;
10 class OpBuilder;
11 class SymbolTable;
12 
13 namespace func {
14 class FuncOp;
15 } // namespace func
16 
17 namespace bufferization {
18 struct OneShotBufferizationOptions;
19 
20 //===----------------------------------------------------------------------===//
21 // Passes
22 //===----------------------------------------------------------------------===//
23 
24 #define GEN_PASS_DECL
25 #include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
26 
27 /// Creates an instance of the BufferDeallocation pass to free all allocated
28 /// buffers.
29 std::unique_ptr<Pass> createBufferDeallocationPass();
30 
31 /// Creates an instance of the OwnershipBasedBufferDeallocation pass to free all
32 /// allocated buffers.
33 std::unique_ptr<Pass> createOwnershipBasedBufferDeallocationPass(
34  bool privateFuncDynamicOwnership = false);
35 
36 /// Creates a pass that optimizes `bufferization.dealloc` operations. For
37 /// example, it reduces the number of alias checks needed at runtime using
38 /// static alias analysis.
39 std::unique_ptr<Pass> createBufferDeallocationSimplificationPass();
40 
41 /// Creates an instance of the LowerDeallocations pass to lower
42 /// `bufferization.dealloc` operations to the `memref` dialect.
43 std::unique_ptr<Pass> createLowerDeallocationsPass();
44 
45 /// Adds the conversion pattern of the `bufferization.dealloc` operation to the
46 /// given pattern set for use in other transformation passes.
48  RewritePatternSet &patterns, func::FuncOp deallocLibraryFunc);
49 
50 /// Construct the library function needed for the fully generic
51 /// `bufferization.dealloc` lowering implemented in the LowerDeallocations pass.
52 /// The function can then be called at bufferization dealloc sites to determine
53 /// aliasing and ownership.
54 ///
55 /// The generated function takes two memrefs of indices and three memrefs of
56 /// booleans as arguments:
57 /// * The first argument A should contain the result of the
58 /// extract_aligned_pointer_as_index operation applied to the memrefs to be
59 /// deallocated
60 /// * The second argument B should contain the result of the
61 /// extract_aligned_pointer_as_index operation applied to the memrefs to be
62 /// retained
63 /// * The third argument C should contain the conditions as passed directly
64 /// to the deallocation operation.
65 /// * The fourth argument D is used to pass results to the caller. Those
66 /// represent the condition under which the memref at the corresponding
67 /// position in A should be deallocated.
68 /// * The fifth argument E is used to pass results to the caller. It
69 /// provides the ownership value corresponding the the memref at the same
70 /// position in B
71 ///
72 /// This helper function is supposed to be called once for each
73 /// `bufferization.dealloc` operation to determine the deallocation need and new
74 /// ownership indicator for the retained values, but does not perform the
75 /// deallocation itself.
76 ///
77 /// Generated code:
78 /// ```
79 /// func.func @dealloc_helper(
80 /// %dyn_dealloc_base_pointer_list: memref<?xindex>,
81 /// %dyn_retain_base_pointer_list: memref<?xindex>,
82 /// %dyn_cond_list: memref<?xi1>,
83 /// %dyn_dealloc_cond_out: memref<?xi1>,
84 /// %dyn_ownership_out: memref<?xi1>) {
85 /// %c0 = arith.constant 0 : index
86 /// %c1 = arith.constant 1 : index
87 /// %true = arith.constant true
88 /// %false = arith.constant false
89 /// %num_dealloc_memrefs = memref.dim %dyn_dealloc_base_pointer_list, %c0
90 /// %num_retain_memrefs = memref.dim %dyn_retain_base_pointer_list, %c0
91 /// // Zero initialize result buffer.
92 /// scf.for %i = %c0 to %num_retain_memrefs step %c1 {
93 /// memref.store %false, %dyn_ownership_out[%i] : memref<?xi1>
94 /// }
95 /// scf.for %i = %c0 to %num_dealloc_memrefs step %c1 {
96 /// %dealloc_bp = memref.load %dyn_dealloc_base_pointer_list[%i]
97 /// %cond = memref.load %dyn_cond_list[%i]
98 /// // Check for aliasing with retained memrefs.
99 /// %does_not_alias_retained = scf.for %j = %c0 to %num_retain_memrefs
100 /// step %c1 iter_args(%does_not_alias_aggregated = %true) -> (i1) {
101 /// %retain_bp = memref.load %dyn_retain_base_pointer_list[%j]
102 /// %does_alias = arith.cmpi eq, %retain_bp, %dealloc_bp : index
103 /// scf.if %does_alias {
104 /// %curr_ownership = memref.load %dyn_ownership_out[%j]
105 /// %updated_ownership = arith.ori %curr_ownership, %cond : i1
106 /// memref.store %updated_ownership, %dyn_ownership_out[%j]
107 /// }
108 /// %does_not_alias = arith.cmpi ne, %retain_bp, %dealloc_bp : index
109 /// %updated_aggregate = arith.andi %does_not_alias_aggregated,
110 /// %does_not_alias : i1
111 /// scf.yield %updated_aggregate : i1
112 /// }
113 /// // Check for aliasing with dealloc memrefs in the list before the
114 /// // current one, i.e.,
115 /// // `fix i, forall j < i: check_aliasing(%dyn_dealloc_base_pointer[j],
116 /// // %dyn_dealloc_base_pointer[i])`
117 /// %does_not_alias_any = scf.for %j = %c0 to %i step %c1
118 /// iter_args(%does_not_alias_agg = %does_not_alias_retained) -> (i1) {
119 /// %prev_dealloc_bp = memref.load %dyn_dealloc_base_pointer_list[%j]
120 /// %does_not_alias = arith.cmpi ne, %prev_dealloc_bp, %dealloc_bp
121 /// %updated_alias_agg = arith.andi %does_not_alias_agg, %does_not_alias
122 /// scf.yield %updated_alias_agg : i1
123 /// }
124 /// %dealloc_cond = arith.andi %does_not_alias_any, %cond : i1
125 /// memref.store %dealloc_cond, %dyn_dealloc_cond_out[%i] : memref<?xi1>
126 /// }
127 /// return
128 /// }
129 /// ```
130 func::FuncOp buildDeallocationLibraryFunction(OpBuilder &builder, Location loc,
131  SymbolTable &symbolTable);
132 
133 /// Run buffer deallocation.
134 LogicalResult deallocateBuffers(Operation *op);
135 
136 /// Run ownership basedbuffer deallocation.
137 LogicalResult deallocateBuffersOwnershipBased(FunctionOpInterface op,
138  bool privateFuncDynamicOwnership);
139 
140 /// Creates a pass that moves allocations upwards to reduce the number of
141 /// required copies that are inserted during the BufferDeallocation pass.
142 std::unique_ptr<Pass> createBufferHoistingPass();
143 
144 /// Creates a pass that moves allocations upwards out of loops. This avoids
145 /// reallocations inside of loops.
146 std::unique_ptr<Pass> createBufferLoopHoistingPass();
147 
148 // Options struct for BufferResultsToOutParams pass.
149 // Note: defined only here, not in tablegen.
151  // Filter function; returns true if the function should be converted.
152  // Defaults to true, i.e. all functions are converted.
153  llvm::function_ref<bool(func::FuncOp *)> filterFn = [](func::FuncOp *func) {
154  return true;
155  };
156 };
157 
158 /// Creates a pass that converts memref function results to out-params.
159 std::unique_ptr<Pass> createBufferResultsToOutParamsPass(
160  const BufferResultsToOutParamsOptions &options = {});
161 
162 /// Replace buffers that are returned from a function with an out parameter.
163 /// Also update all call sites.
164 LogicalResult
165 promoteBufferResultsToOutParams(ModuleOp module,
166  const BufferResultsToOutParamsOptions &options);
167 
168 /// Creates a pass that drops memref function results that are equivalent to a
169 /// function argument.
170 std::unique_ptr<Pass> createDropEquivalentBufferResultsPass();
171 
172 /// Create a pass that rewrites tensor.empty to bufferization.alloc_tensor.
173 std::unique_ptr<Pass> createEmptyTensorToAllocTensorPass();
174 
175 /// Drop all memref function results that are equivalent to a function argument.
176 LogicalResult dropEquivalentBufferResults(ModuleOp module);
177 
178 /// Creates a pass that finalizes a partial bufferization by removing remaining
179 /// bufferization.to_tensor and bufferization.to_memref operations.
180 std::unique_ptr<OperationPass<func::FuncOp>> createFinalizingBufferizePass();
181 
182 /// Create a pass that bufferizes all ops that implement BufferizableOpInterface
183 /// with One-Shot Bufferize.
184 std::unique_ptr<Pass> createOneShotBufferizePass();
185 
186 /// Create a pass that bufferizes all ops that implement BufferizableOpInterface
187 /// with One-Shot Bufferize and the specified bufferization options.
188 std::unique_ptr<Pass>
189 createOneShotBufferizePass(const OneShotBufferizationOptions &options);
190 
191 /// Creates a pass that promotes heap-based allocations to stack-based ones.
192 /// Only buffers smaller than the provided size are promoted.
193 /// Dynamic shaped buffers are promoted up to the given rank.
194 std::unique_ptr<Pass>
195 createPromoteBuffersToStackPass(unsigned maxAllocSizeInBytes = 1024,
196  unsigned maxRankOfAllocatedMemRef = 1);
197 
198 /// Creates a pass that promotes heap-based allocations to stack-based ones.
199 /// Only buffers smaller with `isSmallAlloc(alloc) == true` are promoted.
200 std::unique_ptr<Pass>
201 createPromoteBuffersToStackPass(std::function<bool(Value)> isSmallAlloc);
202 
203 /// Create a pass that tries to eliminate tensor.empty ops that are anchored on
204 /// insert_slice ops.
205 std::unique_ptr<Pass> createEmptyTensorEliminationPass();
206 
207 /// Create a pass that bufferizes ops from the bufferization dialect.
208 std::unique_ptr<Pass> createBufferizationBufferizePass();
209 
210 //===----------------------------------------------------------------------===//
211 // Registration
212 //===----------------------------------------------------------------------===//
213 
214 /// Generate the code for registering passes.
215 #define GEN_PASS_REGISTRATION
216 #include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
217 
218 } // namespace bufferization
219 } // namespace mlir
220 
221 #endif // MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_PASSES_H
static llvm::ManagedStatic< PassManagerOptions > options
std::unique_ptr< Pass > createDropEquivalentBufferResultsPass()
Creates a pass that drops memref function results that are equivalent to a function argument.
std::unique_ptr< Pass > createBufferHoistingPass()
Creates a pass that moves allocations upwards to reduce the number of required copies that are insert...
std::unique_ptr< Pass > createOwnershipBasedBufferDeallocationPass(bool privateFuncDynamicOwnership=false)
Creates an instance of the OwnershipBasedBufferDeallocation pass to free all allocated buffers.
std::unique_ptr< Pass > createLowerDeallocationsPass()
Creates an instance of the LowerDeallocations pass to lower bufferization.dealloc operations to the m...
LogicalResult promoteBufferResultsToOutParams(ModuleOp module, const BufferResultsToOutParamsOptions &options)
Replace buffers that are returned from a function with an out parameter.
std::unique_ptr< OperationPass< func::FuncOp > > createFinalizingBufferizePass()
Creates a pass that finalizes a partial bufferization by removing remaining bufferization....
Definition: Bufferize.cpp:345
std::unique_ptr< Pass > createOneShotBufferizePass()
Create a pass that bufferizes all ops that implement BufferizableOpInterface with One-Shot Bufferize.
Definition: Bufferize.cpp:335
LogicalResult deallocateBuffers(Operation *op)
Run buffer deallocation.
std::unique_ptr< Pass > createBufferDeallocationSimplificationPass()
Creates a pass that optimizes bufferization.dealloc operations.
std::unique_ptr< Pass > createBufferLoopHoistingPass()
Creates a pass that moves allocations upwards out of loops.
std::unique_ptr< Pass > createBufferResultsToOutParamsPass(const BufferResultsToOutParamsOptions &options={})
Creates a pass that converts memref function results to out-params.
std::unique_ptr< Pass > createEmptyTensorEliminationPass()
Create a pass that tries to eliminate tensor.empty ops that are anchored on insert_slice ops.
std::unique_ptr< Pass > createPromoteBuffersToStackPass(unsigned maxAllocSizeInBytes=1024, unsigned maxRankOfAllocatedMemRef=1)
Creates a pass that promotes heap-based allocations to stack-based ones.
LogicalResult deallocateBuffersOwnershipBased(FunctionOpInterface op, bool privateFuncDynamicOwnership)
Run ownership basedbuffer deallocation.
std::unique_ptr< Pass > createBufferDeallocationPass()
Creates an instance of the BufferDeallocation pass to free all allocated buffers.
func::FuncOp buildDeallocationLibraryFunction(OpBuilder &builder, Location loc, SymbolTable &symbolTable)
Construct the library function needed for the fully generic bufferization.dealloc lowering implemente...
void populateBufferizationDeallocLoweringPattern(RewritePatternSet &patterns, func::FuncOp deallocLibraryFunc)
Adds the conversion pattern of the bufferization.dealloc operation to the given pattern set for use i...
LogicalResult dropEquivalentBufferResults(ModuleOp module)
Drop all memref function results that are equivalent to a function argument.
std::unique_ptr< Pass > createEmptyTensorToAllocTensorPass()
Create a pass that rewrites tensor.empty to bufferization.alloc_tensor.
std::unique_ptr< Pass > createBufferizationBufferizePass()
Create a pass that bufferizes ops from the bufferization dialect.
Definition: Bufferize.cpp:331
Include the generated interface declarations.
llvm::function_ref< bool(func::FuncOp *)> filterFn
Definition: Passes.h:153