MLIR  21.0.0git
LinalgDialect.cpp
Go to the documentation of this file.
1 //===- Dialect.cpp - Implementation of the linalg dialect and types -------===//
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 // This file implements the Linalg dialect types and dialect.
10 //
11 //===----------------------------------------------------------------------===//
12 
21 #include "mlir/IR/BuiltinTypes.h"
22 #include "mlir/IR/Dialect.h"
28 #include "mlir/Parser/Parser.h"
29 #include "mlir/Support/LLVM.h"
31 
32 #include "llvm/ADT/StringExtras.h"
33 #include "llvm/ADT/TypeSwitch.h"
34 #include "llvm/Support/raw_ostream.h"
35 
36 using namespace mlir;
37 using namespace mlir::linalg;
38 
39 //===----------------------------------------------------------------------===//
40 // LinalgDialect Dialect Interfaces
41 //===----------------------------------------------------------------------===//
42 
43 namespace {
44 
45 struct LinalgInlinerInterface : public DialectInlinerInterface {
47 
48  // We don't have any special restrictions on what can be inlined into
49  // destination regions (e.g. while/conditional bodies). Always allow it.
50  bool isLegalToInline(Region *dest, Region *src, bool wouldBeCloned,
51  IRMapping &valueMapping) const final {
52  return true;
53  }
54  // Operations in Linalg dialect are always legal to inline.
55  bool isLegalToInline(Operation *, Region *, bool, IRMapping &) const final {
56  return true;
57  }
58  // Handle the given inlined terminator by replacing it with a new operation
59  // as necessary. Required when the region has only one block.
60  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {}
61 };
62 
63 } // namespace
64 
65 //===----------------------------------------------------------------------===//
66 // LinalgDialect
67 //===----------------------------------------------------------------------===//
68 
69 /// Attribute name used to memoize indexing maps for named ops.
70 constexpr const ::llvm::StringLiteral
71  LinalgDialect::kMemoizedIndexingMapsAttrName;
72 
73 /// Trait to check if T provides a `regionBuilder` method.
74 template <typename T, typename... Args>
75 using has_region_builder = decltype(T::regionBuilder);
76 template <typename T>
77 using detect_has_region_builder = llvm::is_detected<has_region_builder, T>;
78 
79 /// SFINAE helper for single C++ class without a `regionBuilder` method (e.g.
80 /// an OpInterface).
81 template <typename OpType, typename = std::enable_if_t<
84  llvm::StringMap<LinalgDialect::RegionBuilderFunType> &map) {
85  // Do nothing.
86 }
87 
88 template <typename OpType,
89  typename = std::enable_if_t<detect_has_region_builder<OpType>::value>,
90  typename = void>
92  llvm::StringMap<LinalgDialect::RegionBuilderFunType> &map) {
93  map.insert(std::make_pair(
94  OpType::getOperationName(),
95  static_cast<LinalgDialect::RegionBuilderFunType>(OpType::regionBuilder)));
96 }
97 
98 template <typename... OpTypes>
100  llvm::StringMap<LinalgDialect::RegionBuilderFunType> &map) {
101  (addNamedOpBuilderImpl<OpTypes>(map), ...);
102 }
103 
104 void mlir::linalg::LinalgDialect::initialize() {
105  addAttributes<
106 #define GET_ATTRDEF_LIST
107 #include "mlir/Dialect/Linalg/IR/LinalgOpsAttrDefs.cpp.inc"
108  >();
109  addOperations<
110 #define GET_OP_LIST
111 #include "mlir/Dialect/Linalg/IR/LinalgOps.cpp.inc"
112  >();
113  addOperations<
114 #define GET_OP_LIST
115 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
116  >();
117  addOperations<
118 #define GET_OP_LIST
119 #include "mlir/Dialect/Linalg/IR/LinalgRelayoutOps.cpp.inc"
120  >();
121 
122  // Fill the Linalg-specific OpName to RegionBuilder map.
124 #define GET_OP_LIST
125 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
126  >(namedStructuredOpRegionBuilders);
127 
128  addInterfaces<LinalgInlinerInterface>();
129 
130  declarePromisedInterface<mesh::ShardingInterface, GenericOp>();
131  declarePromisedInterfaces<mesh::ShardingInterface,
132 #define GET_OP_LIST
133 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
134  >();
135  declarePromisedInterface<SubsetOpInterface, CopyOp>();
136  declarePromisedInterface<SubsetInsertionOpInterface, CopyOp>();
137 
138  // ValueBoundsOpInterface
139  declarePromisedInterface<ValueBoundsOpInterface, IndexOp>();
140 
141  declarePromisedInterface<PartialReductionOpInterface, linalg::GenericOp>();
142 
143  // Tiling Interface
144  declarePromisedInterface<TilingInterface, linalg::GenericOp>();
145  declarePromisedInterfaces<TilingInterface,
146 #define GET_OP_LIST
147 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
148  >();
149  declarePromisedInterfaces<TilingInterface,
150 #define GET_OP_LIST
151 #include "mlir/Dialect/Linalg/IR/LinalgRelayoutOps.cpp.inc"
152  >();
153  declarePromisedInterfaces<PartialReductionOpInterface,
154 #define GET_OP_LIST
155 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
156  >();
157  declarePromisedInterfaces<bufferization::BufferizableOpInterface,
158 #define GET_OP_LIST
159 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
160  >();
161 }
162 
163 LogicalResult LinalgDialect::verifyOperationAttribute(Operation *op,
164  NamedAttribute attr) {
165  if (attr.getName() == LinalgDialect::kMemoizedIndexingMapsAttrName)
166  return success();
167  return op->emitError() << "attribute '" << attr.getName()
168  << "' not supported by the linalg dialect";
169 }
170 
171 #include "mlir/Dialect/Linalg/IR/LinalgOpsEnums.cpp.inc"
172 
173 #define GET_ATTRDEF_CLASSES
174 #include "mlir/Dialect/Linalg/IR/LinalgOpsAttrDefs.cpp.inc"
175 
176 #include "mlir/Dialect/Linalg/IR/LinalgOpsDialect.cpp.inc"
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.
llvm::is_detected< has_region_builder, T > detect_has_region_builder
decltype(T::regionBuilder) has_region_builder
Trait to check if T provides a regionBuilder method.
void addNamedOpBuilders(llvm::StringMap< LinalgDialect::RegionBuilderFunType > &map)
void addNamedOpBuilderImpl(llvm::StringMap< LinalgDialect::RegionBuilderFunType > &map)
SFINAE helper for single C++ class without a regionBuilder method (e.g.
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:164
StringAttr getName() const
Return the name of the attribute.
Definition: Attributes.cpp:55
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
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition: Region.h:26
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:387
Include the generated interface declarations.