1 //===- BuiltinDialect.cpp - MLIR Builtin Dialect --------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
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 //===----------------------------------------------------------------------===//
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
)) {
53 return AliasResult::OverridableAlias
;
55 if (llvm::isa
<IntegerSetAttr
>(attr
)) {
57 return AliasResult::OverridableAlias
;
59 if (llvm::isa
<LocationAttr
>(attr
)) {
61 return AliasResult::OverridableAlias
;
63 if (auto distinct
= llvm::dyn_cast
<DistinctAttr
>(attr
))
64 if (!llvm::isa
<UnitAttr
>(distinct
.getReferencedAttr())) {
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) {
75 return AliasResult::OverridableAlias
;
78 return AliasResult::NoAlias
;
81 //===------------------------------------------------------------------===//
83 //===------------------------------------------------------------------===//
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();
98 // Update the blob for this entry.
99 blobManager
.update(entry
.getKey(), std::move(*blob
));
103 buildResources(Operation
*op
,
104 const SetVector
<AsmDialectResourceHandle
> &referencedResources
,
105 AsmResourceBuilder
&provider
) const final
{
106 blobManager
.buildResources(provider
, referencedResources
.getArrayRef());
110 /// The blob manager for the dialect.
111 BuiltinBlobManagerInterface
&blobManager
;
115 void BuiltinDialect::initialize() {
117 registerAttributes();
118 registerLocationAttributes();
121 #include "mlir/IR/BuiltinOps.cpp.inc"
124 auto &blobInterface
= addInterface
<BuiltinBlobManagerInterface
>();
125 addInterface
<BuiltinOpAsmDialectInterface
>(blobInterface
);
126 builtin_dialect_detail::addBytecodeInterface(this);
129 //===----------------------------------------------------------------------===//
131 //===----------------------------------------------------------------------===//
133 void ModuleOp::build(OpBuilder
&builder
, OperationState
&state
,
134 std::optional
<StringRef
> name
) {
135 state
.addRegion()->emplaceBlock();
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()))
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()))
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('.') &&
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())) {
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();
203 //===----------------------------------------------------------------------===//
204 // UnrealizedConversionCastOp
205 //===----------------------------------------------------------------------===//
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());
218 if (operands
.empty())
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
224 Value firstInput
= operands
.front();
225 auto inputOp
= firstInput
.getDefiningOp
<UnrealizedConversionCastOp
>();
226 if (!inputOp
|| inputOp
.getResults() != operands
||
227 inputOp
.getOperandTypes() != results
.getTypes())
230 // If everything matches up, we can fold the passthrough.
231 foldResults
.append(inputOp
->operand_begin(), inputOp
->operand_end());
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";
243 //===----------------------------------------------------------------------===//
244 // TableGen'd op method definitions
245 //===----------------------------------------------------------------------===//
247 #define GET_OP_CLASSES
248 #include "mlir/IR/BuiltinOps.cpp.inc"