19e0b5533SMathieu Fehr //===- ExtensibleDialect.cpp - Extensible dialect ---------------*- C++ -*-===//
29e0b5533SMathieu Fehr //
39e0b5533SMathieu Fehr // This file is licensed under the Apache License v2.0 with LLVM Exceptions.
49e0b5533SMathieu Fehr // See https://llvm.org/LICENSE.txt for license information.
59e0b5533SMathieu Fehr // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69e0b5533SMathieu Fehr //
79e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
89e0b5533SMathieu Fehr
99e0b5533SMathieu Fehr #include "mlir/IR/ExtensibleDialect.h"
109e0b5533SMathieu Fehr #include "mlir/IR/AttributeSupport.h"
119e0b5533SMathieu Fehr #include "mlir/IR/DialectImplementation.h"
129e0b5533SMathieu Fehr #include "mlir/IR/OperationSupport.h"
139e0b5533SMathieu Fehr #include "mlir/IR/StorageUniquerSupport.h"
149e0b5533SMathieu Fehr #include "mlir/Support/LogicalResult.h"
159e0b5533SMathieu Fehr
169e0b5533SMathieu Fehr using namespace mlir;
179e0b5533SMathieu Fehr
189e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
199e0b5533SMathieu Fehr // Dynamic types and attributes shared functions
209e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
219e0b5533SMathieu Fehr
229e0b5533SMathieu Fehr /// Default parser for dynamic attribute or type parameters.
239e0b5533SMathieu Fehr /// Parse in the format '(<>)?' or '<attr (,attr)*>'.
249e0b5533SMathieu Fehr static LogicalResult
typeOrAttrParser(AsmParser & parser,SmallVectorImpl<Attribute> & parsedParams)259e0b5533SMathieu Fehr typeOrAttrParser(AsmParser &parser, SmallVectorImpl<Attribute> &parsedParams) {
269e0b5533SMathieu Fehr // No parameters
279e0b5533SMathieu Fehr if (parser.parseOptionalLess() || !parser.parseOptionalGreater())
289e0b5533SMathieu Fehr return success();
299e0b5533SMathieu Fehr
309e0b5533SMathieu Fehr Attribute attr;
319e0b5533SMathieu Fehr if (parser.parseAttribute(attr))
329e0b5533SMathieu Fehr return failure();
339e0b5533SMathieu Fehr parsedParams.push_back(attr);
349e0b5533SMathieu Fehr
359e0b5533SMathieu Fehr while (parser.parseOptionalGreater()) {
369e0b5533SMathieu Fehr Attribute attr;
379e0b5533SMathieu Fehr if (parser.parseComma() || parser.parseAttribute(attr))
389e0b5533SMathieu Fehr return failure();
399e0b5533SMathieu Fehr parsedParams.push_back(attr);
409e0b5533SMathieu Fehr }
419e0b5533SMathieu Fehr
429e0b5533SMathieu Fehr return success();
439e0b5533SMathieu Fehr }
449e0b5533SMathieu Fehr
459e0b5533SMathieu Fehr /// Default printer for dynamic attribute or type parameters.
469e0b5533SMathieu Fehr /// Print in the format '(<>)?' or '<attr (,attr)*>'.
typeOrAttrPrinter(AsmPrinter & printer,ArrayRef<Attribute> params)479e0b5533SMathieu Fehr static void typeOrAttrPrinter(AsmPrinter &printer, ArrayRef<Attribute> params) {
489e0b5533SMathieu Fehr if (params.empty())
499e0b5533SMathieu Fehr return;
509e0b5533SMathieu Fehr
519e0b5533SMathieu Fehr printer << "<";
529e0b5533SMathieu Fehr interleaveComma(params, printer.getStream());
539e0b5533SMathieu Fehr printer << ">";
549e0b5533SMathieu Fehr }
559e0b5533SMathieu Fehr
569e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
579e0b5533SMathieu Fehr // Dynamic type
589e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
599e0b5533SMathieu Fehr
609e0b5533SMathieu Fehr std::unique_ptr<DynamicTypeDefinition>
get(StringRef name,ExtensibleDialect * dialect,VerifierFn && verifier)619e0b5533SMathieu Fehr DynamicTypeDefinition::get(StringRef name, ExtensibleDialect *dialect,
629e0b5533SMathieu Fehr VerifierFn &&verifier) {
639e0b5533SMathieu Fehr return DynamicTypeDefinition::get(name, dialect, std::move(verifier),
649e0b5533SMathieu Fehr typeOrAttrParser, typeOrAttrPrinter);
659e0b5533SMathieu Fehr }
669e0b5533SMathieu Fehr
679e0b5533SMathieu Fehr std::unique_ptr<DynamicTypeDefinition>
get(StringRef name,ExtensibleDialect * dialect,VerifierFn && verifier,ParserFn && parser,PrinterFn && printer)689e0b5533SMathieu Fehr DynamicTypeDefinition::get(StringRef name, ExtensibleDialect *dialect,
699e0b5533SMathieu Fehr VerifierFn &&verifier, ParserFn &&parser,
709e0b5533SMathieu Fehr PrinterFn &&printer) {
719e0b5533SMathieu Fehr return std::unique_ptr<DynamicTypeDefinition>(
729e0b5533SMathieu Fehr new DynamicTypeDefinition(name, dialect, std::move(verifier),
739e0b5533SMathieu Fehr std::move(parser), std::move(printer)));
749e0b5533SMathieu Fehr }
759e0b5533SMathieu Fehr
DynamicTypeDefinition(StringRef nameRef,ExtensibleDialect * dialect,VerifierFn && verifier,ParserFn && parser,PrinterFn && printer)769e0b5533SMathieu Fehr DynamicTypeDefinition::DynamicTypeDefinition(StringRef nameRef,
779e0b5533SMathieu Fehr ExtensibleDialect *dialect,
789e0b5533SMathieu Fehr VerifierFn &&verifier,
799e0b5533SMathieu Fehr ParserFn &&parser,
809e0b5533SMathieu Fehr PrinterFn &&printer)
819e0b5533SMathieu Fehr : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
829e0b5533SMathieu Fehr parser(std::move(parser)), printer(std::move(printer)),
839e0b5533SMathieu Fehr ctx(dialect->getContext()) {}
849e0b5533SMathieu Fehr
DynamicTypeDefinition(ExtensibleDialect * dialect,StringRef nameRef)859e0b5533SMathieu Fehr DynamicTypeDefinition::DynamicTypeDefinition(ExtensibleDialect *dialect,
869e0b5533SMathieu Fehr StringRef nameRef)
879e0b5533SMathieu Fehr : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
889e0b5533SMathieu Fehr
registerInTypeUniquer()899e0b5533SMathieu Fehr void DynamicTypeDefinition::registerInTypeUniquer() {
909e0b5533SMathieu Fehr detail::TypeUniquer::registerType<DynamicType>(&getContext(), getTypeID());
919e0b5533SMathieu Fehr }
929e0b5533SMathieu Fehr
939e0b5533SMathieu Fehr namespace mlir {
949e0b5533SMathieu Fehr namespace detail {
959e0b5533SMathieu Fehr /// Storage of DynamicType.
969e0b5533SMathieu Fehr /// Contains a pointer to the type definition and type parameters.
979e0b5533SMathieu Fehr struct DynamicTypeStorage : public TypeStorage {
989e0b5533SMathieu Fehr
999e0b5533SMathieu Fehr using KeyTy = std::pair<DynamicTypeDefinition *, ArrayRef<Attribute>>;
1009e0b5533SMathieu Fehr
DynamicTypeStoragemlir::detail::DynamicTypeStorage1019e0b5533SMathieu Fehr explicit DynamicTypeStorage(DynamicTypeDefinition *typeDef,
1029e0b5533SMathieu Fehr ArrayRef<Attribute> params)
1039e0b5533SMathieu Fehr : typeDef(typeDef), params(params) {}
1049e0b5533SMathieu Fehr
operator ==mlir::detail::DynamicTypeStorage1059e0b5533SMathieu Fehr bool operator==(const KeyTy &key) const {
1069e0b5533SMathieu Fehr return typeDef == key.first && params == key.second;
1079e0b5533SMathieu Fehr }
1089e0b5533SMathieu Fehr
hashKeymlir::detail::DynamicTypeStorage1099e0b5533SMathieu Fehr static llvm::hash_code hashKey(const KeyTy &key) {
1109e0b5533SMathieu Fehr return llvm::hash_value(key);
1119e0b5533SMathieu Fehr }
1129e0b5533SMathieu Fehr
constructmlir::detail::DynamicTypeStorage1139e0b5533SMathieu Fehr static DynamicTypeStorage *construct(TypeStorageAllocator &alloc,
1149e0b5533SMathieu Fehr const KeyTy &key) {
1159e0b5533SMathieu Fehr return new (alloc.allocate<DynamicTypeStorage>())
1169e0b5533SMathieu Fehr DynamicTypeStorage(key.first, alloc.copyInto(key.second));
1179e0b5533SMathieu Fehr }
1189e0b5533SMathieu Fehr
1199e0b5533SMathieu Fehr /// Definition of the type.
1209e0b5533SMathieu Fehr DynamicTypeDefinition *typeDef;
1219e0b5533SMathieu Fehr
1229e0b5533SMathieu Fehr /// The type parameters.
1239e0b5533SMathieu Fehr ArrayRef<Attribute> params;
1249e0b5533SMathieu Fehr };
1259e0b5533SMathieu Fehr } // namespace detail
1269e0b5533SMathieu Fehr } // namespace mlir
1279e0b5533SMathieu Fehr
get(DynamicTypeDefinition * typeDef,ArrayRef<Attribute> params)1289e0b5533SMathieu Fehr DynamicType DynamicType::get(DynamicTypeDefinition *typeDef,
1299e0b5533SMathieu Fehr ArrayRef<Attribute> params) {
1309e0b5533SMathieu Fehr auto &ctx = typeDef->getContext();
1319e0b5533SMathieu Fehr auto emitError = detail::getDefaultDiagnosticEmitFn(&ctx);
1329e0b5533SMathieu Fehr assert(succeeded(typeDef->verify(emitError, params)));
1339e0b5533SMathieu Fehr return detail::TypeUniquer::getWithTypeID<DynamicType>(
1349e0b5533SMathieu Fehr &ctx, typeDef->getTypeID(), typeDef, params);
1359e0b5533SMathieu Fehr }
1369e0b5533SMathieu Fehr
1379e0b5533SMathieu Fehr DynamicType
getChecked(function_ref<InFlightDiagnostic ()> emitError,DynamicTypeDefinition * typeDef,ArrayRef<Attribute> params)1389e0b5533SMathieu Fehr DynamicType::getChecked(function_ref<InFlightDiagnostic()> emitError,
1399e0b5533SMathieu Fehr DynamicTypeDefinition *typeDef,
1409e0b5533SMathieu Fehr ArrayRef<Attribute> params) {
1419e0b5533SMathieu Fehr if (failed(typeDef->verify(emitError, params)))
1429e0b5533SMathieu Fehr return {};
1439e0b5533SMathieu Fehr auto &ctx = typeDef->getContext();
1449e0b5533SMathieu Fehr return detail::TypeUniquer::getWithTypeID<DynamicType>(
1459e0b5533SMathieu Fehr &ctx, typeDef->getTypeID(), typeDef, params);
1469e0b5533SMathieu Fehr }
1479e0b5533SMathieu Fehr
getTypeDef()1489e0b5533SMathieu Fehr DynamicTypeDefinition *DynamicType::getTypeDef() { return getImpl()->typeDef; }
1499e0b5533SMathieu Fehr
getParams()1509e0b5533SMathieu Fehr ArrayRef<Attribute> DynamicType::getParams() { return getImpl()->params; }
1519e0b5533SMathieu Fehr
classof(Type type)1529e0b5533SMathieu Fehr bool DynamicType::classof(Type type) {
1539e0b5533SMathieu Fehr return type.hasTrait<TypeTrait::IsDynamicType>();
1549e0b5533SMathieu Fehr }
1559e0b5533SMathieu Fehr
parse(AsmParser & parser,DynamicTypeDefinition * typeDef,DynamicType & parsedType)1569e0b5533SMathieu Fehr ParseResult DynamicType::parse(AsmParser &parser,
1579e0b5533SMathieu Fehr DynamicTypeDefinition *typeDef,
1589e0b5533SMathieu Fehr DynamicType &parsedType) {
1599e0b5533SMathieu Fehr SmallVector<Attribute> params;
1609e0b5533SMathieu Fehr if (failed(typeDef->parser(parser, params)))
1619e0b5533SMathieu Fehr return failure();
1629e0b5533SMathieu Fehr parsedType = parser.getChecked<DynamicType>(typeDef, params);
1639e0b5533SMathieu Fehr if (!parsedType)
1649e0b5533SMathieu Fehr return failure();
1659e0b5533SMathieu Fehr return success();
1669e0b5533SMathieu Fehr }
1679e0b5533SMathieu Fehr
print(AsmPrinter & printer)1689e0b5533SMathieu Fehr void DynamicType::print(AsmPrinter &printer) {
1699e0b5533SMathieu Fehr printer << getTypeDef()->getName();
1709e0b5533SMathieu Fehr getTypeDef()->printer(printer, getParams());
1719e0b5533SMathieu Fehr }
1729e0b5533SMathieu Fehr
1739e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
1749e0b5533SMathieu Fehr // Dynamic attribute
1759e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
1769e0b5533SMathieu Fehr
1779e0b5533SMathieu Fehr std::unique_ptr<DynamicAttrDefinition>
get(StringRef name,ExtensibleDialect * dialect,VerifierFn && verifier)1789e0b5533SMathieu Fehr DynamicAttrDefinition::get(StringRef name, ExtensibleDialect *dialect,
1799e0b5533SMathieu Fehr VerifierFn &&verifier) {
1809e0b5533SMathieu Fehr return DynamicAttrDefinition::get(name, dialect, std::move(verifier),
1819e0b5533SMathieu Fehr typeOrAttrParser, typeOrAttrPrinter);
1829e0b5533SMathieu Fehr }
1839e0b5533SMathieu Fehr
1849e0b5533SMathieu Fehr std::unique_ptr<DynamicAttrDefinition>
get(StringRef name,ExtensibleDialect * dialect,VerifierFn && verifier,ParserFn && parser,PrinterFn && printer)1859e0b5533SMathieu Fehr DynamicAttrDefinition::get(StringRef name, ExtensibleDialect *dialect,
1869e0b5533SMathieu Fehr VerifierFn &&verifier, ParserFn &&parser,
1879e0b5533SMathieu Fehr PrinterFn &&printer) {
1889e0b5533SMathieu Fehr return std::unique_ptr<DynamicAttrDefinition>(
1899e0b5533SMathieu Fehr new DynamicAttrDefinition(name, dialect, std::move(verifier),
1909e0b5533SMathieu Fehr std::move(parser), std::move(printer)));
1919e0b5533SMathieu Fehr }
1929e0b5533SMathieu Fehr
DynamicAttrDefinition(StringRef nameRef,ExtensibleDialect * dialect,VerifierFn && verifier,ParserFn && parser,PrinterFn && printer)1939e0b5533SMathieu Fehr DynamicAttrDefinition::DynamicAttrDefinition(StringRef nameRef,
1949e0b5533SMathieu Fehr ExtensibleDialect *dialect,
1959e0b5533SMathieu Fehr VerifierFn &&verifier,
1969e0b5533SMathieu Fehr ParserFn &&parser,
1979e0b5533SMathieu Fehr PrinterFn &&printer)
1989e0b5533SMathieu Fehr : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
1999e0b5533SMathieu Fehr parser(std::move(parser)), printer(std::move(printer)),
2009e0b5533SMathieu Fehr ctx(dialect->getContext()) {}
2019e0b5533SMathieu Fehr
DynamicAttrDefinition(ExtensibleDialect * dialect,StringRef nameRef)2029e0b5533SMathieu Fehr DynamicAttrDefinition::DynamicAttrDefinition(ExtensibleDialect *dialect,
2039e0b5533SMathieu Fehr StringRef nameRef)
2049e0b5533SMathieu Fehr : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {}
2059e0b5533SMathieu Fehr
registerInAttrUniquer()2069e0b5533SMathieu Fehr void DynamicAttrDefinition::registerInAttrUniquer() {
2079e0b5533SMathieu Fehr detail::AttributeUniquer::registerAttribute<DynamicAttr>(&getContext(),
2089e0b5533SMathieu Fehr getTypeID());
2099e0b5533SMathieu Fehr }
2109e0b5533SMathieu Fehr
2119e0b5533SMathieu Fehr namespace mlir {
2129e0b5533SMathieu Fehr namespace detail {
2139e0b5533SMathieu Fehr /// Storage of DynamicAttr.
2149e0b5533SMathieu Fehr /// Contains a pointer to the attribute definition and attribute parameters.
2159e0b5533SMathieu Fehr struct DynamicAttrStorage : public AttributeStorage {
2169e0b5533SMathieu Fehr using KeyTy = std::pair<DynamicAttrDefinition *, ArrayRef<Attribute>>;
2179e0b5533SMathieu Fehr
DynamicAttrStoragemlir::detail::DynamicAttrStorage2189e0b5533SMathieu Fehr explicit DynamicAttrStorage(DynamicAttrDefinition *attrDef,
2199e0b5533SMathieu Fehr ArrayRef<Attribute> params)
2209e0b5533SMathieu Fehr : attrDef(attrDef), params(params) {}
2219e0b5533SMathieu Fehr
operator ==mlir::detail::DynamicAttrStorage2229e0b5533SMathieu Fehr bool operator==(const KeyTy &key) const {
2239e0b5533SMathieu Fehr return attrDef == key.first && params == key.second;
2249e0b5533SMathieu Fehr }
2259e0b5533SMathieu Fehr
hashKeymlir::detail::DynamicAttrStorage2269e0b5533SMathieu Fehr static llvm::hash_code hashKey(const KeyTy &key) {
2279e0b5533SMathieu Fehr return llvm::hash_value(key);
2289e0b5533SMathieu Fehr }
2299e0b5533SMathieu Fehr
constructmlir::detail::DynamicAttrStorage2309e0b5533SMathieu Fehr static DynamicAttrStorage *construct(AttributeStorageAllocator &alloc,
2319e0b5533SMathieu Fehr const KeyTy &key) {
2329e0b5533SMathieu Fehr return new (alloc.allocate<DynamicAttrStorage>())
2339e0b5533SMathieu Fehr DynamicAttrStorage(key.first, alloc.copyInto(key.second));
2349e0b5533SMathieu Fehr }
2359e0b5533SMathieu Fehr
2369e0b5533SMathieu Fehr /// Definition of the type.
2379e0b5533SMathieu Fehr DynamicAttrDefinition *attrDef;
2389e0b5533SMathieu Fehr
2399e0b5533SMathieu Fehr /// The type parameters.
2409e0b5533SMathieu Fehr ArrayRef<Attribute> params;
2419e0b5533SMathieu Fehr };
2429e0b5533SMathieu Fehr } // namespace detail
2439e0b5533SMathieu Fehr } // namespace mlir
2449e0b5533SMathieu Fehr
get(DynamicAttrDefinition * attrDef,ArrayRef<Attribute> params)2459e0b5533SMathieu Fehr DynamicAttr DynamicAttr::get(DynamicAttrDefinition *attrDef,
2469e0b5533SMathieu Fehr ArrayRef<Attribute> params) {
2479e0b5533SMathieu Fehr auto &ctx = attrDef->getContext();
2489e0b5533SMathieu Fehr return detail::AttributeUniquer::getWithTypeID<DynamicAttr>(
2499e0b5533SMathieu Fehr &ctx, attrDef->getTypeID(), attrDef, params);
2509e0b5533SMathieu Fehr }
2519e0b5533SMathieu Fehr
2529e0b5533SMathieu Fehr DynamicAttr
getChecked(function_ref<InFlightDiagnostic ()> emitError,DynamicAttrDefinition * attrDef,ArrayRef<Attribute> params)2539e0b5533SMathieu Fehr DynamicAttr::getChecked(function_ref<InFlightDiagnostic()> emitError,
2549e0b5533SMathieu Fehr DynamicAttrDefinition *attrDef,
2559e0b5533SMathieu Fehr ArrayRef<Attribute> params) {
2569e0b5533SMathieu Fehr if (failed(attrDef->verify(emitError, params)))
2579e0b5533SMathieu Fehr return {};
2589e0b5533SMathieu Fehr return get(attrDef, params);
2599e0b5533SMathieu Fehr }
2609e0b5533SMathieu Fehr
getAttrDef()2619e0b5533SMathieu Fehr DynamicAttrDefinition *DynamicAttr::getAttrDef() { return getImpl()->attrDef; }
2629e0b5533SMathieu Fehr
getParams()2639e0b5533SMathieu Fehr ArrayRef<Attribute> DynamicAttr::getParams() { return getImpl()->params; }
2649e0b5533SMathieu Fehr
classof(Attribute attr)2659e0b5533SMathieu Fehr bool DynamicAttr::classof(Attribute attr) {
2669e0b5533SMathieu Fehr return attr.hasTrait<AttributeTrait::IsDynamicAttr>();
2679e0b5533SMathieu Fehr }
2689e0b5533SMathieu Fehr
parse(AsmParser & parser,DynamicAttrDefinition * attrDef,DynamicAttr & parsedAttr)2699e0b5533SMathieu Fehr ParseResult DynamicAttr::parse(AsmParser &parser,
2709e0b5533SMathieu Fehr DynamicAttrDefinition *attrDef,
2719e0b5533SMathieu Fehr DynamicAttr &parsedAttr) {
2729e0b5533SMathieu Fehr SmallVector<Attribute> params;
2739e0b5533SMathieu Fehr if (failed(attrDef->parser(parser, params)))
2749e0b5533SMathieu Fehr return failure();
2759e0b5533SMathieu Fehr parsedAttr = parser.getChecked<DynamicAttr>(attrDef, params);
2769e0b5533SMathieu Fehr if (!parsedAttr)
2779e0b5533SMathieu Fehr return failure();
2789e0b5533SMathieu Fehr return success();
2799e0b5533SMathieu Fehr }
2809e0b5533SMathieu Fehr
print(AsmPrinter & printer)2819e0b5533SMathieu Fehr void DynamicAttr::print(AsmPrinter &printer) {
2829e0b5533SMathieu Fehr printer << getAttrDef()->getName();
2839e0b5533SMathieu Fehr getAttrDef()->printer(printer, getParams());
2849e0b5533SMathieu Fehr }
2859e0b5533SMathieu Fehr
2869e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
2879e0b5533SMathieu Fehr // Dynamic operation
2889e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
2899e0b5533SMathieu Fehr
DynamicOpDefinition(StringRef name,ExtensibleDialect * dialect,OperationName::VerifyInvariantsFn && verifyFn,OperationName::VerifyRegionInvariantsFn && verifyRegionFn,OperationName::ParseAssemblyFn && parseFn,OperationName::PrintAssemblyFn && printFn,OperationName::FoldHookFn && foldHookFn,OperationName::GetCanonicalizationPatternsFn && getCanonicalizationPatternsFn,OperationName::PopulateDefaultAttrsFn && populateDefaultAttrsFn)2909e0b5533SMathieu Fehr DynamicOpDefinition::DynamicOpDefinition(
2919e0b5533SMathieu Fehr StringRef name, ExtensibleDialect *dialect,
2929e0b5533SMathieu Fehr OperationName::VerifyInvariantsFn &&verifyFn,
2939e0b5533SMathieu Fehr OperationName::VerifyRegionInvariantsFn &&verifyRegionFn,
2949e0b5533SMathieu Fehr OperationName::ParseAssemblyFn &&parseFn,
2959e0b5533SMathieu Fehr OperationName::PrintAssemblyFn &&printFn,
2969e0b5533SMathieu Fehr OperationName::FoldHookFn &&foldHookFn,
2979e0b5533SMathieu Fehr OperationName::GetCanonicalizationPatternsFn
298*69b6454fSJacques Pienaar &&getCanonicalizationPatternsFn,
299*69b6454fSJacques Pienaar OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn)
3009e0b5533SMathieu Fehr : typeID(dialect->allocateTypeID()),
3019e0b5533SMathieu Fehr name((dialect->getNamespace() + "." + name).str()), dialect(dialect),
3029e0b5533SMathieu Fehr verifyFn(std::move(verifyFn)), verifyRegionFn(std::move(verifyRegionFn)),
3039e0b5533SMathieu Fehr parseFn(std::move(parseFn)), printFn(std::move(printFn)),
3049e0b5533SMathieu Fehr foldHookFn(std::move(foldHookFn)),
305*69b6454fSJacques Pienaar getCanonicalizationPatternsFn(std::move(getCanonicalizationPatternsFn)),
306*69b6454fSJacques Pienaar populateDefaultAttrsFn(std::move(populateDefaultAttrsFn)) {}
3079e0b5533SMathieu Fehr
get(StringRef name,ExtensibleDialect * dialect,OperationName::VerifyInvariantsFn && verifyFn,OperationName::VerifyRegionInvariantsFn && verifyRegionFn)3089e0b5533SMathieu Fehr std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
3099e0b5533SMathieu Fehr StringRef name, ExtensibleDialect *dialect,
3109e0b5533SMathieu Fehr OperationName::VerifyInvariantsFn &&verifyFn,
3119e0b5533SMathieu Fehr OperationName::VerifyRegionInvariantsFn &&verifyRegionFn) {
3129e0b5533SMathieu Fehr auto parseFn = [](OpAsmParser &parser, OperationState &result) {
3139e0b5533SMathieu Fehr return parser.emitError(
3149e0b5533SMathieu Fehr parser.getCurrentLocation(),
3159e0b5533SMathieu Fehr "dynamic operation do not define any parser function");
3169e0b5533SMathieu Fehr };
3179e0b5533SMathieu Fehr
3189e0b5533SMathieu Fehr auto printFn = [](Operation *op, OpAsmPrinter &printer, StringRef) {
3199e0b5533SMathieu Fehr printer.printGenericOp(op);
3209e0b5533SMathieu Fehr };
3219e0b5533SMathieu Fehr
3229e0b5533SMathieu Fehr return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
3239e0b5533SMathieu Fehr std::move(verifyRegionFn), std::move(parseFn),
3249e0b5533SMathieu Fehr std::move(printFn));
3259e0b5533SMathieu Fehr }
3269e0b5533SMathieu Fehr
get(StringRef name,ExtensibleDialect * dialect,OperationName::VerifyInvariantsFn && verifyFn,OperationName::VerifyRegionInvariantsFn && verifyRegionFn,OperationName::ParseAssemblyFn && parseFn,OperationName::PrintAssemblyFn && printFn)3279e0b5533SMathieu Fehr std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
3289e0b5533SMathieu Fehr StringRef name, ExtensibleDialect *dialect,
3299e0b5533SMathieu Fehr OperationName::VerifyInvariantsFn &&verifyFn,
3309e0b5533SMathieu Fehr OperationName::VerifyRegionInvariantsFn &&verifyRegionFn,
3319e0b5533SMathieu Fehr OperationName::ParseAssemblyFn &&parseFn,
3329e0b5533SMathieu Fehr OperationName::PrintAssemblyFn &&printFn) {
3339e0b5533SMathieu Fehr auto foldHookFn = [](Operation *op, ArrayRef<Attribute> operands,
3349e0b5533SMathieu Fehr SmallVectorImpl<OpFoldResult> &results) {
3359e0b5533SMathieu Fehr return failure();
3369e0b5533SMathieu Fehr };
3379e0b5533SMathieu Fehr
3389e0b5533SMathieu Fehr auto getCanonicalizationPatternsFn = [](RewritePatternSet &, MLIRContext *) {
3399e0b5533SMathieu Fehr };
3409e0b5533SMathieu Fehr
341*69b6454fSJacques Pienaar auto populateDefaultAttrsFn = [](const RegisteredOperationName &,
342*69b6454fSJacques Pienaar NamedAttrList &) {};
343*69b6454fSJacques Pienaar
3449e0b5533SMathieu Fehr return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
3459e0b5533SMathieu Fehr std::move(verifyRegionFn), std::move(parseFn),
3469e0b5533SMathieu Fehr std::move(printFn), std::move(foldHookFn),
347*69b6454fSJacques Pienaar std::move(getCanonicalizationPatternsFn),
348*69b6454fSJacques Pienaar std::move(populateDefaultAttrsFn));
3499e0b5533SMathieu Fehr }
3509e0b5533SMathieu Fehr
get(StringRef name,ExtensibleDialect * dialect,OperationName::VerifyInvariantsFn && verifyFn,OperationName::VerifyInvariantsFn && verifyRegionFn,OperationName::ParseAssemblyFn && parseFn,OperationName::PrintAssemblyFn && printFn,OperationName::FoldHookFn && foldHookFn,OperationName::GetCanonicalizationPatternsFn && getCanonicalizationPatternsFn,OperationName::PopulateDefaultAttrsFn && populateDefaultAttrsFn)351*69b6454fSJacques Pienaar std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
352*69b6454fSJacques Pienaar StringRef name, ExtensibleDialect *dialect,
3539e0b5533SMathieu Fehr OperationName::VerifyInvariantsFn &&verifyFn,
3549e0b5533SMathieu Fehr OperationName::VerifyInvariantsFn &&verifyRegionFn,
3559e0b5533SMathieu Fehr OperationName::ParseAssemblyFn &&parseFn,
3569e0b5533SMathieu Fehr OperationName::PrintAssemblyFn &&printFn,
3579e0b5533SMathieu Fehr OperationName::FoldHookFn &&foldHookFn,
3589e0b5533SMathieu Fehr OperationName::GetCanonicalizationPatternsFn
359*69b6454fSJacques Pienaar &&getCanonicalizationPatternsFn,
360*69b6454fSJacques Pienaar OperationName::PopulateDefaultAttrsFn &&populateDefaultAttrsFn) {
3619e0b5533SMathieu Fehr return std::unique_ptr<DynamicOpDefinition>(new DynamicOpDefinition(
3629e0b5533SMathieu Fehr name, dialect, std::move(verifyFn), std::move(verifyRegionFn),
3639e0b5533SMathieu Fehr std::move(parseFn), std::move(printFn), std::move(foldHookFn),
364*69b6454fSJacques Pienaar std::move(getCanonicalizationPatternsFn),
365*69b6454fSJacques Pienaar std::move(populateDefaultAttrsFn)));
3669e0b5533SMathieu Fehr }
3679e0b5533SMathieu Fehr
3689e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
3699e0b5533SMathieu Fehr // Extensible dialect
3709e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
3719e0b5533SMathieu Fehr
3729e0b5533SMathieu Fehr namespace {
3739e0b5533SMathieu Fehr /// Interface that can only be implemented by extensible dialects.
3749e0b5533SMathieu Fehr /// The interface is used to check if a dialect is extensible or not.
3759e0b5533SMathieu Fehr class IsExtensibleDialect : public DialectInterface::Base<IsExtensibleDialect> {
3769e0b5533SMathieu Fehr public:
IsExtensibleDialect(Dialect * dialect)3779e0b5533SMathieu Fehr IsExtensibleDialect(Dialect *dialect) : Base(dialect) {}
3789e0b5533SMathieu Fehr
3799e0b5533SMathieu Fehr MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(IsExtensibleDialect)
3809e0b5533SMathieu Fehr };
3819e0b5533SMathieu Fehr } // namespace
3829e0b5533SMathieu Fehr
ExtensibleDialect(StringRef name,MLIRContext * ctx,TypeID typeID)3839e0b5533SMathieu Fehr ExtensibleDialect::ExtensibleDialect(StringRef name, MLIRContext *ctx,
3849e0b5533SMathieu Fehr TypeID typeID)
3859e0b5533SMathieu Fehr : Dialect(name, ctx, typeID) {
3869e0b5533SMathieu Fehr addInterfaces<IsExtensibleDialect>();
3879e0b5533SMathieu Fehr }
3889e0b5533SMathieu Fehr
registerDynamicType(std::unique_ptr<DynamicTypeDefinition> && type)3899e0b5533SMathieu Fehr void ExtensibleDialect::registerDynamicType(
3909e0b5533SMathieu Fehr std::unique_ptr<DynamicTypeDefinition> &&type) {
3919e0b5533SMathieu Fehr DynamicTypeDefinition *typePtr = type.get();
3929e0b5533SMathieu Fehr TypeID typeID = type->getTypeID();
3939e0b5533SMathieu Fehr StringRef name = type->getName();
3949e0b5533SMathieu Fehr ExtensibleDialect *dialect = type->getDialect();
3959e0b5533SMathieu Fehr
3969e0b5533SMathieu Fehr assert(dialect == this &&
3979e0b5533SMathieu Fehr "trying to register a dynamic type in the wrong dialect");
3989e0b5533SMathieu Fehr
3999e0b5533SMathieu Fehr // If a type with the same name is already defined, fail.
4009e0b5533SMathieu Fehr auto registered = dynTypes.try_emplace(typeID, std::move(type)).second;
4019e0b5533SMathieu Fehr (void)registered;
4029e0b5533SMathieu Fehr assert(registered && "type TypeID was not unique");
4039e0b5533SMathieu Fehr
4049e0b5533SMathieu Fehr registered = nameToDynTypes.insert({name, typePtr}).second;
4059e0b5533SMathieu Fehr (void)registered;
4069e0b5533SMathieu Fehr assert(registered &&
4079e0b5533SMathieu Fehr "Trying to create a new dynamic type with an existing name");
4089e0b5533SMathieu Fehr
4099e0b5533SMathieu Fehr auto abstractType =
4109e0b5533SMathieu Fehr AbstractType::get(*dialect, DynamicAttr::getInterfaceMap(),
4119e0b5533SMathieu Fehr DynamicType::getHasTraitFn(), typeID);
4129e0b5533SMathieu Fehr
4139e0b5533SMathieu Fehr /// Add the type to the dialect and the type uniquer.
4149e0b5533SMathieu Fehr addType(typeID, std::move(abstractType));
4159e0b5533SMathieu Fehr typePtr->registerInTypeUniquer();
4169e0b5533SMathieu Fehr }
4179e0b5533SMathieu Fehr
registerDynamicAttr(std::unique_ptr<DynamicAttrDefinition> && attr)4189e0b5533SMathieu Fehr void ExtensibleDialect::registerDynamicAttr(
4199e0b5533SMathieu Fehr std::unique_ptr<DynamicAttrDefinition> &&attr) {
4209e0b5533SMathieu Fehr auto *attrPtr = attr.get();
4219e0b5533SMathieu Fehr auto typeID = attr->getTypeID();
4229e0b5533SMathieu Fehr auto name = attr->getName();
4239e0b5533SMathieu Fehr auto *dialect = attr->getDialect();
4249e0b5533SMathieu Fehr
4259e0b5533SMathieu Fehr assert(dialect == this &&
4269e0b5533SMathieu Fehr "trying to register a dynamic attribute in the wrong dialect");
4279e0b5533SMathieu Fehr
4289e0b5533SMathieu Fehr // If an attribute with the same name is already defined, fail.
4299e0b5533SMathieu Fehr auto registered = dynAttrs.try_emplace(typeID, std::move(attr)).second;
4309e0b5533SMathieu Fehr (void)registered;
4319e0b5533SMathieu Fehr assert(registered && "attribute TypeID was not unique");
4329e0b5533SMathieu Fehr
4339e0b5533SMathieu Fehr registered = nameToDynAttrs.insert({name, attrPtr}).second;
4349e0b5533SMathieu Fehr (void)registered;
4359e0b5533SMathieu Fehr assert(registered &&
4369e0b5533SMathieu Fehr "Trying to create a new dynamic attribute with an existing name");
4379e0b5533SMathieu Fehr
4389e0b5533SMathieu Fehr auto abstractAttr =
4399e0b5533SMathieu Fehr AbstractAttribute::get(*dialect, DynamicAttr::getInterfaceMap(),
4409e0b5533SMathieu Fehr DynamicAttr::getHasTraitFn(), typeID);
4419e0b5533SMathieu Fehr
4429e0b5533SMathieu Fehr /// Add the type to the dialect and the type uniquer.
4439e0b5533SMathieu Fehr addAttribute(typeID, std::move(abstractAttr));
4449e0b5533SMathieu Fehr attrPtr->registerInAttrUniquer();
4459e0b5533SMathieu Fehr }
4469e0b5533SMathieu Fehr
registerDynamicOp(std::unique_ptr<DynamicOpDefinition> && op)4479e0b5533SMathieu Fehr void ExtensibleDialect::registerDynamicOp(
4489e0b5533SMathieu Fehr std::unique_ptr<DynamicOpDefinition> &&op) {
4499e0b5533SMathieu Fehr assert(op->dialect == this &&
4509e0b5533SMathieu Fehr "trying to register a dynamic op in the wrong dialect");
4519e0b5533SMathieu Fehr auto hasTraitFn = [](TypeID traitId) { return false; };
4529e0b5533SMathieu Fehr
4539e0b5533SMathieu Fehr RegisteredOperationName::insert(
4549e0b5533SMathieu Fehr op->name, *op->dialect, op->typeID, std::move(op->parseFn),
4559e0b5533SMathieu Fehr std::move(op->printFn), std::move(op->verifyFn),
4569e0b5533SMathieu Fehr std::move(op->verifyRegionFn), std::move(op->foldHookFn),
4579e0b5533SMathieu Fehr std::move(op->getCanonicalizationPatternsFn),
45882140ad7SJacques Pienaar detail::InterfaceMap::get<>(), std::move(hasTraitFn), {},
459*69b6454fSJacques Pienaar std::move(op->populateDefaultAttrsFn));
4609e0b5533SMathieu Fehr }
4619e0b5533SMathieu Fehr
classof(const Dialect * dialect)4629e0b5533SMathieu Fehr bool ExtensibleDialect::classof(const Dialect *dialect) {
4639e0b5533SMathieu Fehr return const_cast<Dialect *>(dialect)
4649e0b5533SMathieu Fehr ->getRegisteredInterface<IsExtensibleDialect>();
4659e0b5533SMathieu Fehr }
4669e0b5533SMathieu Fehr
parseOptionalDynamicType(StringRef typeName,AsmParser & parser,Type & resultType) const4679e0b5533SMathieu Fehr OptionalParseResult ExtensibleDialect::parseOptionalDynamicType(
4689e0b5533SMathieu Fehr StringRef typeName, AsmParser &parser, Type &resultType) const {
4699e0b5533SMathieu Fehr DynamicTypeDefinition *typeDef = lookupTypeDefinition(typeName);
4709e0b5533SMathieu Fehr if (!typeDef)
4719e0b5533SMathieu Fehr return llvm::None;
4729e0b5533SMathieu Fehr
4739e0b5533SMathieu Fehr DynamicType dynType;
4749e0b5533SMathieu Fehr if (DynamicType::parse(parser, typeDef, dynType))
4759e0b5533SMathieu Fehr return failure();
4769e0b5533SMathieu Fehr resultType = dynType;
4779e0b5533SMathieu Fehr return success();
4789e0b5533SMathieu Fehr }
4799e0b5533SMathieu Fehr
printIfDynamicType(Type type,AsmPrinter & printer)4809e0b5533SMathieu Fehr LogicalResult ExtensibleDialect::printIfDynamicType(Type type,
4819e0b5533SMathieu Fehr AsmPrinter &printer) {
4829e0b5533SMathieu Fehr if (auto dynType = type.dyn_cast<DynamicType>()) {
4839e0b5533SMathieu Fehr dynType.print(printer);
4849e0b5533SMathieu Fehr return success();
4859e0b5533SMathieu Fehr }
4869e0b5533SMathieu Fehr return failure();
4879e0b5533SMathieu Fehr }
4889e0b5533SMathieu Fehr
parseOptionalDynamicAttr(StringRef attrName,AsmParser & parser,Attribute & resultAttr) const4899e0b5533SMathieu Fehr OptionalParseResult ExtensibleDialect::parseOptionalDynamicAttr(
4909e0b5533SMathieu Fehr StringRef attrName, AsmParser &parser, Attribute &resultAttr) const {
4919e0b5533SMathieu Fehr DynamicAttrDefinition *attrDef = lookupAttrDefinition(attrName);
4929e0b5533SMathieu Fehr if (!attrDef)
4939e0b5533SMathieu Fehr return llvm::None;
4949e0b5533SMathieu Fehr
4959e0b5533SMathieu Fehr DynamicAttr dynAttr;
4969e0b5533SMathieu Fehr if (DynamicAttr::parse(parser, attrDef, dynAttr))
4979e0b5533SMathieu Fehr return failure();
4989e0b5533SMathieu Fehr resultAttr = dynAttr;
4999e0b5533SMathieu Fehr return success();
5009e0b5533SMathieu Fehr }
5019e0b5533SMathieu Fehr
printIfDynamicAttr(Attribute attribute,AsmPrinter & printer)5029e0b5533SMathieu Fehr LogicalResult ExtensibleDialect::printIfDynamicAttr(Attribute attribute,
5039e0b5533SMathieu Fehr AsmPrinter &printer) {
5049e0b5533SMathieu Fehr if (auto dynAttr = attribute.dyn_cast<DynamicAttr>()) {
5059e0b5533SMathieu Fehr dynAttr.print(printer);
5069e0b5533SMathieu Fehr return success();
5079e0b5533SMathieu Fehr }
5089e0b5533SMathieu Fehr return failure();
5099e0b5533SMathieu Fehr }
510