MLIR  21.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 
7 #include "mlir/Pass/Pass.h"
8 
9 namespace mlir {
10 class FunctionOpInterface;
11 class MemRefType;
12 class ModuleOp;
13 class RewritePatternSet;
14 class OpBuilder;
15 class SymbolTable;
16 
17 namespace func {
18 class FuncOp;
19 } // namespace func
20 
21 namespace bufferization {
22 struct OneShotBufferizationOptions;
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 /// ```
119 func::FuncOp buildDeallocationLibraryFunction(OpBuilder &builder, Location loc,
120  SymbolTable &symbolTable);
121 
122 /// Run the ownership-based buffer deallocation.
123 LogicalResult deallocateBuffersOwnershipBased(FunctionOpInterface op,
124  DeallocationOptions options);
125 
126 // Options struct for BufferResultsToOutParams pass.
127 // Note: defined only here, not in tablegen.
129  /// Allocator function: Generate a memref allocation with the given type.
130  /// Since `promoteBufferResultsToOutParams` doesn't allow dynamically shaped
131  /// results, we don't allow passing a range of values for dynamic dims.
132  using AllocationFn =
133  std::function<FailureOr<Value>(OpBuilder &, Location, MemRefType)>;
134 
135  /// Memcpy function: Generate a memcpy between two memrefs.
136  using MemCpyFn =
137  std::function<LogicalResult(OpBuilder &, Location, Value, Value)>;
138 
139  // Filter function; returns true if the function should be converted.
140  // Defaults to true, i.e. all functions are converted.
141  std::function<bool(func::FuncOp *)> filterFn = [](func::FuncOp *func) {
142  return true;
143  };
144 
145  /// Allocation function; used to allocate a memref.
146  /// Default memref.alloc is used
148  MemRefType type) {
149  return builder.create<memref::AllocOp>(loc, type).getResult();
150  };
151 
152  /// Memcpy function; used to create a copy between two memrefs.
153  /// Default memref.copy is used.
154  MemCpyFn memCpyFn = [](OpBuilder &builder, Location loc, Value from,
155  Value to) {
156  builder.create<memref::CopyOp>(loc, from, to);
157  return success();
158  };
159 
160  /// If true, the pass adds a "bufferize.result" attribute to each output
161  /// parameter.
162  bool addResultAttribute = false;
163 
164  /// If true, the pass eliminates the memref.alloc and memcpy if the returned
165  /// memref is allocated in the current function.
166  bool hoistStaticAllocs = false;
167 };
168 
169 /// Replace buffers that are returned from a function with an out parameter.
170 /// Also update all call sites.
171 LogicalResult
172 promoteBufferResultsToOutParams(ModuleOp module,
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 promotes heap-based allocations to stack-based ones.
179 /// Only buffers smaller with `isSmallAlloc(alloc) == true` are promoted.
180 std::unique_ptr<Pass>
181 createPromoteBuffersToStackPass(std::function<bool(Value)> isSmallAlloc);
182 
183 //===----------------------------------------------------------------------===//
184 // Registration
185 //===----------------------------------------------------------------------===//
186 
187 /// Generate the code for registering passes.
188 #define GEN_PASS_REGISTRATION
189 #include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
190 
191 } // namespace bufferization
192 } // namespace mlir
193 
194 #endif // MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_PASSES_H
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:66
This class helps build Operations.
Definition: Builders.h:204
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:453
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
std::unique_ptr< Pass > createPromoteBuffersToStackPass(std::function< bool(Value)> isSmallAlloc)
Creates a pass that promotes heap-based allocations to stack-based ones.
LogicalResult promoteBufferResultsToOutParams(ModuleOp module, const BufferResultsToOutParamsOpts &options)
Replace buffers that are returned from a function with an out parameter.
llvm::DenseMap< Operation *, func::FuncOp > DeallocHelperMap
Maps from symbol table to its corresponding dealloc helper function.
Definition: Passes.h:25
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 deallocateBuffersOwnershipBased(FunctionOpInterface op, DeallocationOptions options)
Run the ownership-based buffer deallocation.
func::FuncOp buildDeallocationLibraryFunction(OpBuilder &builder, Location loc, SymbolTable &symbolTable)
Construct the library function needed for the fully generic bufferization.dealloc lowering implemente...
LogicalResult dropEquivalentBufferResults(ModuleOp module)
Drop all memref function results that are equivalent to a function argument.
Include the generated interface declarations.
const FrozenRewritePatternSet & patterns
std::function< LogicalResult(OpBuilder &, Location, Value, Value)> MemCpyFn
Memcpy function: Generate a memcpy between two memrefs.
Definition: Passes.h:137
std::function< FailureOr< Value >(OpBuilder &, Location, MemRefType)> AllocationFn
Allocator function: Generate a memref allocation with the given type.
Definition: Passes.h:133
MemCpyFn memCpyFn
Memcpy function; used to create a copy between two memrefs.
Definition: Passes.h:154
bool hoistStaticAllocs
If true, the pass eliminates the memref.alloc and memcpy if the returned memref is allocated in the c...
Definition: Passes.h:166
AllocationFn allocationFn
Allocation function; used to allocate a memref.
Definition: Passes.h:147
bool addResultAttribute
If true, the pass adds a "bufferize.result" attribute to each output parameter.
Definition: Passes.h:162
std::function< bool(func::FuncOp *)> filterFn
Definition: Passes.h:141