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 
9 #include "mlir/Dialect/Bufferization/IR/Bufferization.h"
10 #include "mlir/Dialect/MemRef/IR/MemRef.h"
11 #include "mlir/Dialect/Tensor/IR/Tensor.h"
12 #include "mlir/IR/FunctionInterfaces.h"
13 #include "mlir/Transforms/InliningUtils.h"
14 
15 using namespace mlir;
16 using namespace mlir::bufferization;
17 
18 #include "mlir/Dialect/Bufferization/IR/BufferizationOpsDialect.cpp.inc"
19 
20 /// Attribute name used to mark function arguments who's buffers can be written
21 /// to during One-Shot Module Bufferize.
22 constexpr const ::llvm::StringLiteral BufferizationDialect::kWritableAttrName;
23 
24 /// Attribute name used to mark the bufferization layout for region arguments
25 /// during One-Shot Module Bufferize.
26 constexpr const ::llvm::StringLiteral
27     BufferizationDialect::kBufferLayoutAttrName;
28 
29 //===----------------------------------------------------------------------===//
30 // Bufferization Dialect Interfaces
31 //===----------------------------------------------------------------------===//
32 
33 namespace {
34 struct BufferizationInlinerInterface : public DialectInlinerInterface {
35   using DialectInlinerInterface::DialectInlinerInterface;
36 
37   /// Operations in Bufferization dialect are always legal to inline.
38   bool isLegalToInline(Operation *, Region *, bool,
39                        BlockAndValueMapping &) const final {
40     return true;
41   }
42 };
43 } // namespace
44 
45 //===----------------------------------------------------------------------===//
46 // Bufferization Dialect
47 //===----------------------------------------------------------------------===//
48 
49 void mlir::bufferization::BufferizationDialect::initialize() {
50   addOperations<
51 #define GET_OP_LIST
52 #include "mlir/Dialect/Bufferization/IR/BufferizationOps.cpp.inc"
53       >();
54   addInterfaces<BufferizationInlinerInterface>();
55 }
56 
57 LogicalResult
58 BufferizationDialect::verifyOperationAttribute(Operation *op,
59                                                NamedAttribute attr) {
60   using bufferization::BufferizableOpInterface;
61 
62   if (attr.getName() == kWritableAttrName) {
63     if (!attr.getValue().isa<BoolAttr>()) {
64       return op->emitError() << "'" << kWritableAttrName
65                              << "' is expected to be a boolean attribute";
66     }
67     if (!isa<FunctionOpInterface>(op))
68       return op->emitError() << "expected " << attr.getName()
69                              << " to be used on function-like operations";
70     return success();
71   }
72   if (attr.getName() == kBufferLayoutAttrName) {
73     if (!attr.getValue().isa<AffineMapAttr>()) {
74       return op->emitError() << "'" << kBufferLayoutAttrName
75                              << "' is expected to be a affine map attribute";
76     }
77     if (!isa<FunctionOpInterface>(op))
78       return op->emitError() << "expected " << attr.getName()
79                              << " to be used on function-like operations";
80     return success();
81   }
82 
83   return op->emitError() << "attribute '" << attr.getName()
84                          << "' not supported by the bufferization dialect";
85 }
86