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
13#include "mlir/Dialect/Affine/IR/AffineOps.h"
14#include "mlir/Dialect/Arith/IR/Arith.h"
15#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
16#include "mlir/Dialect/Linalg/IR/Linalg.h"
17#include "mlir/Dialect/Math/IR/Math.h"
18#include "mlir/Dialect/MemRef/IR/MemRef.h"
19#include "mlir/Dialect/Mesh/Interfaces/ShardingInterface.h"
20#include "mlir/Dialect/Tensor/IR/Tensor.h"
21#include "mlir/IR/BuiltinTypes.h"
22#include "mlir/IR/Dialect.h"
23#include "mlir/IR/DialectImplementation.h"
24#include "mlir/Interfaces/DestinationStyleOpInterface.h"
25#include "mlir/Interfaces/FunctionInterfaces.h"
26#include "mlir/Interfaces/SubsetOpInterface.h"
27#include "mlir/Interfaces/ValueBoundsOpInterface.h"
28#include "mlir/Parser/Parser.h"
29#include "mlir/Support/LLVM.h"
30#include "mlir/Transforms/InliningUtils.h"
31
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/ADT/TypeSwitch.h"
34#include "llvm/Support/raw_ostream.h"
35
36using namespace mlir;
37using namespace mlir::linalg;
38
39//===----------------------------------------------------------------------===//
40// LinalgDialect Dialect Interfaces
41//===----------------------------------------------------------------------===//
42
43namespace {
44
45struct LinalgInlinerInterface : public DialectInlinerInterface {
46 using DialectInlinerInterface::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.
70constexpr const ::llvm::StringLiteral
71 LinalgDialect::kMemoizedIndexingMapsAttrName;
72
73/// Trait to check if T provides a `regionBuilder` method.
74template <typename T, typename... Args>
75using has_region_builder = decltype(T::regionBuilder);
76template <typename T>
77using 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).
81template <typename OpType, typename = std::enable_if_t<
82 !detect_has_region_builder<OpType>::value>>
83void addNamedOpBuilderImpl(
84 llvm::StringMap<LinalgDialect::RegionBuilderFunType> &map) {
85 // Do nothing.
86}
87
88template <typename OpType,
89 typename = std::enable_if_t<detect_has_region_builder<OpType>::value>,
90 typename = void>
91void addNamedOpBuilderImpl(
92 llvm::StringMap<LinalgDialect::RegionBuilderFunType> &map) {
93 map.insert(std::make_pair(
94 OpType::getOperationName(),
95 static_cast<LinalgDialect::RegionBuilderFunType>(OpType::regionBuilder)));
96}
97
98template <typename... OpTypes>
99void addNamedOpBuilders(
100 llvm::StringMap<LinalgDialect::RegionBuilderFunType> &map) {
101 (addNamedOpBuilderImpl<OpTypes>(map), ...);
102}
103
104void 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.
123 addNamedOpBuilders<
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
163LogicalResult 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"
177

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp