[LLVM] Fix Maintainers.md formatting (NFC)
[llvm-project.git] / mlir / lib / IR / BuiltinDialect.cpp
blob99796c5f1c37186306cba214b3b0d3e07558acc6
1 //===- BuiltinDialect.cpp - MLIR Builtin Dialect --------------------------===//
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 contains the Builtin dialect that contains all of the attributes,
10 // operations, and types that are necessary for the validity of the IR.
12 //===----------------------------------------------------------------------===//
14 #include "mlir/IR/BuiltinDialect.h"
15 #include "BuiltinDialectBytecode.h"
16 #include "mlir/IR/Builders.h"
17 #include "mlir/IR/BuiltinOps.h"
18 #include "mlir/IR/BuiltinTypes.h"
19 #include "mlir/IR/DialectResourceBlobManager.h"
20 #include "mlir/IR/IRMapping.h"
21 #include "mlir/IR/OpImplementation.h"
22 #include "mlir/IR/PatternMatch.h"
23 #include "mlir/IR/TypeRange.h"
25 using namespace mlir;
27 //===----------------------------------------------------------------------===//
28 // TableGen'erated dialect
29 //===----------------------------------------------------------------------===//
31 #include "mlir/IR/BuiltinDialect.cpp.inc"
33 //===----------------------------------------------------------------------===//
34 // BuiltinBlobManagerInterface
35 //===----------------------------------------------------------------------===//
37 using BuiltinBlobManagerInterface =
38 ResourceBlobManagerDialectInterfaceBase<DenseResourceElementsHandle>;
40 //===----------------------------------------------------------------------===//
41 // BuiltinOpAsmDialectInterface
42 //===----------------------------------------------------------------------===//
44 namespace {
45 struct BuiltinOpAsmDialectInterface : public OpAsmDialectInterface {
46 BuiltinOpAsmDialectInterface(Dialect *dialect,
47 BuiltinBlobManagerInterface &mgr)
48 : OpAsmDialectInterface(dialect), blobManager(mgr) {}
50 AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
51 if (llvm::isa<AffineMapAttr>(attr)) {
52 os << "map";
53 return AliasResult::OverridableAlias;
55 if (llvm::isa<IntegerSetAttr>(attr)) {
56 os << "set";
57 return AliasResult::OverridableAlias;
59 if (llvm::isa<LocationAttr>(attr)) {
60 os << "loc";
61 return AliasResult::OverridableAlias;
63 if (auto distinct = llvm::dyn_cast<DistinctAttr>(attr))
64 if (!llvm::isa<UnitAttr>(distinct.getReferencedAttr())) {
65 os << "distinct";
66 return AliasResult::OverridableAlias;
68 return AliasResult::NoAlias;
71 AliasResult getAlias(Type type, raw_ostream &os) const final {
72 if (auto tupleType = llvm::dyn_cast<TupleType>(type)) {
73 if (tupleType.size() > 16) {
74 os << "tuple";
75 return AliasResult::OverridableAlias;
78 return AliasResult::NoAlias;
81 //===------------------------------------------------------------------===//
82 // Resources
83 //===------------------------------------------------------------------===//
85 std::string
86 getResourceKey(const AsmDialectResourceHandle &handle) const override {
87 return cast<DenseResourceElementsHandle>(handle).getKey().str();
89 FailureOr<AsmDialectResourceHandle>
90 declareResource(StringRef key) const final {
91 return blobManager.insert(key);
93 LogicalResult parseResource(AsmParsedResourceEntry &entry) const final {
94 FailureOr<AsmResourceBlob> blob = entry.parseAsBlob();
95 if (failed(blob))
96 return failure();
98 // Update the blob for this entry.
99 blobManager.update(entry.getKey(), std::move(*blob));
100 return success();
102 void
103 buildResources(Operation *op,
104 const SetVector<AsmDialectResourceHandle> &referencedResources,
105 AsmResourceBuilder &provider) const final {
106 blobManager.buildResources(provider, referencedResources.getArrayRef());
109 private:
110 /// The blob manager for the dialect.
111 BuiltinBlobManagerInterface &blobManager;
113 } // namespace
115 void BuiltinDialect::initialize() {
116 registerTypes();
117 registerAttributes();
118 registerLocationAttributes();
119 addOperations<
120 #define GET_OP_LIST
121 #include "mlir/IR/BuiltinOps.cpp.inc"
122 >();
124 auto &blobInterface = addInterface<BuiltinBlobManagerInterface>();
125 addInterface<BuiltinOpAsmDialectInterface>(blobInterface);
126 builtin_dialect_detail::addBytecodeInterface(this);
129 //===----------------------------------------------------------------------===//
130 // ModuleOp
131 //===----------------------------------------------------------------------===//
133 void ModuleOp::build(OpBuilder &builder, OperationState &state,
134 std::optional<StringRef> name) {
135 state.addRegion()->emplaceBlock();
136 if (name) {
137 state.attributes.push_back(builder.getNamedAttr(
138 mlir::SymbolTable::getSymbolAttrName(), builder.getStringAttr(*name)));
142 /// Construct a module from the given context.
143 ModuleOp ModuleOp::create(Location loc, std::optional<StringRef> name) {
144 OpBuilder builder(loc->getContext());
145 return builder.create<ModuleOp>(loc, name);
148 DataLayoutSpecInterface ModuleOp::getDataLayoutSpec() {
149 // Take the first and only (if present) attribute that implements the
150 // interface. This needs a linear search, but is called only once per data
151 // layout object construction that is used for repeated queries.
152 for (NamedAttribute attr : getOperation()->getAttrs())
153 if (auto spec = llvm::dyn_cast<DataLayoutSpecInterface>(attr.getValue()))
154 return spec;
155 return {};
158 TargetSystemSpecInterface ModuleOp::getTargetSystemSpec() {
159 // Take the first and only (if present) attribute that implements the
160 // interface. This needs a linear search, but is called only once per data
161 // layout object construction that is used for repeated queries.
162 for (NamedAttribute attr : getOperation()->getAttrs())
163 if (auto spec = llvm::dyn_cast<TargetSystemSpecInterface>(attr.getValue()))
164 return spec;
165 return {};
168 LogicalResult ModuleOp::verify() {
169 // Check that none of the attributes are non-dialect attributes, except for
170 // the symbol related attributes.
171 for (auto attr : (*this)->getAttrs()) {
172 if (!attr.getName().strref().contains('.') &&
173 !llvm::is_contained(
174 ArrayRef<StringRef>{mlir::SymbolTable::getSymbolAttrName(),
175 mlir::SymbolTable::getVisibilityAttrName()},
176 attr.getName().strref()))
177 return emitOpError() << "can only contain attributes with "
178 "dialect-prefixed names, found: '"
179 << attr.getName().getValue() << "'";
182 // Check that there is at most one data layout spec attribute.
183 StringRef layoutSpecAttrName;
184 DataLayoutSpecInterface layoutSpec;
185 for (const NamedAttribute &na : (*this)->getAttrs()) {
186 if (auto spec = llvm::dyn_cast<DataLayoutSpecInterface>(na.getValue())) {
187 if (layoutSpec) {
188 InFlightDiagnostic diag =
189 emitOpError() << "expects at most one data layout attribute";
190 diag.attachNote() << "'" << layoutSpecAttrName
191 << "' is a data layout attribute";
192 diag.attachNote() << "'" << na.getName().getValue()
193 << "' is a data layout attribute";
195 layoutSpecAttrName = na.getName().strref();
196 layoutSpec = spec;
200 return success();
203 //===----------------------------------------------------------------------===//
204 // UnrealizedConversionCastOp
205 //===----------------------------------------------------------------------===//
207 LogicalResult
208 UnrealizedConversionCastOp::fold(FoldAdaptor adaptor,
209 SmallVectorImpl<OpFoldResult> &foldResults) {
210 OperandRange operands = getInputs();
211 ResultRange results = getOutputs();
213 if (operands.getType() == results.getType()) {
214 foldResults.append(operands.begin(), operands.end());
215 return success();
218 if (operands.empty())
219 return failure();
221 // Check that the input is a cast with results that all feed into this
222 // operation, and operand types that directly match the result types of this
223 // operation.
224 Value firstInput = operands.front();
225 auto inputOp = firstInput.getDefiningOp<UnrealizedConversionCastOp>();
226 if (!inputOp || inputOp.getResults() != operands ||
227 inputOp.getOperandTypes() != results.getTypes())
228 return failure();
230 // If everything matches up, we can fold the passthrough.
231 foldResults.append(inputOp->operand_begin(), inputOp->operand_end());
232 return success();
235 LogicalResult UnrealizedConversionCastOp::verify() {
236 // TODO: The verifier of external models is not called. This op verifier can
237 // be removed when that is fixed.
238 if (getNumResults() == 0)
239 return emitOpError() << "expected at least one result for cast operation";
240 return success();
243 //===----------------------------------------------------------------------===//
244 // TableGen'd op method definitions
245 //===----------------------------------------------------------------------===//
247 #define GET_OP_CLASSES
248 #include "mlir/IR/BuiltinOps.cpp.inc"