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