MLIR  16.0.0git
BufferizableOpInterface.h
Go to the documentation of this file.
1 //===- BufferizableOpInterface.h - Bufferizable Ops -------------*- 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 #ifndef MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZABLEOPINTERFACE_H_
10 #define MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZABLEOPINTERFACE_H_
11 
12 #include "mlir/IR/Operation.h"
13 #include "mlir/IR/PatternMatch.h"
14 #include "mlir/Support/LLVM.h"
15 #include "llvm/ADT/SetVector.h"
16 
17 namespace mlir {
18 class OpBuilder;
19 
20 namespace bufferization {
21 
22 class AnalysisState;
23 class BufferizableOpInterface;
25 
26 class OpFilter {
27 public:
28  /// An op filter entry. Filters can be used to specify which ops should be
29  /// processed by the bufferization.
30  struct Entry {
31  /// If the filter function evaluates to `true`, the filter matches.
32  using FilterFn = std::function<bool(Operation *)>;
33 
34  /// Filter type: A filter can either be a DENY filter or an ALLOW filter.
35  enum FilterType : int8_t { DENY = 0, ALLOW = 1 };
36 
39  };
40 
41  /// Return whether the op is allowed or not.
42  ///
43  /// If the filter does not have an ALLOW rule, ops are allowed by default,
44  /// unless they are explicitly marked as DENY. If the filter has at least one
45  /// ALLOW rule, ops are denied by default and only allowed if they match
46  /// an ALLOW rule and no DENY rule.
47  bool isOpAllowed(Operation *op) const;
48 
49  /// Allow the given dialects.
50  ///
51  /// This function adds one or multiple ALLOW entries.
52  template <typename... DialectTs>
53  void allowDialect() {
54  // The following expands a call to allowDialectImpl for each dialect
55  // in 'DialectTs'.
56  (allowDialectImpl<DialectTs>(), ...);
57  }
58 
59  /// Deny the given dialects.
60  ///
61  /// This function adds one or multiple DENY entries.
62  template <typename... DialectTs>
63  void denyDialect() {
64  (denyDialectImpl<DialectTs>(), ...);
65  }
66 
67  /// Allow the given dialect.
68  ///
69  /// This function adds an ALLOW entry.
70  void allowDialect(StringRef dialectNamespace) {
71  Entry::FilterFn filterFn = [=](Operation *op) {
72  return op->getDialect()->getNamespace() == dialectNamespace;
73  };
74  entries.push_back(Entry{filterFn, Entry::FilterType::ALLOW});
75  }
76 
77  /// Allow the given ops.
78  ///
79  /// This function adds one or multiple ALLOW entries.
80  template <typename... OpTys>
81  void allowOperation() {
82  (allowOperationImpl<OpTys>(), ...);
83  }
84 
85  /// Deny the given ops.
86  ///
87  /// This function adds one or multiple DENY entries.
88  template <typename... OpTys>
89  void denyOperation() {
90  (denyOperationImpl<OpTys>(), ...);
91  }
92 
93  /// Allow the given op.
94  ///
95  /// This function adds an ALLOW entry.
96  void allowOperation(StringRef opName) {
97  Entry::FilterFn filterFn = [=](Operation *op) {
98  return op->getName().getStringRef() == opName;
99  };
100  allowOperation(filterFn);
101  }
102 
103  /// Deny the given op.
104  ///
105  /// This function adds a DENY entry.
106  void denyOperation(StringRef opName) {
107  Entry::FilterFn filterFn = [=](Operation *op) {
108  return op->getName().getStringRef() == opName;
109  };
110  denyOperation(filterFn);
111  }
112 
113  /// Allow ops that are matched by `fn`.
114  ///
115  /// This function adds an ALLOW entry.
117  entries.push_back(Entry{fn, Entry::FilterType::ALLOW});
118  }
119 
120  /// Deny ops that are matched by `fn`.
121  ///
122  /// This function adds a DENY entry.
124  entries.push_back(Entry{fn, Entry::FilterType::DENY});
125  }
126 
127 private:
128  /// Return `true` if the filter has at least one ALLOW rule.
129  bool hasAllowRule() const {
130  for (const Entry &e : entries)
131  if (e.type == Entry::FilterType::ALLOW)
132  return true;
133  return false;
134  }
135 
136  /// Allow a dialect.
137  template <typename DialectT>
138  void allowDialectImpl() {
139  allowDialect(DialectT::getDialectNamespace());
140  }
141 
142  /// Deny a dialect.
143  template <typename DialectT>
144  void denyDialectImpl() {
145  denyDialect(DialectT::getDialectNamespace());
146  }
147 
148  /// Allow an op.
149  template <typename OpTy>
150  void allowOperationImpl() {
151  allowOperation(OpTy::getOperationName());
152  }
153 
154  /// Deny an op.
155  template <typename OpTy>
156  void denyOperationImpl() {
157  denyOperation(OpTy::getOperationName());
158  }
159 
160  /// A list of filter entries that determine whether an op should be allowed or
161  /// denied. If the filter has an ALLOW rule, only ops that are allowed and not
162  /// denied are allowed. If the filter does not have an ALLOW rule, only ops
163  /// that are not denied are allowed.
164  SmallVector<Entry> entries;
165 };
166 
167 /// Options for BufferizableOpInterface-based bufferization.
169  /// Allocator function: Generate a memref allocation with the given type,
170  /// dynamic extents and alignment.
171  using AllocationFn = std::function<FailureOr<Value>(
172  OpBuilder &, Location, MemRefType, ValueRange, unsigned int)>;
173  /// Deallocator function: Deallocate a buffer that was allocated with
174  /// AllocatorFn.
175  using DeallocationFn =
176  std::function<LogicalResult(OpBuilder &, Location, Value)>;
177  /// Memcpy function: Generate a memcpy between two buffers.
178  using MemCpyFn =
179  std::function<LogicalResult(OpBuilder &, Location, Value, Value)>;
180  /// Initializer function for analysis state.
181  using AnalysisStateInitFn = std::function<void(AnalysisState &)>;
182  /// Initializer function for dialect-specific analysis state.
183  using DialectStateInitFn =
184  std::function<std::unique_ptr<DialectAnalysisState>()>;
185  /// Tensor -> MemRef type converter.
186  /// Parameters: Value, memory space, bufferization options
187  using UnknownTypeConverterFn = std::function<BaseMemRefType(
188  Value, unsigned, const BufferizationOptions &)>;
189 
190  enum class LayoutMapOption : int8_t {
191  InferLayoutMap = 0,
192  IdentityLayoutMap = 1,
193  FullyDynamicLayoutMap = 2
194  };
195 
197 
198  /// Try to cast the given op to BufferizableOpInterface if the op is allow
199  /// listed.
200  BufferizableOpInterface dynCastBufferizableOp(Operation *op) const;
201 
202  /// Try to cast the given value to BufferizableOpInterface if the op is allow
203  /// listed.
204  BufferizableOpInterface dynCastBufferizableOp(Value value) const;
205 
206  /// A filter that specifies which ops should be bufferized and which ops
207  /// should be ignored.
209 
210  /// Return `true` if the given op should be bufferized.
211  bool isOpAllowed(Operation *op) const;
212 
213  /// Helper functions for allocation, deallocation, memory copying.
217 
218  /// Create a memref allocation with the given type and dynamic extents.
219  FailureOr<Value> createAlloc(OpBuilder &b, Location loc, MemRefType type,
220  ValueRange dynShape) const;
221 
222  /// Creates a memref deallocation. The given memref buffer must have been
223  /// allocated using `createAlloc`.
224  LogicalResult createDealloc(OpBuilder &b, Location loc,
225  Value allocatedBuffer) const;
226 
227  /// Creates a memcpy between two given buffers.
228  LogicalResult createMemCpy(OpBuilder &b, Location loc, Value from,
229  Value to) const;
230 
231  /// Specifies whether not bufferizable ops are allowed in the input. If so,
232  /// bufferization.to_memref and bufferization.to_tensor ops are inserted at
233  /// the boundaries.
234  bool allowUnknownOps = false;
235 
236  /// Specifies whether function boundaries (ops in the func dialect) should be
237  /// bufferized or not.
238  bool bufferizeFunctionBoundaries = false;
239 
240  /// The default memory space that should be used when it cannot be inferred
241  /// from the context. If no default memory space is specified, bufferization
242  /// fails when the memory space cannot be inferred at any point.
243  Optional<unsigned> defaultMemorySpace = 0;
244 
245  /// Certain ops have aliasing OpOperand/OpResult invariants (e.g., scf.for).
246  /// If this flag is set to `false`, those invariants are no longer enforced
247  /// with buffer copies.
248  ///
249  /// Note: Deactivating this flag can lead to incorrect bufferization results
250  /// when used incorrectly. This flag is useful with
251  /// `AlwaysCopyAnalysisState` which bufferizes all writing tensor
252  /// OpOperands out-of-place.
253  bool enforceAliasingInvariants = true;
254 
255  /// This flag controls buffer types on function signatures.
256  ///
257  /// * InferLayoutMap: All function parameter types have a fully dynamic layout
258  /// map, but function result types are inferred from the body of the
259  /// function.
260  /// * FullyDynamicLayoutMap: All function parameter types and result types
261  /// have a fully dynamic layout map. This option is most efficient because
262  /// any layout map can be casted to a fully dynamic one.
263  /// * IdentityLayoutMap: All function parameter types and result types have a
264  /// static identity layout (i.e., no layout map). This option may introduce
265  /// additional buffer allocs and copies because layout maps cannot be casted
266  /// away.
267  ///
268  /// If `bufferizeFunctionBoundaries` is not set, this flag has no effect.
269  ///
270  /// Note: Inferred layout maps may not be desireable when interacting with
271  /// external functions, because the generated function signatures will be less
272  /// predictable.
273  LayoutMapOption functionBoundaryTypeConversion =
274  LayoutMapOption::InferLayoutMap;
275 
276  /// Type converter from tensors to memrefs. This type converter is used if no
277  /// memref type could be inferred during bufferization. By default, a type
278  /// converter that returns a memref type with a fully dynamic layout map is
279  /// used.
280  UnknownTypeConverterFn unknownTypeConverterFn = nullptr;
281 
282  /// Specifies whether dealloc ops should be generated along with alloc ops. If
283  /// not, new memory allocations will leak.
284  bool createDeallocs = true;
285 
286  /// Seed for the analysis fuzzer. If set to `0`, the fuzzer is deactivated.
287  /// Should be used only with `testAnalysisOnly = true`.
288  unsigned analysisFuzzerSeed = 0;
289 
290  /// If set to `true`, does not modify the IR apart from adding attributes (for
291  /// checking the results of the analysis) and post analysis steps.
292  bool testAnalysisOnly = false;
293 
294  /// If set to `true`, the IR is annotated with details about RaW conflicts.
295  /// For debugging only. Should be used together with `testAnalysisOnly`.
296  bool printConflicts = false;
297 
298  /// Buffer alignment for new memory allocations.
299  unsigned int bufferAlignment = 128;
300 
301  /// Initializer functions for analysis state. These can be used to
302  /// initialize dialect-specific analysis state.
304 
305  /// Add a analysis state initializer that initializes the specified
306  /// dialect-specific analysis state.
307  void addDialectStateInitializer(StringRef name, const DialectStateInitFn &fn);
308 };
309 
310 /// Specify fine-grain relationship between buffers to enable more analysis.
311 enum class BufferRelation {
312  None,
313  // TODO: ResultContainsOperand,
314  // TODO: OperandContainsResult,
315  Equivalent
316 };
317 
318 /// Return `true` if the given value is a BlockArgument of a func::FuncOp.
320 
321 /// Dialect-specific analysis state. Analysis/bufferization information
322 /// that is specific to ops from a certain dialect can be stored in derived
323 /// variants of this struct.
325  DialectAnalysisState() = default;
326 
327  virtual ~DialectAnalysisState() = default;
328 
329  // Copying state is forbidden. Always pass as reference.
330  DialectAnalysisState(const DialectAnalysisState &) = delete;
331 };
332 
333 /// AnalysisState provides a variety of helper functions for dealing with
334 /// tensor values.
336 public:
337  /// Determine which OpOperand* will alias with `result` if the op is
338  /// bufferized in place. Return an empty vector if the op is not bufferizable.
339  SmallVector<OpOperand *> getAliasingOpOperand(OpResult result) const;
340 
341  /// Determine which OpResult will alias with `opOperand` if the op is
342  /// bufferized in place. Return an empty vector if the op is not bufferizable.
343  SmallVector<OpResult> getAliasingOpResult(OpOperand &opOperand) const;
344 
345  /// Return true if `opOperand` bufferizes to a memory read. Return `true` if
346  /// the op is not bufferizable.
347  bool bufferizesToMemoryRead(OpOperand &opOperand) const;
348 
349  /// Return true if `opOperand` bufferizes to a memory write. Return true` if
350  /// the op is not bufferizable.
351  bool bufferizesToMemoryWrite(OpOperand &opOperand) const;
352 
353  /// Return true if `opOperand` does neither read nor write but bufferizes to
354  /// an alias. Return false if the op is not bufferizable.
355  bool bufferizesToAliasOnly(OpOperand &opOperand) const;
356 
357  /// Return true if a copy can always be avoided when allocating a new tensor
358  /// for the given OpOperand.
359  bool canOmitTensorCopy(OpOperand &opOperand) const;
360 
361  /// Return true if the given value is read by an op that bufferizes to a
362  /// memory read. Also takes into account ops that create an alias but do not
363  /// read by themselves (e.g., ExtractSliceOp).
364  bool isValueRead(Value value) const;
365 
366  /// Starting from `value`, follow the use-def chain in reverse, always
367  /// selecting the aliasing OpOperands. Find and return Values for which
368  /// `condition` evaluates to true. OpOperands of such matching Values are not
369  /// traversed any further.
370  ///
371  /// When reaching the end of a chain (BlockArgument or Value without aliasing
372  /// OpOperands), also return the last Value of that chain.
373  ///
374  /// Example:
375  ///
376  /// 8
377  /// |
378  /// 6* 7* +-----+----+
379  /// | | | |
380  /// 2* 3 4* 5
381  /// | | | |
382  /// +----------+----------+----------+
383  /// |
384  /// 1
385  ///
386  /// In the above example, Values with a star satisfy the condition. When
387  /// starting the traversal from Value 1, the resulting SetVector is:
388  /// { 2, 7, 8, 5 }
389  SetVector<Value> findValueInReverseUseDefChain(
390  Value value, llvm::function_ref<bool(Value)> condition) const;
391 
392  /// Find the Values of the last preceding write of a given Value.
393  ///
394  /// Note: Unknown ops are handled conservatively and assumed to be writes.
395  /// Furthermore, BlockArguments are also assumed to be writes. There is no
396  /// analysis across block boundaries.
397  ///
398  /// Note: When reaching an end of the reverse SSA use-def chain, that value
399  /// is returned regardless of whether it is a memory write or not.
400  SetVector<Value> findLastPrecedingWrite(Value value) const;
401 
402  /// Return `true` if the given OpResult has been decided to bufferize inplace.
403  virtual bool isInPlace(OpOperand &opOperand) const;
404 
405  /// Return true if `v1` and `v2` bufferize to equivalent buffers.
406  virtual bool areEquivalentBufferizedValues(Value v1, Value v2) const;
407 
408  /// Return true if `v1` and `v2` may bufferize to aliasing buffers.
409  virtual bool areAliasingBufferizedValues(Value v1, Value v2) const;
410 
411  /// Return `true` if the given tensor has undefined contents.
412  virtual bool hasUndefinedContents(OpOperand *opOperand) const;
413 
414  /// Return true if the given tensor (or an aliasing tensor) is yielded from
415  /// the containing block. Also include all aliasing tensors in the same block.
416  ///
417  /// Note: In the absence of an analysis, an implementation may return true for
418  /// any given tensor.
419  virtual bool isTensorYielded(Value tensor) const;
420 
421  /// Return `true` if the given dialect state exists.
422  bool hasDialectState(StringRef name) const {
423  auto it = dialectState.find(name);
424  return it != dialectState.end();
425  }
426 
427  /// Return dialect-specific bufferization state.
428  template <typename StateT>
430  auto it = dialectState.find(name);
431  if (it == dialectState.end())
432  return None;
433  return static_cast<const StateT *>(it->getSecond().get());
434  }
435 
436  /// Return dialect-specific analysis state or create one if none exists.
437  template <typename StateT>
438  StateT &getOrCreateDialectState(StringRef name) {
439  // Create state if it does not exist yet.
440  if (!hasDialectState(name))
441  dialectState[name] = std::make_unique<StateT>();
442  return static_cast<StateT &>(*dialectState[name]);
443  }
444 
445  void insertDialectState(StringRef name,
446  std::unique_ptr<DialectAnalysisState> state) {
447  assert(!dialectState.count(name) && "dialect state already initialized");
448  dialectState[name] = std::move(state);
449  }
450 
451  /// Return a reference to the BufferizationOptions.
452  const BufferizationOptions &getOptions() const { return options; }
453 
454  explicit AnalysisState(const BufferizationOptions &options);
455 
456  // AnalysisState should be passed as a reference.
457  AnalysisState(const AnalysisState &) = delete;
458 
459  virtual ~AnalysisState() = default;
460 
461 private:
462  /// Dialect-specific analysis state.
464 
465  /// A reference to current bufferization options.
467 };
468 
469 /// Create an AllocTensorOp for the given shaped value (memref or tensor).
470 /// If `copy` is set, the shaped value is copied. Otherwise, a tensor with
471 /// undefined contents is allocated.
474  bool escape, const BufferizationOptions &options,
475  bool copy = true);
476 
477 /// Return `true` if the allocation of the given op is guaranteed to not escape
478 /// the containing block.
479 bool allocationDoesNotEscape(OpResult opResult);
480 
481 /// Lookup the buffer for the given value. If the value was not bufferized
482 /// yet, wrap it in a ToMemrefOp. Otherwise, it is the result of a ToTensorOp,
483 /// from which the memref operand is returned.
485  const BufferizationOptions &options);
486 
487 /// Return the buffer type for a given Value (tensor) after bufferization.
488 ///
489 /// Note: Op implementations should preferrably call `getBuffer()->getType()`.
490 /// This function should only be used if `getBuffer` cannot be used.
492  const BufferizationOptions &options);
493 
494 /// Replace an op with replacement values. The op is deleted. Tensor OpResults
495 /// must be replaced with memref values.
497  ValueRange values);
498 
499 /// Replace an op with a new op. The new op must have the same number of
500 /// results as the replaced op. The new op may not return any tensor values.
501 template <typename OpTy, typename... Args>
503  Args &&...args) {
504  auto newOp = rewriter.create<OpTy>(op->getLoc(), std::forward<Args>(args)...);
505  replaceOpWithBufferizedValues(rewriter, op, newOp->getResults());
506  return newOp;
507 }
508 
509 /// Return `true` if the buffer of given OpResult should be deallocated. This
510 /// function should be called during `BufferizableOpInterface::bufferize`
511 /// implementations that allocate a new buffer for the given OpResult.
512 bool shouldDeallocateOpResult(OpResult opResult,
513  const BufferizationOptions &options);
514 
515 /// Return a MemRefType to which the type of the given value can be bufferized.
516 ///
517 /// If possible, op bufferization implementations should not use this function
518 /// and instead infer precise memref types for tensor results by themselves.
519 ///
520 /// Unless a layout map was specified, `options.unknownTypeConverterFn`
521 /// determines what kind of layout map will be used. For best composability
522 /// (without copies), the fully dynamic layout map is used by default.
523 ///
524 /// Note: Canonicalization patterns could clean up layout maps and infer more
525 /// precise layout maps after bufferization. However, many possible
526 /// canonicalizations are currently not implemented.
528  MemRefLayoutAttrInterface layout = {},
529  unsigned memorySpace = 0);
530 
531 /// Return a MemRef type with fully dynamic layout. If the given tensor type
532 /// is unranked, return an unranked MemRef type.
534  unsigned memorySpace = 0);
535 
536 /// Return a MemRef type with a static identity layout (i.e., no layout map). If
537 /// the given tensor type is unranked, return an unranked MemRef type.
539  unsigned memorySpace = 0);
540 
541 } // namespace bufferization
542 } // namespace mlir
543 
544 #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h.inc"
545 
546 #endif // MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZABLEOPINTERFACE_H_
Include the generated interface declarations.
void allowOperation(StringRef opName)
Allow the given op.
bool isOpAllowed(Operation *op) const
Return whether the op is allowed or not.
Optional< const StateT * > getDialectState(StringRef name) const
Return dialect-specific bufferization state.
FailureOr< Value > allocateTensorForShapedValue(OpBuilder &b, Location loc, Value shapedValue, bool escape, const BufferizationOptions &options, bool copy=true)
Create an AllocTensorOp for the given shaped value (memref or tensor).
FilterType
Filter type: A filter can either be a DENY filter or an ALLOW filter.
void denyOperation(StringRef opName)
Deny the given op.
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
FailureOr< Value > getBuffer(RewriterBase &rewriter, Value value, const BufferizationOptions &options)
Lookup the buffer for the given value.
OpFilter opFilter
A filter that specifies which ops should be bufferized and which ops should be ignored.
This is a value defined by a result of an operation.
Definition: Value.h:425
const BufferizationOptions & getOptions() const
Return a reference to the BufferizationOptions.
void allowOperation()
Allow the given ops.
static void copy(Location loc, Value dst, Value src, Value size, OpBuilder &builder)
Copies the given number of bytes from src to dst pointers.
void allowDialect()
Allow the given dialects.
void replaceOpWithBufferizedValues(RewriterBase &rewriter, Operation *op, ValueRange values)
Replace an op with replacement values.
std::function< LogicalResult(OpBuilder &, Location, Value, Value)> MemCpyFn
Memcpy function: Generate a memcpy between two buffers.
bool hasDialectState(StringRef name) const
Return true if the given dialect state exists.
Optional< AllocationFn > allocationFn
Helper functions for allocation, deallocation, memory copying.
std::function< std::unique_ptr< DialectAnalysisState >()> DialectStateInitFn
Initializer function for dialect-specific analysis state.
bool shouldDeallocateOpResult(OpResult opResult, const BufferizationOptions &options)
Return true if the buffer of given OpResult should be deallocated.
static constexpr const bool value
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
BaseMemRefType getMemRefTypeWithStaticIdentityLayout(TensorType tensorType, unsigned memorySpace=0)
Return a MemRef type with a static identity layout (i.e., no layout map).
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:404
AnalysisState provides a variety of helper functions for dealing with tensor values.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
std::function< LogicalResult(OpBuilder &, Location, Value)> DeallocationFn
Deallocator function: Deallocate a buffer that was allocated with AllocatorFn.
FailureOr< BaseMemRefType > getBufferType(Value value, const BufferizationOptions &options)
Return the buffer type for a given Value (tensor) after bufferization.
This class provides support for representing a failure result, or a valid value of type T...
Definition: LogicalResult.h:78
SmallVector< AnalysisStateInitFn > stateInitializers
Initializer functions for analysis state.
BaseMemRefType getMemRefType(Value value, const BufferizationOptions &options, MemRefLayoutAttrInterface layout={}, unsigned memorySpace=0)
Return a MemRefType to which the type of the given value can be bufferized.
void denyOperation()
Deny the given ops.
bool allocationDoesNotEscape(OpResult opResult)
Return true if the allocation of the given op is guaranteed to not escape the containing block...
Location getLoc()
The source location the operation was defined or derived from.
Definition: Operation.h:154
bool isFunctionArgument(Value value)
Return true if the given value is a BlockArgument of a func::FuncOp.
std::function< bool(Operation *)> FilterFn
If the filter function evaluates to true, the filter matches.
Tensor types represent multi-dimensional arrays, and have two variants: RankedTensorType and Unranked...
Definition: BuiltinTypes.h:76
Options for BufferizableOpInterface-based bufferization.
void denyDialect()
Deny the given dialects.
std::function< BaseMemRefType(Value, unsigned, const BufferizationOptions &)> UnknownTypeConverterFn
Tensor -> MemRef type converter.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
static llvm::ManagedStatic< PassManagerOptions > options
void allowDialect(StringRef dialectNamespace)
Allow the given dialect.
OpTy replaceOpWithNewBufferizedOp(RewriterBase &rewriter, Operation *op, Args &&...args)
Replace an op with a new op.
This class provides a shared interface for ranked and unranked memref types.
Definition: BuiltinTypes.h:112
void allowOperation(Entry::FilterFn fn)
Allow ops that are matched by fn.
This class represents an operand of an operation.
Definition: Value.h:251
BaseMemRefType getMemRefTypeWithFullyDynamicLayout(TensorType tensorType, unsigned memorySpace=0)
Return a MemRef type with fully dynamic layout.
StateT & getOrCreateDialectState(StringRef name)
Return dialect-specific analysis state or create one if none exists.
BufferRelation
Specify fine-grain relationship between buffers to enable more analysis.
void insertDialectState(StringRef name, std::unique_ptr< DialectAnalysisState > state)
void denyOperation(Entry::FilterFn fn)
Deny ops that are matched by fn.
std::function< FailureOr< Value >(OpBuilder &, Location, MemRefType, ValueRange, unsigned int)> AllocationFn
Allocator function: Generate a memref allocation with the given type, dynamic extents and alignment...
result_range getResults()
Definition: Operation.h:332
This class helps build Operations.
Definition: Builders.h:192
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:345
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
Definition: PatternMatch.h:398
std::function< void(AnalysisState &)> AnalysisStateInitFn
Initializer function for analysis state.