9#ifndef MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZABLEOPINTERFACE_H_
10#define MLIR_DIALECT_BUFFERIZATION_IR_BUFFERIZABLEOPINTERFACE_H_
15#include "llvm/ADT/DenseMapInfoVariant.h"
16#include "llvm/ADT/SetVector.h"
19#include "mlir/Dialect/Bufferization/IR/BufferizationEnums.h.inc"
31class BufferizableOpInterface;
34enum class BufferRelation {
43struct AliasingOpOperand {
44 AliasingOpOperand(OpOperand *opOperand, BufferRelation relation,
45 bool isDefinite =
true)
46 : opOperand(opOperand), relation(relation), isDefinite(isDefinite) {}
49 BufferRelation relation;
56 AliasingValue(Value value, BufferRelation relation,
bool isDefinite =
true)
57 : value(value), relation(relation), isDefinite(isDefinite) {}
60 BufferRelation relation;
68 AliasList() =
default;
71 AliasList(std::initializer_list<T> elems) {
77 AliasList(SmallVector<T> &&aliases) : aliases(std::move(aliases)) {}
79 ArrayRef<T> getAliases()
const {
return aliases; }
81 size_t getNumAliases()
const {
return aliases.size(); }
83 void addAlias(T alias) { aliases.push_back(alias); }
85 auto begin()
const {
return aliases.begin(); }
86 auto end()
const {
return aliases.end(); }
90 SmallVector<T> aliases;
95using AliasingOpOperandList = AliasList<AliasingOpOperand>;
99using AliasingValueList = AliasList<AliasingValue>;
107 using FilterFn = std::function<bool(Operation *)>;
110 enum FilterType : int8_t { DENY = 0, ALLOW = 1 };
122 bool isOpAllowed(Operation *op)
const;
127 template <
typename... DialectTs>
128 void allowDialect() {
131 (allowDialectImpl<DialectTs>(), ...);
137 template <
typename... DialectTs>
139 (denyDialectImpl<DialectTs>(), ...);
145 void allowDialect(StringRef dialectNamespace) {
146 Entry::FilterFn filterFn = [=](Operation *op) {
147 return op->getName().getDialectNamespace() == dialectNamespace;
149 entries.push_back(Entry{filterFn, Entry::FilterType::ALLOW});
155 void denyDialect(StringRef dialectNamespace) {
156 Entry::FilterFn filterFn = [=](Operation *op) {
157 return op->getName().getDialectNamespace() == dialectNamespace;
159 entries.push_back(Entry{filterFn, Entry::FilterType::DENY});
165 template <
typename... OpTys>
166 void allowOperation() {
167 (allowOperationImpl<OpTys>(), ...);
173 template <
typename... OpTys>
174 void denyOperation() {
175 (denyOperationImpl<OpTys>(), ...);
181 void allowOperation(StringRef opName) {
182 Entry::FilterFn filterFn = [=](Operation *op) {
183 return op->getName().getStringRef() == opName;
185 allowOperation(filterFn);
191 void denyOperation(StringRef opName) {
192 Entry::FilterFn filterFn = [=](Operation *op) {
193 return op->getName().getStringRef() == opName;
195 denyOperation(filterFn);
201 void allowOperation(Entry::FilterFn fn) {
202 entries.push_back(Entry{fn, Entry::FilterType::ALLOW});
208 void denyOperation(Entry::FilterFn fn) {
209 entries.push_back(Entry{fn, Entry::FilterType::DENY});
214 bool hasAllowRule()
const {
215 for (
const Entry &e : entries)
216 if (e.type == Entry::FilterType::ALLOW)
222 template <
typename DialectT>
223 void allowDialectImpl() {
224 allowDialect(DialectT::getDialectNamespace());
228 template <
typename DialectT>
229 void denyDialectImpl() {
230 denyDialect(DialectT::getDialectNamespace());
234 template <
typename OpTy>
235 void allowOperationImpl() {
236 allowOperation(OpTy::getOperationName());
240 template <
typename OpTy>
241 void denyOperationImpl() {
242 denyOperation(OpTy::getOperationName());
249 SmallVector<Entry> entries;
253struct BufferizationOptions {
257 OpBuilder &, Location, MemRefType,
ValueRange,
unsigned int)>;
260 std::function<LogicalResult(OpBuilder &, Location, Value, Value)>;
266 std::function<FailureOr<Value>(OpBuilder &, Location, Type, Value)>;
268 using AnalysisStateInitFn = std::function<void(AnalysisState &)>;
271 using FunctionArgTypeConverterFn =
272 std::function<BufferLikeType(TensorLikeType, Attribute memorySpace,
273 func::FuncOp,
const BufferizationOptions &)>;
276 using UnknownTypeConverterFn = std::function<BufferLikeType(
277 TensorLikeType, Attribute memorySpace,
const BufferizationOptions &)>;
279 using DefaultMemorySpaceFn =
280 std::function<std::optional<Attribute>(TensorLikeType t)>;
286 using ReconcileBufferTypeMismatchFn = std::function<FailureOr<BufferLikeType>(
287 BufferLikeType, BufferLikeType,
const BufferizationOptions &)>;
289 BufferizationOptions();
293 BufferizableOpInterface dynCastBufferizableOp(Operation *op)
const;
297 BufferizableOpInterface dynCastBufferizableOp(Value value)
const;
304 bool isOpAllowed(Operation *op)
const;
309 bool allowUnknownOps =
false;
313 bool bufferizeFunctionBoundaries =
false;
318 bool checkParallelRegions =
true;
337 void setFunctionBoundaryTypeConversion(LayoutMapOption layoutMapOption);
346 CastFn castFn =
nullptr;
356 FunctionArgTypeConverterFn functionArgTypeConverterFn =
nullptr;
363 bool inferFunctionResultLayout =
true;
368 UnknownTypeConverterFn unknownTypeConverterFn =
nullptr;
374 DefaultMemorySpaceFn defaultMemorySpaceFn =
375 [](TensorLikeType t) -> std::optional<Attribute> {
return Attribute(); };
385 ReconcileBufferTypeMismatchFn reconcileBufferTypeMismatchFn =
nullptr;
389 bool copyBeforeWrite =
false;
393 bool testAnalysisOnly =
false;
397 bool printConflicts =
false;
400 unsigned int bufferAlignment = 64;
404 SmallVector<AnalysisStateInitFn> stateInitializers;
408struct TraversalConfig {
411 bool alwaysIncludeLeaves =
true;
414 bool followInPlaceOnly =
false;
417 bool followEquivalentOnly =
false;
421 bool followUnknownOps =
false;
425 bool followSameTypeOrCastsOnly =
false;
429 bool revisitAlreadyVisitedValues =
false;
439 AliasingOpOperandList getAliasingOpOperands(Value value)
const;
443 AliasingValueList getAliasingValues(OpOperand &opOperand)
const;
447 bool bufferizesToMemoryRead(OpOperand &opOperand)
const;
451 bool bufferizesToMemoryWrite(OpOperand &opOperand)
const;
456 bool bufferizesToMemoryWrite(Value value)
const;
460 bool bufferizesToAliasOnly(OpOperand &opOperand)
const;
464 bool canOmitTensorCopy(OpOperand &opOperand)
const;
469 bool isValueRead(Value value)
const;
498 SetVector<Value> findValueInReverseUseDefChain(
499 OpOperand *opOperand, llvm::function_ref<
bool(Value)> condition,
500 TraversalConfig config = TraversalConfig(),
501 llvm::DenseSet<OpOperand *> *visitedOpOperands =
nullptr)
const;
535 SetVector<Value> findDefinitions(OpOperand *opOperand)
const;
538 virtual bool isInPlace(OpOperand &opOperand)
const;
541 virtual bool areEquivalentBufferizedValues(Value v1, Value v2)
const;
544 virtual bool areAliasingBufferizedValues(Value v1, Value v2)
const;
547 virtual bool hasUndefinedContents(OpOperand *opOperand)
const;
550 const BufferizationOptions &getOptions()
const {
return options; }
552 AnalysisState(
const BufferizationOptions &
options);
555 AnalysisState(
const AnalysisState &) =
delete;
557 virtual ~AnalysisState() =
default;
559 static bool classof(
const AnalysisState *base) {
return true; }
561 TypeID
getType()
const {
return type; }
565 const BufferizationOptions &
options);
570 const BufferizationOptions &
options);
574 const BufferizationOptions &
options);
576 virtual void resetCache();
584 AnalysisState(
const BufferizationOptions &
options, TypeID type);
588 const BufferizationOptions &
options;
594 DenseMap<std::variant<Operation *, Block *, Region *, Value>, Region *>
595 enclosingRepetitiveRegionCache;
599 DenseMap<std::pair<Operation *, Operation *>,
bool>
600 insideMutuallyExclusiveRegionsCache;
605class BufferizationState {
608 SymbolTableCollection &getSymbolTables();
610 SymbolTableCollection &getSymbolTables()
const;
616 mutable SymbolTableCollection symbolTables;
623allocateTensorForShapedValue(OpBuilder &
b, Location loc, Value shapedValue,
624 const BufferizationOptions &
options,
625 const BufferizationState &state,
bool copy =
true);
630FailureOr<Value> getBuffer(RewriterBase &rewriter, Value value,
631 const BufferizationOptions &
options,
632 const BufferizationState &state);
643 const BufferizationOptions &
options,
644 const BufferizationState &state);
657 const BufferizationOptions &
options,
658 const BufferizationState &state,
659 SmallVector<Value> &invocationStack);
665bool hasTensorSemantics(Operation *op);
669void replaceOpWithBufferizedValues(RewriterBase &rewriter, Operation *op,
674template <
typename OpTy,
typename... Args>
675OpTy replaceOpWithNewBufferizedOp(RewriterBase &rewriter, Operation *op,
678 OpTy::create(rewriter, op->getLoc(), std::forward<Args>(args)...);
679 replaceOpWithBufferizedValues(rewriter, op, newOp->getResults());
686getMemRefTypeWithFullyDynamicLayout(TensorType tensorType,
687 Attribute memorySpace =
nullptr);
692getMemRefTypeWithStaticIdentityLayout(TensorType tensorType,
693 Attribute memorySpace =
nullptr);
701Region *getNextEnclosingRepetitiveRegion(Region *region,
702 const BufferizationOptions &
options);
710Region *getParallelRegion(Region *region,
const BufferizationOptions &
options);
716AliasingOpOperandList defaultGetAliasingOpOperands(Value value,
717 const AnalysisState &state);
722FailureOr<BufferLikeType>
723defaultGetBufferType(Value value,
const BufferizationOptions &
options,
724 const BufferizationState &state,
725 SmallVector<Value> &invocationStack);
730bool defaultResultBufferizesToMemoryWrite(OpResult opResult,
731 const AnalysisState &state);
736bool defaultIsRepetitiveRegion(BufferizableOpInterface bufferizableOp,
741AliasingOpOperandList unknownGetAliasingOpOperands(Value value);
745AliasingValueList unknownGetAliasingValues(OpOperand &opOperand);
749bool defaultHasTensorSemantics(Operation *op);
757FailureOr<BaseMemRefType> asMemRefType(FailureOr<BufferLikeType> bufferType);
762bool typesMatchAfterBufferization(Operation &op, Value tensor, Value buffer);
774#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h.inc"
bufferization::BufferResultsToOutParamsOpts::AllocationFn AllocationFn
bufferization::BufferResultsToOutParamsOpts::MemCpyFn MemCpyFn
static void copy(Location loc, Value dst, Value src, Value size, OpBuilder &builder)
Copies the given number of bytes from src to dst pointers.
static llvm::ManagedStatic< PassManagerOptions > options
static RankedTensorType getBufferType(const SparseTensorType &stt, bool needTmpCOO)
#define MLIR_DECLARE_EXPLICIT_TYPE_ID(CLASS_NAME)
static Operation * getOwnerOfValue(Value value)
This class helps build Operations.
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
bool insideMutuallyExclusiveRegions(Operation *a, Operation *b)
Return true if a and b are in mutually exclusive regions as per RegionBranchOpInterface.
Region * getEnclosingRepetitiveRegion(Operation *op)
Return the first enclosing region of the given op that may be executed repetitively as per RegionBran...