MLIR  20.0.0git
BufferizationDialect.cpp
Go to the documentation of this file.
1 //===----------------------------------------------------------------------===//
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 
16 
17 using namespace mlir;
18 using namespace mlir::bufferization;
19 
20 #include "mlir/Dialect/Bufferization/IR/BufferizationOpsDialect.cpp.inc"
21 
22 /// Attribute name used to mark function arguments who's buffers can be written
23 /// to during One-Shot Module Bufferize.
24 constexpr const ::llvm::StringLiteral BufferizationDialect::kWritableAttrName;
25 
26 /// Attribute name used to mark the bufferization layout for region arguments
27 /// during One-Shot Module Bufferize.
28 constexpr const ::llvm::StringLiteral
29  BufferizationDialect::kBufferLayoutAttrName;
30 
31 /// An attribute that can be attached to ops with an allocation and/or
32 /// deallocation side effect. It indicates that the op is under a "manual
33 /// deallocation" scheme. In the case of an allocation op, the returned
34 /// value is *not* an automatically managed allocation and assigned an
35 /// ownership of "false". Furthermore, only deallocation ops that are
36 /// guaranteed to deallocate a buffer under "manual deallocation" are
37 /// allowed to have this attribute. (Deallocation ops without this
38 /// attribute are rejected by the ownership-based buffer deallocation pass.)
39 constexpr const ::llvm::StringLiteral BufferizationDialect::kManualDeallocation;
40 
41 //===----------------------------------------------------------------------===//
42 // Bufferization Dialect Interfaces
43 //===----------------------------------------------------------------------===//
44 
45 namespace {
46 struct BufferizationInlinerInterface : public DialectInlinerInterface {
48 
49  /// Operations in Bufferization dialect are always legal to inline.
50  bool isLegalToInline(Operation *, Region *, bool, IRMapping &) const final {
51  return true;
52  }
53 };
54 } // namespace
55 
56 //===----------------------------------------------------------------------===//
57 // Bufferization Dialect
58 //===----------------------------------------------------------------------===//
59 
60 void mlir::bufferization::BufferizationDialect::initialize() {
61  addOperations<
62 #define GET_OP_LIST
63 #include "mlir/Dialect/Bufferization/IR/BufferizationOps.cpp.inc"
64  >();
65  addInterfaces<BufferizationInlinerInterface>();
66 }
67 
68 LogicalResult BufferizationDialect::verifyRegionArgAttribute(
69  Operation *op, unsigned /*regionIndex*/, unsigned argIndex,
70  NamedAttribute attr) {
71  if (attr.getName() == kWritableAttrName) {
72  if (!llvm::isa<BoolAttr>(attr.getValue())) {
73  return op->emitError() << "'" << kWritableAttrName
74  << "' is expected to be a boolean attribute";
75  }
76  if (!isa<FunctionOpInterface>(op))
77  return op->emitError() << "expected '" << kWritableAttrName
78  << "' to be used on function-like operations";
79  if (cast<FunctionOpInterface>(op).isExternal())
80  return op->emitError() << "'" << kWritableAttrName
81  << "' is invalid on external functions";
82  return success();
83  }
84  if (attr.getName() == kBufferAccessAttrName) {
85  if (!llvm::isa<StringAttr>(attr.getValue())) {
86  return op->emitError() << "'" << kBufferAccessAttrName
87  << "' is expected to be a string attribute";
88  }
89  StringRef str = llvm::cast<StringAttr>(attr.getValue()).getValue();
90  if (str != "none" && str != "read" && str != "write" && str != "read-write")
91  return op->emitError()
92  << "invalid value for '" << kBufferAccessAttrName << "'";
93  if (!isa<FunctionOpInterface>(op))
94  return op->emitError() << "expected '" << kBufferAccessAttrName
95  << "' to be used on function-like operations";
96  return success();
97  }
98  if (attr.getName() == kBufferLayoutAttrName) {
99  if (!llvm::isa<AffineMapAttr>(attr.getValue())) {
100  return op->emitError() << "'" << kBufferLayoutAttrName
101  << "' is expected to be a affine map attribute";
102  }
103  if (!isa<FunctionOpInterface>(op))
104  return op->emitError() << "expected '" << kBufferLayoutAttrName
105  << "' to be used on function-like operations";
106  return success();
107  }
108  return op->emitError() << "attribute '" << kBufferLayoutAttrName
109  << "' not supported as a region arg attribute by the "
110  "bufferization dialect";
111 }
112 
113 LogicalResult
114 BufferizationDialect::verifyOperationAttribute(Operation *op,
115  NamedAttribute attr) {
116  using bufferization::BufferizableOpInterface;
117 
118  if (attr.getName() == kManualDeallocation) {
119  if (!mlir::hasEffect<MemoryEffects::Allocate>(op) &&
120  !mlir::hasEffect<MemoryEffects::Free>(op))
121  return op->emitOpError("attribute '")
122  << kManualDeallocation
123  << "' can be used only on ops that have an allocation and/or free "
124  "side effect";
125  return success();
126  }
127 
128  return op->emitError()
129  << "attribute '" << attr.getName()
130  << "' not supported as an op attribute by the bufferization dialect";
131 }
static bool isLegalToInline(InlinerInterface &interface, Region *src, Region *insertRegion, bool shouldCloneInlinedRegion, IRMapping &valueMapping)
Utility to check that all of the operations within 'src' can be inlined.
This is the interface that must be implemented by the dialects of operations to be inlined.
Definition: InliningUtils.h:44
DialectInlinerInterface(Dialect *dialect)
Definition: InliningUtils.h:46
This is a utility class for mapping one set of IR entities to another.
Definition: IRMapping.h:26
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:207
StringAttr getName() const
Return the name of the attribute.
Definition: Attributes.cpp:49
Attribute getValue() const
Return the value of the attribute.
Definition: Attributes.h:221
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Definition: Operation.cpp:268
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
Definition: Operation.cpp:671
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
Include the generated interface declarations.