[Mlir-commits] [mlir] 1b2e35e - Revert "[mlir] Add extensible dialects"

Andrzej Warzynski llvmlistbot at llvm.org
Thu Mar 3 02:31:03 PST 2022


Author: Andrzej Warzynski
Date: 2022-03-03T10:30:50Z
New Revision: 1b2e35e4d484e5ec6bbc71d333427aae2e30e4de

URL: https://github.com/llvm/llvm-project/commit/1b2e35e4d484e5ec6bbc71d333427aae2e30e4de
DIFF: https://github.com/llvm/llvm-project/commit/1b2e35e4d484e5ec6bbc71d333427aae2e30e4de.diff

LOG: Revert "[mlir] Add extensible dialects"

This reverts commit dbe9f0914fcfd8444fd9656821af0f1a34a27e7a.

The flang-x86_64-windows buildbot has been failing since this has been merged:
* https://lab.llvm.org/buildbot/#/builders/172/builds/9124
Similar failure was reported by the pre-commit CI.

Added: 
    

Modified: 
    mlir/include/mlir/IR/AttributeSupport.h
    mlir/include/mlir/IR/Dialect.h
    mlir/include/mlir/IR/OpBase.td
    mlir/include/mlir/IR/TypeSupport.h
    mlir/include/mlir/TableGen/Dialect.h
    mlir/lib/IR/CMakeLists.txt
    mlir/lib/TableGen/Dialect.cpp
    mlir/test/lib/Dialect/Test/TestAttributes.cpp
    mlir/test/lib/Dialect/Test/TestDialect.cpp
    mlir/test/lib/Dialect/Test/TestDialect.h
    mlir/test/lib/Dialect/Test/TestDialect.td
    mlir/test/lib/Dialect/Test/TestTypes.cpp
    mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
    mlir/tools/mlir-tblgen/DialectGen.cpp

Removed: 
    mlir/docs/ExtensibleDialects.md
    mlir/include/mlir/IR/ExtensibleDialect.h
    mlir/lib/IR/ExtensibleDialect.cpp
    mlir/test/IR/dynamic.mlir


################################################################################
diff  --git a/mlir/docs/ExtensibleDialects.md b/mlir/docs/ExtensibleDialects.md
deleted file mode 100644
index e46e4061924b7..0000000000000
--- a/mlir/docs/ExtensibleDialects.md
+++ /dev/null
@@ -1,369 +0,0 @@
-# Extensible dialects
-
-This file documents the design and API of the extensible dialects. Extensible
-dialects are dialects that can be extended with new operations and types defined
-at runtime. This allows for users to define dialects via with meta-programming,
-or from another language, without having to recompile C++ code.
-
-[TOC]
-
-## Usage
-
-### Defining an extensible dialect
-
-Dialects defined in C++ can be extended with new operations, types, etc., at
-runtime by inheriting from `mlir::ExtensibleDialect` instead of `mlir::Dialect`
-(note that `ExtensibleDialect` inherits from `Dialect`). The `ExtensibleDialect`
-class contains the necessary fields and methods to extend the dialect at
-runtime.
-
-```c++
-class MyDialect : public mlir::ExtensibleDialect {
-    ...
-}
-```
-
-For dialects defined in TableGen, this is done by setting the `isExtensible`
-flag to `1`.
-
-```tablegen
-def Test_Dialect : Dialect {
-  let isExtensible = 1;
-  ...
-}
-```
-
-An extensible `Dialect` can be casted back to `ExtensibleDialect` using
-`llvm::dyn_cast`, or `llvm::cast`:
-
-```c++
-if (auto extensibleDialect = llvm::dyn_cast<ExtensibleDialect>(dialect)) {
-    ...
-}
-```
-
-### Defining an operation at runtime
-
-The `DynamicOpDefinition` class represents the definition of an operation
-defined at runtime. It is created using the `DynamicOpDefinition::get`
-functions. An operation defined at runtime must provide a name, a dialect in
-which the operation will be registered in, an operation verifier. It may also
-optionally define a custom parser and a printer, fold hook, and more.
-
-```c++
-// The operation name, without the dialect name prefix.
-StringRef name = "my_operation_name";
-
-// The dialect defining the operation.
-Dialect* dialect = ctx->getOrLoadDialect<MyDialect>();
-
-// Operation verifier definition.
-AbstractOperation::VerifyInvariantsFn verifyFn = [](Operation* op) {
-    // Logic for the operation verification.
-    ...
-}
-
-// Parser function definition.
-AbstractOperation::ParseAssemblyFn parseFn =
-    [](OpAsmParser &parser, OperationState &state) {
-        // Parse the operation, given that the name is already parsed.
-        ...    
-};
-
-// Printer function
-auto printFn = [](Operation *op, OpAsmPrinter &printer) {
-        printer << op->getName();
-        // Print the operation, given that the name is already printed.
-        ...
-};
-
-// General folder implementation, see AbstractOperation::foldHook for more
-// information.
-auto foldHookFn = [](Operation * op, ArrayRef<Attribute> operands, 
-                                   SmallVectorImpl<OpFoldResult> &result) {
-    ...
-};
-
-// Returns any canonicalization pattern rewrites that the operation
-// supports, for use by the canonicalization pass.
-auto getCanonicalizationPatterns = 
-        [](RewritePatternSet &results, MLIRContext *context) {
-    ...
-}
-
-// Definition of the operation.
-std::unique_ptr<DynamicOpDefinition> opDef =
-    DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
-        std::move(parseFn), std::move(printFn), std::move(foldHookFn),
-        std::move(getCanonicalizationPatterns));
-```
-
-Once the operation is defined, it can be registered by an `ExtensibleDialect`:
-
-```c++
-extensibleDialect->registerDynamicOperation(std::move(opDef));
-```
-
-Note that the `Dialect` given to the operation should be the one registering
-the operation.
-
-### Using an operation defined at runtime
-
-It is possible to match on an operation defined at runtime using their names:
-
-```c++
-if (op->getName().getStringRef() == "my_dialect.my_dynamic_op") {
-    ...
-}
-```
-
-An operation defined at runtime can be created by instantiating an
-`OperationState` with the operation name, and using it with a rewriter
-(for instance a `PatternRewriter`) to create the operation.
-
-```c++
-OperationState state(location, "my_dialect.my_dynamic_op",
-                     operands, resultTypes, attributes);
-
-rewriter.createOperation(state);
-```
-
-
-### Defining a type at runtime
-
-Contrary to types defined in C++ or in TableGen, types defined at runtime can
-only have as argument a list of `Attribute`.
-
-Similarily to operations, a type is defined at runtime using the class
-`DynamicTypeDefinition`, which is created using the `DynamicTypeDefinition::get`
-functions. A type definition requires a name, the dialect that will register the
-type, and a parameter verifier. It can also define optionally a custom parser
-and printer for the arguments (the type name is assumed to be already
-parsed/printed).
-
-```c++
-// The type name, without the dialect name prefix.
-StringRef name = "my_type_name";
-
-// The dialect defining the type.
-Dialect* dialect = ctx->getOrLoadDialect<MyDialect>();
-
-// The type verifier.
-// A type defined at runtime has a list of attributes as parameters.
-auto verifier = [](function_ref<InFlightDiagnostic()> emitError,
-                   ArrayRef<Attribute> args) {
-    ...
-};
-
-// The type parameters parser.
-auto parser = [](DialectAsmParser &parser,
-                 llvm::SmallVectorImpl<Attribute> &parsedParams) {
-    ...
-};
-
-// The type parameters printer.
-auto printer =[](DialectAsmPrinter &printer, ArrayRef<Attribute> params) {
-    ...
-};
-
-std::unique_ptr<DynamicTypeDefinition> typeDef =
-    DynamicTypeDefinition::get(std::move(name), std::move(dialect),
-                               std::move(verifier), std::move(printer),
-                               std::move(parser));
-```
-
-If the printer and the parser are ommited, a default parser and printer is
-generated with the format `!dialect.typename<arg1, arg2, ..., argN>`.
-
-The type can then be registered by the `ExtensibleDialect`:
-
-```c++
-dialect->registerDynamicType(std::move(typeDef));
-```
-
-### Parsing types defined at runtime in an extensible dialect
-
-`parseType` methods generated by TableGen can parse types defined at runtime,
-though overriden `parseType` methods need to add the necessary support for them.
-
-```c++
-Type MyDialect::parseType(DialectAsmParser &parser) const {
-    ...
-    
-    // The type name.
-    StringRef typeTag;
-    if (failed(parser.parseKeyword(&typeTag)))
-        return Type();
-
-    // Try to parse a dynamic type with 'typeTag' name.
-    Type dynType;
-    auto parseResult = parseOptionalDynamicType(typeTag, parser, dynType);
-    if (parseResult.hasValue()) {
-        if (succeeded(parseResult.getValue()))
-            return dynType;
-         return Type();
-    }
-    
-    ...
-}
-```
-
-### Using a type defined at runtime
-
-Dynamic types are instances of `DynamicType`. It is possible to get a dynamic
-type with `DynamicType::get` and `ExtensibleDialect::lookupTypeDefinition`.
-
-```c++
-auto typeDef = extensibleDialect->lookupTypeDefinition("my_dynamic_type");
-ArrayRef<Attribute> params = ...;
-auto type = DynamicType::get(typeDef, params);
-```
-
-It is also possible to cast a `Type` known to be defined at runtime to a
-`DynamicType`.
-
-```c++
-auto dynType = type.cast<DynamicType>();
-auto typeDef = dynType.getTypeDef();
-auto args = dynType.getParams();
-```
-
-### Defining an attribute at runtime
-
-Similar to types defined at runtime, attributes defined at runtime can only have
-as argument a list of `Attribute`.
-
-Similarily to types, an attribute is defined at runtime using the class
-`DynamicAttrDefinition`, which is created using the `DynamicAttrDefinition::get`
-functions. An attribute definition requires a name, the dialect that will
-register the attribute, and a parameter verifier. It can also define optionally
-a custom parser and printer for the arguments (the attribute name is assumed to
-be already parsed/printed).
-
-```c++
-// The attribute name, without the dialect name prefix.
-StringRef name = "my_attribute_name";
-
-// The dialect defining the attribute.
-Dialect* dialect = ctx->getOrLoadDialect<MyDialect>();
-
-// The attribute verifier.
-// An attribute defined at runtime has a list of attributes as parameters.
-auto verifier = [](function_ref<InFlightDiagnostic()> emitError,
-                   ArrayRef<Attribute> args) {
-    ...
-};
-
-// The attribute parameters parser.
-auto parser = [](DialectAsmParser &parser,
-                 llvm::SmallVectorImpl<Attribute> &parsedParams) {
-    ...
-};
-
-// The attribute parameters printer.
-auto printer =[](DialectAsmPrinter &printer, ArrayRef<Attribute> params) {
-    ...
-};
-
-std::unique_ptr<DynamicAttrDefinition> attrDef =
-    DynamicAttrDefinition::get(std::move(name), std::move(dialect),
-                               std::move(verifier), std::move(printer),
-                               std::move(parser));
-```
-
-If the printer and the parser are ommited, a default parser and printer is
-generated with the format `!dialect.attrname<arg1, arg2, ..., argN>`.
-
-The attribute can then be registered by the `ExtensibleDialect`:
-
-```c++
-dialect->registerDynamicAttr(std::move(typeDef));
-```
-
-### Parsing attributes defined at runtime in an extensible dialect
-
-`parseAttribute` methods generated by TableGen can parse attributes defined at
-runtime, though overriden `parseAttribute` methods need to add the necessary
-support for them.
-
-```c++
-Attribute MyDialect::parseAttribute(DialectAsmParser &parser,
-                                    Type type) const override {
-    ...
-    // The attribute name.
-    StringRef attrTag;
-    if (failed(parser.parseKeyword(&attrTag)))
-        return Attribute();
-
-    // Try to parse a dynamic attribute with 'attrTag' name.
-    Attribute dynAttr;
-    auto parseResult = parseOptionalDynamicAttr(attrTag, parser, dynAttr);
-    if (parseResult.hasValue()) {
-        if (succeeded(parseResult.getValue()))
-            return dynAttr;
-         return Attribute();
-    }
-```
-
-### Using an attribute defined at runtime
-
-Similar to types, attributes defined at runtime are instances of `DynamicAttr`.
-It is possible to get a dynamic attribute with `DynamicAttr::get` and
-`ExtensibleDialect::lookupAttrDefinition`.
-
-```c++
-auto attrDef = extensibleDialect->lookupAttrDefinition("my_dynamic_attr");
-ArrayRef<Attribute> params = ...;
-auto attr = DynamicAttr::get(attrDef, params);
-```
-
-It is also possible to cast an `Attribute` known to be defined at runtime to a
-`DynamicAttr`.
-
-```c++
-auto dynAttr = attr.cast<DynamicAttr>();
-auto attrDef = dynAttr.getAttrDef();
-auto args = dynAttr.getParams();
-```
-
-## Implementation details
-
-### Extensible dialect
-
-The role of extensible dialects is to own the necessary data for defined
-operations and types. They also contain the necessary accessors to easily
-access them.
-
-In order to cast a `Dialect` back to an `ExtensibleDialect`, we implement the
-`IsExtensibleDialect` interface to all `ExtensibleDialect`. The casting is done
-by checking if the `Dialect` implements `IsExtensibleDialect` or not.
-
-### Operation representation and registration
-
-Operations are represented in mlir using the `AbstractOperation` class. They are
-registered in dialects the same way operations defined in C++ are registered,
-which is by calling `AbstractOperation::insert`.
-
-The only 
diff erence is that a new `TypeID` needs to be created for each
-operation, since operations are not represented by a C++ class. This is done
-using a `TypeIDAllocator`, which can allocate a new unique `TypeID` at runtime.
-
-### Type representation and registration
-
-Unlike operations, types need to define a C++ storage class that takes care of
-type parameters. They also need to define another C++ class to access that
-storage. `DynamicTypeStorage` defines the storage of types defined at runtime,
-and `DynamicType` gives access to the storage, as well as defining useful
-functions. A `DynamicTypeStorage` contains a list of `Attribute` type
-parameters, as well as a pointer to the type definition.
-
-Types are registered using the `Dialect::addType` method, which expect a
-`TypeID` that is generated using a `TypeIDAllocator`. The type uniquer also
-register the type with the given `TypeID`. This mean that we can reuse our
-single `DynamicType` with 
diff erent `TypeID` to represent the 
diff erent types
-defined at runtime.
-
-Since the 
diff erent types defined at runtime have 
diff erent `TypeID`, it is not
-possible to use `TypeID` to cast a `Type` into a `DynamicType`. Thus, similar to
-`Dialect`, all `DynamicType` define a `IsDynamicTypeTrait`, so casting a `Type`
-to a `DynamicType` boils down to querying the `IsDynamicTypeTrait` trait.

diff  --git a/mlir/include/mlir/IR/AttributeSupport.h b/mlir/include/mlir/IR/AttributeSupport.h
index 9b7843d03a117..9745207fd2ef1 100644
--- a/mlir/include/mlir/IR/AttributeSupport.h
+++ b/mlir/include/mlir/IR/AttributeSupport.h
@@ -45,17 +45,6 @@ class AbstractAttribute {
                              T::getTypeID());
   }
 
-  /// This method is used by Dialect objects to register attributes with
-  /// custom TypeIDs.
-  /// The use of this method is in general discouraged in favor of
-  /// 'get<CustomAttribute>(dialect)'.
-  static AbstractAttribute get(Dialect &dialect,
-                               detail::InterfaceMap &&interfaceMap,
-                               HasTraitFn &&hasTrait, TypeID typeID) {
-    return AbstractAttribute(dialect, std::move(interfaceMap),
-                             std::move(hasTrait), typeID);
-  }
-
   /// Return the dialect this attribute was registered to.
   Dialect &getDialect() const { return const_cast<Dialect &>(dialect); }
 
@@ -186,22 +175,14 @@ namespace detail {
 // MLIRContext. This class manages all creation and uniquing of attributes.
 class AttributeUniquer {
 public:
-  /// Get an uniqued instance of an attribute T.
-  template <typename T, typename... Args>
-  static T get(MLIRContext *ctx, Args &&... args) {
-    return getWithTypeID<T, Args...>(ctx, T::getTypeID(),
-                                     std::forward<Args>(args)...);
-  }
-
   /// Get an uniqued instance of a parametric attribute T.
-  /// The use of this method is in general discouraged in favor of
-  /// 'get<T, Args>(ctx, args)'.
   template <typename T, typename... Args>
   static typename std::enable_if_t<
       !std::is_same<typename T::ImplType, AttributeStorage>::value, T>
-  getWithTypeID(MLIRContext *ctx, TypeID typeID, Args &&... args) {
+  get(MLIRContext *ctx, Args &&...args) {
 #ifndef NDEBUG
-    if (!ctx->getAttributeUniquer().isParametricStorageInitialized(typeID))
+    if (!ctx->getAttributeUniquer().isParametricStorageInitialized(
+            T::getTypeID()))
       llvm::report_fatal_error(
           llvm::Twine("can't create Attribute '") + llvm::getTypeName<T>() +
           "' because storage uniquer isn't initialized: the dialect was likely "
@@ -209,68 +190,57 @@ class AttributeUniquer {
           "in the Dialect::initialize() method.");
 #endif
     return ctx->getAttributeUniquer().get<typename T::ImplType>(
-        [typeID, ctx](AttributeStorage *storage) {
-          initializeAttributeStorage(storage, ctx, typeID);
+        [ctx](AttributeStorage *storage) {
+          initializeAttributeStorage(storage, ctx, T::getTypeID());
 
           // Execute any additional attribute storage initialization with the
           // context.
           static_cast<typename T::ImplType *>(storage)->initialize(ctx);
         },
-        typeID, std::forward<Args>(args)...);
+        T::getTypeID(), std::forward<Args>(args)...);
   }
   /// Get an uniqued instance of a singleton attribute T.
-  /// The use of this method is in general discouraged in favor of
-  /// 'get<T, Args>(ctx, args)'.
   template <typename T>
   static typename std::enable_if_t<
       std::is_same<typename T::ImplType, AttributeStorage>::value, T>
-  getWithTypeID(MLIRContext *ctx, TypeID typeID) {
+  get(MLIRContext *ctx) {
 #ifndef NDEBUG
-    if (!ctx->getAttributeUniquer().isSingletonStorageInitialized(typeID))
+    if (!ctx->getAttributeUniquer().isSingletonStorageInitialized(
+            T::getTypeID()))
       llvm::report_fatal_error(
           llvm::Twine("can't create Attribute '") + llvm::getTypeName<T>() +
           "' because storage uniquer isn't initialized: the dialect was likely "
           "not loaded, or the attribute wasn't added with addAttributes<...>() "
           "in the Dialect::initialize() method.");
 #endif
-    return ctx->getAttributeUniquer().get<typename T::ImplType>(typeID);
+    return ctx->getAttributeUniquer().get<typename T::ImplType>(T::getTypeID());
   }
 
   template <typename T, typename... Args>
   static LogicalResult mutate(MLIRContext *ctx, typename T::ImplType *impl,
-                              Args &&... args) {
+                              Args &&...args) {
     assert(impl && "cannot mutate null attribute");
     return ctx->getAttributeUniquer().mutate(T::getTypeID(), impl,
                                              std::forward<Args>(args)...);
   }
 
-  /// Register an attribute instance T with the uniquer.
-  template <typename T>
-  static void registerAttribute(MLIRContext *ctx) {
-    registerAttribute<T>(ctx, T::getTypeID());
-  }
-
   /// Register a parametric attribute instance T with the uniquer.
-  /// The use of this method is in general discouraged in favor of
-  /// 'registerAttribute<T>(ctx)'.
   template <typename T>
   static typename std::enable_if_t<
       !std::is_same<typename T::ImplType, AttributeStorage>::value>
-  registerAttribute(MLIRContext *ctx, TypeID typeID) {
+  registerAttribute(MLIRContext *ctx) {
     ctx->getAttributeUniquer()
-        .registerParametricStorageType<typename T::ImplType>(typeID);
+        .registerParametricStorageType<typename T::ImplType>(T::getTypeID());
   }
   /// Register a singleton attribute instance T with the uniquer.
-  /// The use of this method is in general discouraged in favor of
-  /// 'registerAttribute<T>(ctx)'.
   template <typename T>
   static typename std::enable_if_t<
       std::is_same<typename T::ImplType, AttributeStorage>::value>
-  registerAttribute(MLIRContext *ctx, TypeID typeID) {
+  registerAttribute(MLIRContext *ctx) {
     ctx->getAttributeUniquer()
         .registerSingletonStorageType<typename T::ImplType>(
-            typeID, [ctx, typeID](AttributeStorage *storage) {
-              initializeAttributeStorage(storage, ctx, typeID);
+            T::getTypeID(), [ctx](AttributeStorage *storage) {
+              initializeAttributeStorage(storage, ctx, T::getTypeID());
             });
   }
 

diff  --git a/mlir/include/mlir/IR/Dialect.h b/mlir/include/mlir/IR/Dialect.h
index ae017b9a1f09e..798d66faccdfa 100644
--- a/mlir/include/mlir/IR/Dialect.h
+++ b/mlir/include/mlir/IR/Dialect.h
@@ -212,11 +212,6 @@ class Dialect {
     (void)std::initializer_list<int>{0, (addAttribute<Args>(), 0)...};
   }
 
-  /// Register an attribute instance with this dialect.
-  /// The use of this method is in general discouraged in favor of
-  /// 'addAttributes<CustomAttr>()'.
-  void addAttribute(TypeID typeID, AbstractAttribute &&attrInfo);
-
   /// Enable support for unregistered operations.
   void allowUnknownOperations(bool allow = true) { unknownOpsAllowed = allow; }
 
@@ -242,6 +237,7 @@ class Dialect {
     addAttribute(T::getTypeID(), AbstractAttribute::get<T>(*this));
     detail::AttributeUniquer::registerAttribute<T>(context);
   }
+  void addAttribute(TypeID typeID, AbstractAttribute &&attrInfo);
 
   /// Register a type instance with this dialect.
   template <typename T> void addType() {

diff  --git a/mlir/include/mlir/IR/ExtensibleDialect.h b/mlir/include/mlir/IR/ExtensibleDialect.h
deleted file mode 100644
index 4bec652839f39..0000000000000
--- a/mlir/include/mlir/IR/ExtensibleDialect.h
+++ /dev/null
@@ -1,542 +0,0 @@
-//===- ExtensibleDialect.h - Extensible dialect -----------------*- C++ -*-===//
-//
-// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DynamicOpDefinition class, the DynamicTypeDefinition
-// class, and the DynamicAttrDefinition class, which represent respectively
-// operations, types, and attributes that can be defined at runtime. They can
-// be registered at runtime to an extensible dialect, using the
-// ExtensibleDialect class defined in this file.
-//
-// For a more complete documentation, see
-// https://mlir.llvm.org/docs/ExtensibleDialects/ .
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef MLIR_IR_EXTENSIBLEDIALECT_H
-#define MLIR_IR_EXTENSIBLEDIALECT_H
-
-#include "mlir/IR/Dialect.h"
-#include "mlir/IR/DialectInterface.h"
-#include "mlir/IR/MLIRContext.h"
-#include "mlir/IR/OpDefinition.h"
-#include "mlir/Support/TypeID.h"
-#include "llvm/ADT/StringMap.h"
-
-namespace mlir {
-class AsmParser;
-class AsmPrinter;
-class DynamicAttr;
-class DynamicType;
-class ExtensibleDialect;
-class MLIRContext;
-class OptionalParseResult;
-class ParseResult;
-
-namespace detail {
-struct DynamicAttrStorage;
-struct DynamicTypeStorage;
-} // namespace detail
-
-//===----------------------------------------------------------------------===//
-// Dynamic attribute
-//===----------------------------------------------------------------------===//
-
-/// The definition of a dynamic attribute. A dynamic attribute is an attribute
-/// that is defined at runtime, and that can be registered at runtime by an
-/// extensible dialect (a dialect inheriting ExtensibleDialect). This class
-/// stores the parser, the printer, and the verifier of the attribute. Each
-/// dynamic attribute definition refers to one instance of this class.
-class DynamicAttrDefinition : SelfOwningTypeID {
-public:
-  using VerifierFn = llvm::unique_function<LogicalResult(
-      function_ref<InFlightDiagnostic()>, ArrayRef<Attribute>) const>;
-  using ParserFn = llvm::unique_function<ParseResult(
-      AsmParser &parser, llvm::SmallVectorImpl<Attribute> &parsedAttributes)
-                                             const>;
-  using PrinterFn = llvm::unique_function<void(
-      AsmPrinter &printer, ArrayRef<Attribute> params) const>;
-
-  /// Create a new attribute definition at runtime. The attribute is registered
-  /// only after passing it to the dialect using registerDynamicAttr.
-  static std::unique_ptr<DynamicAttrDefinition>
-  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier);
-  static std::unique_ptr<DynamicAttrDefinition>
-  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier,
-      ParserFn &&parser, PrinterFn &&printer);
-
-  /// Check that the attribute parameters are valid.
-  LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
-                       ArrayRef<Attribute> params) const {
-    return verifier(emitError, params);
-  }
-
-  /// Return the MLIRContext in which the dynamic attributes are uniqued.
-  MLIRContext &getContext() const { return *ctx; }
-
-  /// Return the name of the attribute, in the format 'attrname' and
-  /// not 'dialectname.attrname'.
-  StringRef getName() const { return name; }
-
-  /// Return the dialect defining the attribute.
-  ExtensibleDialect *getDialect() const { return dialect; }
-
-private:
-  DynamicAttrDefinition(StringRef name, ExtensibleDialect *dialect,
-                        VerifierFn &&verifier, ParserFn &&parser,
-                        PrinterFn &&printer);
-
-  /// This constructor should only be used when we need a pointer to
-  /// the DynamicAttrDefinition in the verifier, the parser, or the printer.
-  /// The verifier, parser, and printer need thus to be initialized after the
-  /// constructor.
-  DynamicAttrDefinition(ExtensibleDialect *dialect, StringRef name);
-
-  /// Register the concrete attribute in the attribute Uniquer.
-  void registerInAttrUniquer();
-
-  /// The name should be prefixed with the dialect name followed by '.'.
-  std::string name;
-
-  /// Dialect in which this attribute is defined.
-  ExtensibleDialect *dialect;
-
-  /// The attribute verifier. It checks that the attribute parameters satisfy
-  /// the invariants.
-  VerifierFn verifier;
-
-  /// The attribute parameters parser. It parses only the parameters, and
-  /// expects the attribute name to have already been parsed.
-  ParserFn parser;
-
-  /// The attribute parameters printer. It prints only the parameters, and
-  /// expects the attribute name to have already been printed.
-  PrinterFn printer;
-
-  /// Context in which the concrete attributes are uniqued.
-  MLIRContext *ctx;
-
-  friend ExtensibleDialect;
-  friend DynamicAttr;
-};
-
-/// This trait is used to determine if an attribute is a dynamic attribute or
-/// not; it should only be implemented by dynamic attributes.
-/// Note: This is only required because dynamic attributes do not have a
-/// static/single TypeID.
-template <typename ConcreteType>
-class IsDynamicAttrTrait
-    : public AttributeTrait::TraitBase<ConcreteType, IsDynamicAttrTrait> {};
-
-/// A dynamic attribute instance. This is an attribute whose definition is
-/// defined at runtime.
-/// It is possible to check if an attribute is a dynamic attribute using
-/// `my_attr.isa<DynamicAttr>()`, and getting the attribute definition of a
-/// dynamic attribute using the `DynamicAttr::getAttrDef` method.
-/// All dynamic attributes have the same storage, which is an array of
-/// attributes.
-
-class DynamicAttr : public Attribute::AttrBase<DynamicAttr, Attribute,
-                                               detail::DynamicAttrStorage,
-                                               IsDynamicAttrTrait> {
-public:
-  // Inherit Base constructors.
-  using Base::Base;
-
-  /// Return an instance of a dynamic attribute given a dynamic attribute
-  /// definition and attribute parameters.
-  /// This asserts that the attribute verifier succeeded.
-  static DynamicAttr get(DynamicAttrDefinition *attrDef,
-                         ArrayRef<Attribute> params = {});
-
-  /// Return an instance of a dynamic attribute given a dynamic attribute
-  /// definition and attribute parameters. If the parameters provided are
-  /// invalid, errors are emitted using the provided location and a null object
-  /// is returned.
-  static DynamicAttr getChecked(function_ref<InFlightDiagnostic()> emitError,
-                                DynamicAttrDefinition *attrDef,
-                                ArrayRef<Attribute> params = {});
-
-  /// Return the attribute definition of the concrete attribute.
-  DynamicAttrDefinition *getAttrDef();
-
-  /// Return the attribute parameters.
-  ArrayRef<Attribute> getParams();
-
-  /// Check if an attribute is a specific dynamic attribute.
-  static bool isa(Attribute attr, DynamicAttrDefinition *attrDef) {
-    return attr.getTypeID() == attrDef->getTypeID();
-  }
-
-  /// Check if an attribute is a dynamic attribute.
-  static bool classof(Attribute attr);
-
-  /// Parse the dynamic attribute parameters and construct the attribute.
-  /// The parameters are either empty, and nothing is parsed,
-  /// or they are in the format '<>' or '<attr (,attr)*>'.
-  static ParseResult parse(AsmParser &parser, DynamicAttrDefinition *attrDef,
-                           DynamicAttr &parsedAttr);
-
-  /// Print the dynamic attribute with the format 'attrname' if there is no
-  /// parameters, or 'attrname<attr (,attr)*>'.
-  void print(AsmPrinter &printer);
-};
-
-//===----------------------------------------------------------------------===//
-// Dynamic type
-//===----------------------------------------------------------------------===//
-
-/// The definition of a dynamic type. A dynamic type is a type that is
-/// defined at runtime, and that can be registered at runtime by an
-/// extensible dialect (a dialect inheriting ExtensibleDialect). This class
-/// stores the parser, the printer, and the verifier of the type. Each dynamic
-/// type definition refers to one instance of this class.
-class DynamicTypeDefinition : SelfOwningTypeID {
-public:
-  using VerifierFn = llvm::unique_function<LogicalResult(
-      function_ref<InFlightDiagnostic()>, ArrayRef<Attribute>) const>;
-  using ParserFn = llvm::unique_function<ParseResult(
-      AsmParser &parser, llvm::SmallVectorImpl<Attribute> &parsedAttributes)
-                                             const>;
-  using PrinterFn = llvm::unique_function<void(
-      AsmPrinter &printer, ArrayRef<Attribute> params) const>;
-
-  /// Create a new dynamic type definition. The type is registered only after
-  /// passing it to the dialect using registerDynamicType.
-  static std::unique_ptr<DynamicTypeDefinition>
-  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier);
-  static std::unique_ptr<DynamicTypeDefinition>
-  get(StringRef name, ExtensibleDialect *dialect, VerifierFn &&verifier,
-      ParserFn &&parser, PrinterFn &&printer);
-
-  /// Check that the type parameters are valid.
-  LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
-                       ArrayRef<Attribute> params) const {
-    return verifier(emitError, params);
-  }
-
-  /// Return the MLIRContext in which the dynamic types is uniqued.
-  MLIRContext &getContext() const { return *ctx; }
-
-  /// Return the name of the type, in the format 'typename' and
-  /// not 'dialectname.typename'.
-  StringRef getName() const { return name; }
-
-  /// Return the dialect defining the type.
-  ExtensibleDialect *getDialect() const { return dialect; }
-
-private:
-  DynamicTypeDefinition(StringRef name, ExtensibleDialect *dialect,
-                        VerifierFn &&verifier, ParserFn &&parser,
-                        PrinterFn &&printer);
-
-  /// This constructor should only be used when we need a pointer to
-  /// the DynamicTypeDefinition in the verifier, the parser, or the printer.
-  /// The verifier, parser, and printer need thus to be initialized after the
-  /// constructor.
-  DynamicTypeDefinition(ExtensibleDialect *dialect, StringRef name);
-
-  /// Register the concrete type in the type Uniquer.
-  void registerInTypeUniquer();
-
-  /// The name should be prefixed with the dialect name followed by '.'.
-  std::string name;
-
-  /// Dialect in which this type is defined.
-  ExtensibleDialect *dialect;
-
-  /// The type verifier. It checks that the type parameters satisfy the
-  /// invariants.
-  VerifierFn verifier;
-
-  /// The type parameters parser. It parses only the parameters, and expects the
-  /// type name to have already been parsed.
-  ParserFn parser;
-
-  /// The type parameters printer. It prints only the parameters, and expects
-  /// the type name to have already been printed.
-  PrinterFn printer;
-
-  /// Context in which the concrete types are uniqued.
-  MLIRContext *ctx;
-
-  friend ExtensibleDialect;
-  friend DynamicType;
-};
-
-/// This trait is used to determine if a type is a dynamic type or not;
-/// it should only be implemented by dynamic types.
-/// Note: This is only required because dynamic type do not have a
-/// static/single TypeID.
-template <typename ConcreteType>
-class IsDynamicTypeTrait
-    : public TypeTrait::TraitBase<ConcreteType, IsDynamicTypeTrait> {};
-
-/// A dynamic type instance. This is a type whose definition is defined at
-/// runtime.
-/// It is possible to check if a type is a dynamic type using
-/// `my_type.isa<DynamicType>()`, and getting the type definition of a dynamic
-/// type using the `DynamicType::getTypeDef` method.
-/// All dynamic types have the same storage, which is an array of attributes.
-class DynamicType
-    : public Type::TypeBase<DynamicType, Type, detail::DynamicTypeStorage,
-                            IsDynamicTypeTrait> {
-public:
-  // Inherit Base constructors.
-  using Base::Base;
-
-  /// Return an instance of a dynamic type given a dynamic type definition and
-  /// type parameters.
-  /// This asserts that the type verifier succeeded.
-  static DynamicType get(DynamicTypeDefinition *typeDef,
-                         ArrayRef<Attribute> params = {});
-
-  /// Return an instance of a dynamic type given a dynamic type definition and
-  /// type parameters. If the parameters provided are invalid, errors are
-  /// emitted using the provided location and a null object is returned.
-  static DynamicType getChecked(function_ref<InFlightDiagnostic()> emitError,
-                                DynamicTypeDefinition *typeDef,
-                                ArrayRef<Attribute> params = {});
-
-  /// Return the type definition of the concrete type.
-  DynamicTypeDefinition *getTypeDef();
-
-  /// Return the type parameters.
-  ArrayRef<Attribute> getParams();
-
-  /// Check if a type is a specific dynamic type.
-  static bool isa(Type type, DynamicTypeDefinition *typeDef) {
-    return type.getTypeID() == typeDef->getTypeID();
-  }
-
-  /// Check if a type is a dynamic type.
-  static bool classof(Type type);
-
-  /// Parse the dynamic type parameters and construct the type.
-  /// The parameters are either empty, and nothing is parsed,
-  /// or they are in the format '<>' or '<attr (,attr)*>'.
-  static ParseResult parse(AsmParser &parser, DynamicTypeDefinition *typeDef,
-                           DynamicType &parsedType);
-
-  /// Print the dynamic type with the format
-  /// 'type' or 'type<>' if there is no parameters, or 'type<attr (,attr)*>'.
-  void print(AsmPrinter &printer);
-};
-
-//===----------------------------------------------------------------------===//
-// Dynamic operation
-//===----------------------------------------------------------------------===//
-
-/// The definition of a dynamic op. A dynamic op is an op that is defined at
-/// runtime, and that can be registered at runtime by an extensible dialect (a
-/// dialect inheriting ExtensibleDialect). This class stores the functions that
-/// are in the OperationName class, and in addition defines the TypeID of the op
-/// that will be defined.
-/// Each dynamic operation definition refers to one instance of this class.
-class DynamicOpDefinition {
-public:
-  /// Create a new op at runtime. The op is registered only after passing it to
-  /// the dialect using registerDynamicOp.
-  static std::unique_ptr<DynamicOpDefinition>
-  get(StringRef name, ExtensibleDialect *dialect,
-      OperationName::VerifyInvariantsFn &&verifyFn,
-      OperationName::VerifyRegionInvariantsFn &&verifyRegionFn);
-  static std::unique_ptr<DynamicOpDefinition>
-  get(StringRef name, ExtensibleDialect *dialect,
-      OperationName::VerifyInvariantsFn &&verifyFn,
-      OperationName::VerifyRegionInvariantsFn &&verifyRegionFn,
-      OperationName::ParseAssemblyFn &&parseFn,
-      OperationName::PrintAssemblyFn &&printFn);
-  static std::unique_ptr<DynamicOpDefinition>
-  get(StringRef name, ExtensibleDialect *dialect,
-      OperationName::VerifyInvariantsFn &&verifyFn,
-      OperationName::VerifyRegionInvariantsFn &&verifyRegionFn,
-      OperationName::ParseAssemblyFn &&parseFn,
-      OperationName::PrintAssemblyFn &&printFn,
-      OperationName::FoldHookFn &&foldHookFn,
-      OperationName::GetCanonicalizationPatternsFn
-          &&getCanonicalizationPatternsFn);
-
-  /// Returns the op typeID.
-  TypeID getTypeID() { return typeID; }
-
-  /// Sets the verifier function for this operation. It should emits an error
-  /// message and returns failure if a problem is detected, or returns success
-  /// if everything is ok.
-  void setVerifyFn(OperationName::VerifyInvariantsFn &&verify) {
-    verifyFn = std::move(verify);
-  }
-
-  /// Sets the region verifier function for this operation. It should emits an
-  /// error message and returns failure if a problem is detected, or returns
-  /// success if everything is ok.
-  void setVerifyRegionFn(OperationName::VerifyRegionInvariantsFn &&verify) {
-    verifyRegionFn = std::move(verify);
-  }
-
-  /// Sets the static hook for parsing this op assembly.
-  void setParseFn(OperationName::ParseAssemblyFn &&parse) {
-    parseFn = std::move(parse);
-  }
-
-  /// Sets the static hook for printing this op assembly.
-  void setPrintFn(OperationName::PrintAssemblyFn &&print) {
-    printFn = std::move(print);
-  }
-
-  /// Sets the hook implementing a generalized folder for the op. See
-  /// `RegisteredOperationName::foldHook` for more details
-  void setFoldHookFn(OperationName::FoldHookFn &&foldHook) {
-    foldHookFn = std::move(foldHook);
-  }
-
-  /// Set the hook returning any canonicalization pattern rewrites that the op
-  /// supports, for use by the canonicalization pass.
-  void
-  setGetCanonicalizationPatternsFn(OperationName::GetCanonicalizationPatternsFn
-                                       &&getCanonicalizationPatterns) {
-    getCanonicalizationPatternsFn = std::move(getCanonicalizationPatterns);
-  }
-
-private:
-  DynamicOpDefinition(StringRef name, ExtensibleDialect *dialect,
-                      OperationName::VerifyInvariantsFn &&verifyFn,
-                      OperationName::VerifyRegionInvariantsFn &&verifyRegionFn,
-                      OperationName::ParseAssemblyFn &&parseFn,
-                      OperationName::PrintAssemblyFn &&printFn,
-                      OperationName::FoldHookFn &&foldHookFn,
-                      OperationName::GetCanonicalizationPatternsFn
-                          &&getCanonicalizationPatternsFn);
-
-  /// Unique identifier for this operation.
-  TypeID typeID;
-
-  /// Name of the operation.
-  /// The name is prefixed with the dialect name.
-  std::string name;
-
-  /// Dialect defining this operation.
-  ExtensibleDialect *dialect;
-
-  OperationName::VerifyInvariantsFn verifyFn;
-  OperationName::VerifyRegionInvariantsFn verifyRegionFn;
-  OperationName::ParseAssemblyFn parseFn;
-  OperationName::PrintAssemblyFn printFn;
-  OperationName::FoldHookFn foldHookFn;
-  OperationName::GetCanonicalizationPatternsFn getCanonicalizationPatternsFn;
-
-  friend ExtensibleDialect;
-};
-
-//===----------------------------------------------------------------------===//
-// Extensible dialect
-//===----------------------------------------------------------------------===//
-
-/// A dialect that can be extended with new operations/types/attributes at
-/// runtime.
-class ExtensibleDialect : public mlir::Dialect {
-public:
-  ExtensibleDialect(StringRef name, MLIRContext *ctx, TypeID typeID);
-
-  /// Add a new type defined at runtime to the dialect.
-  void registerDynamicType(std::unique_ptr<DynamicTypeDefinition> &&type);
-
-  /// Add a new attribute defined at runtime to the dialect.
-  void registerDynamicAttr(std::unique_ptr<DynamicAttrDefinition> &&attr);
-
-  /// Add a new operation defined at runtime to the dialect.
-  void registerDynamicOp(std::unique_ptr<DynamicOpDefinition> &&type);
-
-  /// Check if the dialect is an extensible dialect.
-  static bool classof(const Dialect *dialect);
-
-  /// Returns nullptr if the definition was not found.
-  DynamicTypeDefinition *lookupTypeDefinition(StringRef name) const {
-    auto it = nameToDynTypes.find(name);
-    if (it == nameToDynTypes.end())
-      return nullptr;
-    return it->second;
-  }
-
-  /// Returns nullptr if the definition was not found.
-  DynamicTypeDefinition *lookupTypeDefinition(TypeID id) const {
-    auto it = dynTypes.find(id);
-    if (it == dynTypes.end())
-      return nullptr;
-    return it->second.get();
-  }
-
-  /// Returns nullptr if the definition was not found.
-  DynamicAttrDefinition *lookupAttrDefinition(StringRef name) const {
-    auto it = nameToDynAttrs.find(name);
-    if (it == nameToDynAttrs.end())
-      return nullptr;
-    return it->second;
-  }
-
-  /// Returns nullptr if the definition was not found.
-  DynamicAttrDefinition *lookupAttrDefinition(TypeID id) const {
-    auto it = dynAttrs.find(id);
-    if (it == dynAttrs.end())
-      return nullptr;
-    return it->second.get();
-  }
-
-protected:
-  /// Parse the dynamic type 'typeName' in the dialect 'dialect'.
-  /// typename should not be prefixed with the dialect name.
-  /// If the dynamic type does not exist, return no value.
-  /// Otherwise, parse it, and return the parse result.
-  /// If the parsing succeed, put the resulting type in 'resultType'.
-  OptionalParseResult parseOptionalDynamicType(StringRef typeName,
-                                               AsmParser &parser,
-                                               Type &resultType) const;
-
-  /// If 'type' is a dynamic type, print it.
-  /// Returns success if the type was printed, and failure if the type was not a
-  /// dynamic type.
-  static LogicalResult printIfDynamicType(Type type, AsmPrinter &printer);
-
-  /// Parse the dynamic attribute 'attrName' in the dialect 'dialect'.
-  /// attrname should not be prefixed with the dialect name.
-  /// If the dynamic attribute does not exist, return no value.
-  /// Otherwise, parse it, and return the parse result.
-  /// If the parsing succeed, put the resulting attribute in 'resultAttr'.
-  OptionalParseResult parseOptionalDynamicAttr(StringRef attrName,
-                                               AsmParser &parser,
-                                               Attribute &resultAttr) const;
-
-  /// If 'attr' is a dynamic attribute, print it.
-  /// Returns success if the attribute was printed, and failure if the
-  /// attribute was not a dynamic attribute.
-  static LogicalResult printIfDynamicAttr(Attribute attr, AsmPrinter &printer);
-
-private:
-  /// The set of all dynamic types registered.
-  DenseMap<TypeID, std::unique_ptr<DynamicTypeDefinition>> dynTypes;
-
-  /// This structure allows to get in O(1) a dynamic type given its name.
-  llvm::StringMap<DynamicTypeDefinition *> nameToDynTypes;
-
-  /// The set of all dynamic attributes registered.
-  DenseMap<TypeID, std::unique_ptr<DynamicAttrDefinition>> dynAttrs;
-
-  /// This structure allows to get in O(1) a dynamic attribute given its name.
-  llvm::StringMap<DynamicAttrDefinition *> nameToDynAttrs;
-
-  /// Give DynamicOpDefinition access to allocateTypeID.
-  friend DynamicOpDefinition;
-
-  /// Allocates a type ID to uniquify operations.
-  TypeID allocateTypeID() { return typeIDAllocator.allocate(); }
-
-  /// Owns the TypeID generated at runtime for operations.
-  TypeIDAllocator typeIDAllocator;
-};
-} // namespace mlir
-
-#endif // MLIR_IR_EXTENSIBLEDIALECT_H

diff  --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td
index 1e4963ab1a219..11bc1a639794a 100644
--- a/mlir/include/mlir/IR/OpBase.td
+++ b/mlir/include/mlir/IR/OpBase.td
@@ -333,9 +333,6 @@ class Dialect {
   // UpperCamel) and prefixed with `get` or `set` depending on if it is a getter
   // or setter.
   int emitAccessorPrefix = kEmitAccessorPrefix_Raw;
-
-  // If this dialect can be extended at runtime with new operations or types.
-  bit isExtensible = 0;
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/include/mlir/IR/TypeSupport.h b/mlir/include/mlir/IR/TypeSupport.h
index 37bf3fa123668..6f9327003ad86 100644
--- a/mlir/include/mlir/IR/TypeSupport.h
+++ b/mlir/include/mlir/IR/TypeSupport.h
@@ -163,22 +163,13 @@ namespace detail {
 /// A utility class to get, or create, unique instances of types within an
 /// MLIRContext. This class manages all creation and uniquing of types.
 struct TypeUniquer {
-  /// Get an uniqued instance of a type T.
-  template <typename T, typename... Args>
-  static T get(MLIRContext *ctx, Args &&... args) {
-    return getWithTypeID<T, Args...>(ctx, T::getTypeID(),
-                                     std::forward<Args>(args)...);
-  }
-
   /// Get an uniqued instance of a parametric type T.
-  /// The use of this method is in general discouraged in favor of
-  /// 'get<T, Args>(ctx, args)'.
   template <typename T, typename... Args>
   static typename std::enable_if_t<
       !std::is_same<typename T::ImplType, TypeStorage>::value, T>
-  getWithTypeID(MLIRContext *ctx, TypeID typeID, Args &&... args) {
+  get(MLIRContext *ctx, Args &&...args) {
 #ifndef NDEBUG
-    if (!ctx->getTypeUniquer().isParametricStorageInitialized(typeID))
+    if (!ctx->getTypeUniquer().isParametricStorageInitialized(T::getTypeID()))
       llvm::report_fatal_error(
           llvm::Twine("can't create type '") + llvm::getTypeName<T>() +
           "' because storage uniquer isn't initialized: the dialect was likely "
@@ -186,27 +177,25 @@ struct TypeUniquer {
           "in the Dialect::initialize() method.");
 #endif
     return ctx->getTypeUniquer().get<typename T::ImplType>(
-        [&, typeID](TypeStorage *storage) {
-          storage->initialize(AbstractType::lookup(typeID, ctx));
+        [&](TypeStorage *storage) {
+          storage->initialize(AbstractType::lookup(T::getTypeID(), ctx));
         },
-        typeID, std::forward<Args>(args)...);
+        T::getTypeID(), std::forward<Args>(args)...);
   }
   /// Get an uniqued instance of a singleton type T.
-  /// The use of this method is in general discouraged in favor of
-  /// 'get<T, Args>(ctx, args)'.
   template <typename T>
   static typename std::enable_if_t<
       std::is_same<typename T::ImplType, TypeStorage>::value, T>
-  getWithTypeID(MLIRContext *ctx, TypeID typeID) {
+  get(MLIRContext *ctx) {
 #ifndef NDEBUG
-    if (!ctx->getTypeUniquer().isSingletonStorageInitialized(typeID))
+    if (!ctx->getTypeUniquer().isSingletonStorageInitialized(T::getTypeID()))
       llvm::report_fatal_error(
           llvm::Twine("can't create type '") + llvm::getTypeName<T>() +
           "' because storage uniquer isn't initialized: the dialect was likely "
           "not loaded, or the type wasn't added with addTypes<...>() "
           "in the Dialect::initialize() method.");
 #endif
-    return ctx->getTypeUniquer().get<typename T::ImplType>(typeID);
+    return ctx->getTypeUniquer().get<typename T::ImplType>(T::getTypeID());
   }
 
   /// Change the mutable component of the given type instance in the provided
@@ -219,32 +208,22 @@ struct TypeUniquer {
                                         std::forward<Args>(args)...);
   }
 
-  /// Register a type instance T with the uniquer.
-  template <typename T>
-  static void registerType(MLIRContext *ctx) {
-    registerType<T>(ctx, T::getTypeID());
-  }
-
   /// Register a parametric type instance T with the uniquer.
-  /// The use of this method is in general discouraged in favor of
-  /// 'registerType<T>(ctx)'.
   template <typename T>
   static typename std::enable_if_t<
       !std::is_same<typename T::ImplType, TypeStorage>::value>
-  registerType(MLIRContext *ctx, TypeID typeID) {
+  registerType(MLIRContext *ctx) {
     ctx->getTypeUniquer().registerParametricStorageType<typename T::ImplType>(
-        typeID);
+        T::getTypeID());
   }
   /// Register a singleton type instance T with the uniquer.
-  /// The use of this method is in general discouraged in favor of
-  /// 'registerType<T>(ctx)'.
   template <typename T>
   static typename std::enable_if_t<
       std::is_same<typename T::ImplType, TypeStorage>::value>
-  registerType(MLIRContext *ctx, TypeID typeID) {
+  registerType(MLIRContext *ctx) {
     ctx->getTypeUniquer().registerSingletonStorageType<TypeStorage>(
-        typeID, [&ctx, typeID](TypeStorage *storage) {
-          storage->initialize(AbstractType::lookup(typeID, ctx));
+        T::getTypeID(), [&](TypeStorage *storage) {
+          storage->initialize(AbstractType::lookup(T::getTypeID(), ctx));
         });
   }
 };

diff  --git a/mlir/include/mlir/TableGen/Dialect.h b/mlir/include/mlir/TableGen/Dialect.h
index 297d2df988335..3a378898bf50d 100644
--- a/mlir/include/mlir/TableGen/Dialect.h
+++ b/mlir/include/mlir/TableGen/Dialect.h
@@ -82,10 +82,6 @@ class Dialect {
   /// type printing/parsing.
   bool useDefaultTypePrinterParser() const;
 
-  /// Returns true if this dialect can be extended at runtime with new
-  /// operations or types.
-  bool isExtensible() const;
-
   // Returns whether two dialects are equal by checking the equality of the
   // underlying record.
   bool operator==(const Dialect &other) const;

diff  --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt
index 699ef7e2362e8..899194f78ceda 100644
--- a/mlir/lib/IR/CMakeLists.txt
+++ b/mlir/lib/IR/CMakeLists.txt
@@ -13,7 +13,6 @@ add_mlir_library(MLIRIR
   Diagnostics.cpp
   Dialect.cpp
   Dominance.cpp
-  ExtensibleDialect.cpp
   FunctionImplementation.cpp
   FunctionInterfaces.cpp
   IntegerSet.cpp

diff  --git a/mlir/lib/IR/ExtensibleDialect.cpp b/mlir/lib/IR/ExtensibleDialect.cpp
deleted file mode 100644
index d5d46dfde5e92..0000000000000
--- a/mlir/lib/IR/ExtensibleDialect.cpp
+++ /dev/null
@@ -1,513 +0,0 @@
-//===- ExtensibleDialect.cpp - Extensible dialect ---------------*- C++ -*-===//
-//
-// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "mlir/IR/ExtensibleDialect.h"
-#include "mlir/IR/AttributeSupport.h"
-#include "mlir/IR/DialectImplementation.h"
-#include "mlir/IR/OperationSupport.h"
-#include "mlir/IR/StorageUniquerSupport.h"
-#include "mlir/Support/LogicalResult.h"
-
-using namespace mlir;
-
-//===----------------------------------------------------------------------===//
-// Dynamic types and attributes shared functions
-//===----------------------------------------------------------------------===//
-
-/// Default parser for dynamic attribute or type parameters.
-/// Parse in the format '(<>)?' or '<attr (,attr)*>'.
-static LogicalResult
-typeOrAttrParser(AsmParser &parser, SmallVectorImpl<Attribute> &parsedParams) {
-  // No parameters
-  if (parser.parseOptionalLess() || !parser.parseOptionalGreater())
-    return success();
-
-  Attribute attr;
-  if (parser.parseAttribute(attr))
-    return failure();
-  parsedParams.push_back(attr);
-
-  while (parser.parseOptionalGreater()) {
-    Attribute attr;
-    if (parser.parseComma() || parser.parseAttribute(attr))
-      return failure();
-    parsedParams.push_back(attr);
-  }
-
-  return success();
-}
-
-/// Default printer for dynamic attribute or type parameters.
-/// Print in the format '(<>)?' or '<attr (,attr)*>'.
-static void typeOrAttrPrinter(AsmPrinter &printer, ArrayRef<Attribute> params) {
-  if (params.empty())
-    return;
-
-  printer << "<";
-  interleaveComma(params, printer.getStream());
-  printer << ">";
-}
-
-//===----------------------------------------------------------------------===//
-// Dynamic type
-//===----------------------------------------------------------------------===//
-
-std::unique_ptr<DynamicTypeDefinition>
-DynamicTypeDefinition::get(StringRef name, ExtensibleDialect *dialect,
-                           VerifierFn &&verifier) {
-  return DynamicTypeDefinition::get(name, dialect, std::move(verifier),
-                                    typeOrAttrParser, typeOrAttrPrinter);
-}
-
-std::unique_ptr<DynamicTypeDefinition>
-DynamicTypeDefinition::get(StringRef name, ExtensibleDialect *dialect,
-                           VerifierFn &&verifier, ParserFn &&parser,
-                           PrinterFn &&printer) {
-  return std::unique_ptr<DynamicTypeDefinition>(
-      new DynamicTypeDefinition(name, dialect, std::move(verifier),
-                                std::move(parser), std::move(printer)));
-}
-
-DynamicTypeDefinition::DynamicTypeDefinition(StringRef nameRef,
-                                             ExtensibleDialect *dialect,
-                                             VerifierFn &&verifier,
-                                             ParserFn &&parser,
-                                             PrinterFn &&printer)
-    : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
-      parser(std::move(parser)), printer(std::move(printer)),
-      ctx(dialect->getContext()) {
-  assert(!nameRef.contains('.') &&
-         "name should not be prefixed by the dialect name");
-}
-
-DynamicTypeDefinition::DynamicTypeDefinition(ExtensibleDialect *dialect,
-                                             StringRef nameRef)
-    : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {
-  assert(!nameRef.contains('.') &&
-         "name should not be prefixed by the dialect name");
-}
-
-void DynamicTypeDefinition::registerInTypeUniquer() {
-  detail::TypeUniquer::registerType<DynamicType>(&getContext(), getTypeID());
-}
-
-namespace mlir {
-namespace detail {
-/// Storage of DynamicType.
-/// Contains a pointer to the type definition and type parameters.
-struct DynamicTypeStorage : public TypeStorage {
-
-  using KeyTy = std::pair<DynamicTypeDefinition *, ArrayRef<Attribute>>;
-
-  explicit DynamicTypeStorage(DynamicTypeDefinition *typeDef,
-                              ArrayRef<Attribute> params)
-      : typeDef(typeDef), params(params) {}
-
-  bool operator==(const KeyTy &key) const {
-    return typeDef == key.first && params == key.second;
-  }
-
-  static llvm::hash_code hashKey(const KeyTy &key) {
-    return llvm::hash_value(key);
-  }
-
-  static DynamicTypeStorage *construct(TypeStorageAllocator &alloc,
-                                       const KeyTy &key) {
-    return new (alloc.allocate<DynamicTypeStorage>())
-        DynamicTypeStorage(key.first, alloc.copyInto(key.second));
-  }
-
-  /// Definition of the type.
-  DynamicTypeDefinition *typeDef;
-
-  /// The type parameters.
-  ArrayRef<Attribute> params;
-};
-} // namespace detail
-} // namespace mlir
-
-DynamicType DynamicType::get(DynamicTypeDefinition *typeDef,
-                             ArrayRef<Attribute> params) {
-  auto &ctx = typeDef->getContext();
-  auto emitError = detail::getDefaultDiagnosticEmitFn(&ctx);
-  assert(succeeded(typeDef->verify(emitError, params)));
-  return detail::TypeUniquer::getWithTypeID<DynamicType>(
-      &ctx, typeDef->getTypeID(), typeDef, params);
-}
-
-DynamicType
-DynamicType::getChecked(function_ref<InFlightDiagnostic()> emitError,
-                        DynamicTypeDefinition *typeDef,
-                        ArrayRef<Attribute> params) {
-  if (failed(typeDef->verify(emitError, params)))
-    return {};
-  auto &ctx = typeDef->getContext();
-  return detail::TypeUniquer::getWithTypeID<DynamicType>(
-      &ctx, typeDef->getTypeID(), typeDef, params);
-}
-
-DynamicTypeDefinition *DynamicType::getTypeDef() { return getImpl()->typeDef; }
-
-ArrayRef<Attribute> DynamicType::getParams() { return getImpl()->params; }
-
-bool DynamicType::classof(Type type) {
-  return type.hasTrait<IsDynamicTypeTrait>();
-}
-
-ParseResult DynamicType::parse(AsmParser &parser,
-                               DynamicTypeDefinition *typeDef,
-                               DynamicType &parsedType) {
-  SmallVector<Attribute> params;
-  if (failed(typeDef->parser(parser, params)))
-    return failure();
-  parsedType = parser.getChecked<DynamicType>(typeDef, params);
-  if (!parsedType)
-    return failure();
-  return success();
-}
-
-void DynamicType::print(AsmPrinter &printer) {
-  printer << getTypeDef()->getName();
-  getTypeDef()->printer(printer, getParams());
-}
-
-//===----------------------------------------------------------------------===//
-// Dynamic attribute
-//===----------------------------------------------------------------------===//
-
-std::unique_ptr<DynamicAttrDefinition>
-DynamicAttrDefinition::get(StringRef name, ExtensibleDialect *dialect,
-                           VerifierFn &&verifier) {
-  return DynamicAttrDefinition::get(name, dialect, std::move(verifier),
-                                    typeOrAttrParser, typeOrAttrPrinter);
-}
-
-std::unique_ptr<DynamicAttrDefinition>
-DynamicAttrDefinition::get(StringRef name, ExtensibleDialect *dialect,
-                           VerifierFn &&verifier, ParserFn &&parser,
-                           PrinterFn &&printer) {
-  return std::unique_ptr<DynamicAttrDefinition>(
-      new DynamicAttrDefinition(name, dialect, std::move(verifier),
-                                std::move(parser), std::move(printer)));
-}
-
-DynamicAttrDefinition::DynamicAttrDefinition(StringRef nameRef,
-                                             ExtensibleDialect *dialect,
-                                             VerifierFn &&verifier,
-                                             ParserFn &&parser,
-                                             PrinterFn &&printer)
-    : name(nameRef), dialect(dialect), verifier(std::move(verifier)),
-      parser(std::move(parser)), printer(std::move(printer)),
-      ctx(dialect->getContext()) {
-  assert(!nameRef.contains('.') &&
-         "name should not be prefixed by the dialect name");
-}
-
-DynamicAttrDefinition::DynamicAttrDefinition(ExtensibleDialect *dialect,
-                                             StringRef nameRef)
-    : name(nameRef), dialect(dialect), ctx(dialect->getContext()) {
-  assert(!nameRef.contains('.') &&
-         "name should not be prefixed by the dialect name");
-}
-
-void DynamicAttrDefinition::registerInAttrUniquer() {
-  detail::AttributeUniquer::registerAttribute<DynamicAttr>(&getContext(),
-                                                           getTypeID());
-}
-
-namespace mlir {
-namespace detail {
-/// Storage of DynamicAttr.
-/// Contains a pointer to the attribute definition and attribute parameters.
-struct DynamicAttrStorage : public AttributeStorage {
-  using KeyTy = std::pair<DynamicAttrDefinition *, ArrayRef<Attribute>>;
-
-  explicit DynamicAttrStorage(DynamicAttrDefinition *attrDef,
-                              ArrayRef<Attribute> params)
-      : attrDef(attrDef), params(params) {}
-
-  bool operator==(const KeyTy &key) const {
-    return attrDef == key.first && params == key.second;
-  }
-
-  static llvm::hash_code hashKey(const KeyTy &key) {
-    return llvm::hash_value(key);
-  }
-
-  static DynamicAttrStorage *construct(AttributeStorageAllocator &alloc,
-                                       const KeyTy &key) {
-    return new (alloc.allocate<DynamicAttrStorage>())
-        DynamicAttrStorage(key.first, alloc.copyInto(key.second));
-  }
-
-  /// Definition of the type.
-  DynamicAttrDefinition *attrDef;
-
-  /// The type parameters.
-  ArrayRef<Attribute> params;
-};
-} // namespace detail
-} // namespace mlir
-
-DynamicAttr DynamicAttr::get(DynamicAttrDefinition *attrDef,
-                             ArrayRef<Attribute> params) {
-  auto &ctx = attrDef->getContext();
-  return detail::AttributeUniquer::getWithTypeID<DynamicAttr>(
-      &ctx, attrDef->getTypeID(), attrDef, params);
-}
-
-DynamicAttr
-DynamicAttr::getChecked(function_ref<InFlightDiagnostic()> emitError,
-                        DynamicAttrDefinition *attrDef,
-                        ArrayRef<Attribute> params) {
-  if (failed(attrDef->verify(emitError, params)))
-    return {};
-  return get(attrDef, params);
-}
-
-DynamicAttrDefinition *DynamicAttr::getAttrDef() { return getImpl()->attrDef; }
-
-ArrayRef<Attribute> DynamicAttr::getParams() { return getImpl()->params; }
-
-bool DynamicAttr::classof(Attribute attr) {
-  return attr.hasTrait<IsDynamicAttrTrait>();
-}
-
-ParseResult DynamicAttr::parse(AsmParser &parser,
-                               DynamicAttrDefinition *attrDef,
-                               DynamicAttr &parsedAttr) {
-  SmallVector<Attribute> params;
-  if (failed(attrDef->parser(parser, params)))
-    return failure();
-  parsedAttr = parser.getChecked<DynamicAttr>(attrDef, params);
-  if (!parsedAttr)
-    return failure();
-  return success();
-}
-
-void DynamicAttr::print(AsmPrinter &printer) {
-  printer << getAttrDef()->getName();
-  getAttrDef()->printer(printer, getParams());
-}
-
-//===----------------------------------------------------------------------===//
-// Dynamic operation
-//===----------------------------------------------------------------------===//
-
-DynamicOpDefinition::DynamicOpDefinition(
-    StringRef name, ExtensibleDialect *dialect,
-    OperationName::VerifyInvariantsFn &&verifyFn,
-    OperationName::VerifyRegionInvariantsFn &&verifyRegionFn,
-    OperationName::ParseAssemblyFn &&parseFn,
-    OperationName::PrintAssemblyFn &&printFn,
-    OperationName::FoldHookFn &&foldHookFn,
-    OperationName::GetCanonicalizationPatternsFn
-        &&getCanonicalizationPatternsFn)
-    : typeID(dialect->allocateTypeID()),
-      name((dialect->getNamespace() + "." + name).str()), dialect(dialect),
-      verifyFn(std::move(verifyFn)), verifyRegionFn(std::move(verifyRegionFn)),
-      parseFn(std::move(parseFn)), printFn(std::move(printFn)),
-      foldHookFn(std::move(foldHookFn)),
-      getCanonicalizationPatternsFn(std::move(getCanonicalizationPatternsFn)) {
-  assert(!name.contains('.') &&
-         "name should not be prefixed by the dialect name");
-}
-
-std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
-    StringRef name, ExtensibleDialect *dialect,
-    OperationName::VerifyInvariantsFn &&verifyFn,
-    OperationName::VerifyRegionInvariantsFn &&verifyRegionFn) {
-  auto parseFn = [](OpAsmParser &parser, OperationState &result) {
-    return parser.emitError(
-        parser.getCurrentLocation(),
-        "dynamic operation do not define any parser function");
-  };
-
-  auto printFn = [](Operation *op, OpAsmPrinter &printer, StringRef) {
-    printer.printGenericOp(op);
-  };
-
-  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
-                                  std::move(verifyRegionFn), std::move(parseFn),
-                                  std::move(printFn));
-}
-
-std::unique_ptr<DynamicOpDefinition> DynamicOpDefinition::get(
-    StringRef name, ExtensibleDialect *dialect,
-    OperationName::VerifyInvariantsFn &&verifyFn,
-    OperationName::VerifyRegionInvariantsFn &&verifyRegionFn,
-    OperationName::ParseAssemblyFn &&parseFn,
-    OperationName::PrintAssemblyFn &&printFn) {
-  auto foldHookFn = [](Operation *op, ArrayRef<Attribute> operands,
-                       SmallVectorImpl<OpFoldResult> &results) {
-    return failure();
-  };
-
-  auto getCanonicalizationPatternsFn = [](RewritePatternSet &, MLIRContext *) {
-  };
-
-  return DynamicOpDefinition::get(name, dialect, std::move(verifyFn),
-                                  std::move(verifyRegionFn), std::move(parseFn),
-                                  std::move(printFn), std::move(foldHookFn),
-                                  std::move(getCanonicalizationPatternsFn));
-}
-
-std::unique_ptr<DynamicOpDefinition>
-DynamicOpDefinition::get(StringRef name, ExtensibleDialect *dialect,
-                         OperationName::VerifyInvariantsFn &&verifyFn,
-                         OperationName::VerifyInvariantsFn &&verifyRegionFn,
-                         OperationName::ParseAssemblyFn &&parseFn,
-                         OperationName::PrintAssemblyFn &&printFn,
-                         OperationName::FoldHookFn &&foldHookFn,
-                         OperationName::GetCanonicalizationPatternsFn
-                             &&getCanonicalizationPatternsFn) {
-  return std::unique_ptr<DynamicOpDefinition>(new DynamicOpDefinition(
-      name, dialect, std::move(verifyFn), std::move(verifyRegionFn),
-      std::move(parseFn), std::move(printFn), std::move(foldHookFn),
-      std::move(getCanonicalizationPatternsFn)));
-}
-
-//===----------------------------------------------------------------------===//
-// Extensible dialect
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// Interface that can only be implemented by extensible dialects.
-/// The interface is used to check if a dialect is extensible or not.
-class IsExtensibleDialect : public DialectInterface::Base<IsExtensibleDialect> {
-public:
-  IsExtensibleDialect(Dialect *dialect) : Base(dialect) {}
-};
-} // namespace
-
-ExtensibleDialect::ExtensibleDialect(StringRef name, MLIRContext *ctx,
-                                     TypeID typeID)
-    : Dialect(name, ctx, typeID) {
-  addInterfaces<IsExtensibleDialect>();
-}
-
-void ExtensibleDialect::registerDynamicType(
-    std::unique_ptr<DynamicTypeDefinition> &&type) {
-  DynamicTypeDefinition *typePtr = type.get();
-  TypeID typeID = type->getTypeID();
-  StringRef name = type->getName();
-  ExtensibleDialect *dialect = type->getDialect();
-
-  assert(dialect == this &&
-         "trying to register a dynamic type in the wrong dialect");
-
-  // If a type with the same name is already defined, fail.
-  auto registered = dynTypes.try_emplace(typeID, std::move(type)).second;
-  (void)registered;
-  assert(registered && "type TypeID was not unique");
-
-  registered = nameToDynTypes.insert({name, typePtr}).second;
-  (void)registered;
-  assert(registered &&
-         "Trying to create a new dynamic type with an existing name");
-
-  auto abstractType =
-      AbstractType::get(*dialect, DynamicAttr::getInterfaceMap(),
-                        DynamicType::getHasTraitFn(), typeID);
-
-  /// Add the type to the dialect and the type uniquer.
-  addType(typeID, std::move(abstractType));
-  typePtr->registerInTypeUniquer();
-}
-
-void ExtensibleDialect::registerDynamicAttr(
-    std::unique_ptr<DynamicAttrDefinition> &&attr) {
-  auto *attrPtr = attr.get();
-  auto typeID = attr->getTypeID();
-  auto name = attr->getName();
-  auto *dialect = attr->getDialect();
-
-  assert(dialect == this &&
-         "trying to register a dynamic attribute in the wrong dialect");
-
-  // If an attribute with the same name is already defined, fail.
-  auto registered = dynAttrs.try_emplace(typeID, std::move(attr)).second;
-  (void)registered;
-  assert(registered && "attribute TypeID was not unique");
-
-  registered = nameToDynAttrs.insert({name, attrPtr}).second;
-  (void)registered;
-  assert(registered &&
-         "Trying to create a new dynamic attribute with an existing name");
-
-  auto abstractAttr =
-      AbstractAttribute::get(*dialect, DynamicAttr::getInterfaceMap(),
-                             DynamicAttr::getHasTraitFn(), typeID);
-
-  /// Add the type to the dialect and the type uniquer.
-  addAttribute(typeID, std::move(abstractAttr));
-  attrPtr->registerInAttrUniquer();
-}
-
-void ExtensibleDialect::registerDynamicOp(
-    std::unique_ptr<DynamicOpDefinition> &&op) {
-  assert(op->dialect == this &&
-         "trying to register a dynamic op in the wrong dialect");
-  auto hasTraitFn = [](TypeID traitId) { return false; };
-
-  RegisteredOperationName::insert(
-      op->name, *op->dialect, op->typeID, std::move(op->parseFn),
-      std::move(op->printFn), std::move(op->verifyFn),
-      std::move(op->verifyRegionFn), std::move(op->foldHookFn),
-      std::move(op->getCanonicalizationPatternsFn),
-      detail::InterfaceMap::get<>(), std::move(hasTraitFn), {});
-}
-
-bool ExtensibleDialect::classof(const Dialect *dialect) {
-  return const_cast<Dialect *>(dialect)
-      ->getRegisteredInterface<IsExtensibleDialect>();
-}
-
-OptionalParseResult ExtensibleDialect::parseOptionalDynamicType(
-    StringRef typeName, AsmParser &parser, Type &resultType) const {
-  DynamicTypeDefinition *typeDef = lookupTypeDefinition(typeName);
-  if (!typeDef)
-    return llvm::None;
-
-  DynamicType dynType;
-  if (DynamicType::parse(parser, typeDef, dynType))
-    return failure();
-  resultType = dynType;
-  return success();
-}
-
-LogicalResult ExtensibleDialect::printIfDynamicType(Type type,
-                                                    AsmPrinter &printer) {
-  if (auto dynType = type.dyn_cast<DynamicType>()) {
-    dynType.print(printer);
-    return success();
-  }
-  return failure();
-}
-
-OptionalParseResult ExtensibleDialect::parseOptionalDynamicAttr(
-    StringRef attrName, AsmParser &parser, Attribute &resultAttr) const {
-  DynamicAttrDefinition *attrDef = lookupAttrDefinition(attrName);
-  if (!attrDef)
-    return llvm::None;
-
-  DynamicAttr dynAttr;
-  if (DynamicAttr::parse(parser, attrDef, dynAttr))
-    return failure();
-  resultAttr = dynAttr;
-  return success();
-}
-
-LogicalResult ExtensibleDialect::printIfDynamicAttr(Attribute attribute,
-                                                    AsmPrinter &printer) {
-  if (auto dynAttr = attribute.dyn_cast<DynamicAttr>()) {
-    dynAttr.print(printer);
-    return success();
-  }
-  return failure();
-}

diff  --git a/mlir/lib/TableGen/Dialect.cpp b/mlir/lib/TableGen/Dialect.cpp
index 11f972ec7a4a7..57586dd64d07e 100644
--- a/mlir/lib/TableGen/Dialect.cpp
+++ b/mlir/lib/TableGen/Dialect.cpp
@@ -102,14 +102,9 @@ Dialect::EmitPrefix Dialect::getEmitAccessorPrefix() const {
   int prefix = def->getValueAsInt("emitAccessorPrefix");
   if (prefix < 0 || prefix > static_cast<int>(EmitPrefix::Both))
     PrintFatalError(def->getLoc(), "Invalid accessor prefix value");
-
   return static_cast<EmitPrefix>(prefix);
 }
 
-bool Dialect::isExtensible() const {
-  return def->getValueAsBit("isExtensible");
-}
-
 bool Dialect::operator==(const Dialect &other) const {
   return def == other.def;
 }

diff  --git a/mlir/test/IR/dynamic.mlir b/mlir/test/IR/dynamic.mlir
deleted file mode 100644
index 1dfe4d99035ee..0000000000000
--- a/mlir/test/IR/dynamic.mlir
+++ /dev/null
@@ -1,126 +0,0 @@
-// RUN: mlir-opt -allow-unregistered-dialect %s -split-input-file -verify-diagnostics | FileCheck %s
-// Verify that extensible dialects can register dynamic operations and types.
-
-//===----------------------------------------------------------------------===//
-// Dynamic type
-//===----------------------------------------------------------------------===//
-
-// CHECK-LABEL: func @succeededDynamicTypeVerifier
-func @succeededDynamicTypeVerifier() {
-  // CHECK: %{{.*}} = "unregistered_op"() : () -> !test.singleton_dyntype
-  "unregistered_op"() : () -> !test.singleton_dyntype
-  // CHECK-NEXT: "unregistered_op"() : () -> !test.pair_dyntype<i32, f64>
-  "unregistered_op"() : () -> !test.pair_dyntype<i32, f64>
-  // CHECK_NEXT: %{{.*}} = "unregistered_op"() : () -> !test.pair_dyntype<!test.pair_dyntype<i32, f64>, !test.singleton_dyntype>
-  "unregistered_op"() : () -> !test.pair_dyntype<!test.pair_dyntype<i32, f64>, !test.singleton_dyntype>
-  return
-}
-
-// -----
-
-func @failedDynamicTypeVerifier() {
-  // expected-error at +1 {{expected 0 type arguments, but had 1}}
-  "unregistered_op"() : () -> !test.singleton_dyntype<f64>
-  return
-}
-
-// -----
-
-func @failedDynamicTypeVerifier2() {
-  // expected-error at +1 {{expected 2 type arguments, but had 1}}
-  "unregistered_op"() : () -> !test.pair_dyntype<f64>
-  return
-}
-
-// -----
-
-// CHECK-LABEL: func @customTypeParserPrinter
-func @customTypeParserPrinter() {
-  // CHECK: "unregistered_op"() : () -> !test.custom_assembly_format_dyntype<f32:f64>
-  "unregistered_op"() : () -> !test.custom_assembly_format_dyntype<f32 : f64>
-  return
-}
-
-// -----
-
-//===----------------------------------------------------------------------===//
-// Dynamic attribute
-//===----------------------------------------------------------------------===//
-
-// CHECK-LABEL: func @succeededDynamicAttributeVerifier
-func @succeededDynamicAttributeVerifier() {
-  // CHECK: "unregistered_op"() {test_attr = #test.singleton_dynattr} : () -> ()
-  "unregistered_op"() {test_attr = #test.singleton_dynattr} : () -> ()
-  // CHECK-NEXT: "unregistered_op"() {test_attr = #test.pair_dynattr<3 : i32, 5 : i32>} : () -> ()
-  "unregistered_op"() {test_attr = #test.pair_dynattr<3 : i32, 5 : i32>} : () -> ()
-  // CHECK_NEXT: "unregistered_op"() {test_attr = #test.pair_dynattr<3 : i32, 5 : i32>} : () -> ()
-  "unregistered_op"() {test_attr = #test.pair_dynattr<#test.pair_dynattr<3 : i32, 5 : i32>, f64>} : () -> ()
-  return
-}
-
-// -----
-
-func @failedDynamicAttributeVerifier() {
-  // expected-error at +1 {{expected 0 attribute arguments, but had 1}}
-  "unregistered_op"() {test_attr = #test.singleton_dynattr<f64>} : () -> ()
-  return
-}
-
-// -----
-
-func @failedDynamicAttributeVerifier2() {
-  // expected-error at +1 {{expected 2 attribute arguments, but had 1}}
-  "unregistered_op"() {test_attr = #test.pair_dynattr<f64> : () -> ()
-  return
-}
-
-// -----
-
-// CHECK-LABEL: func @customAttributeParserPrinter
-func @customAttributeParserPrinter() {
-  // CHECK: "unregistered_op"() {test_attr = #test.custom_assembly_format_dynattr<f32:f64>} : () -> ()
-  "unregistered_op"() {test_attr = #test.custom_assembly_format_dynattr<f32:f64>} : () -> ()
-  return
-}
-
-//===----------------------------------------------------------------------===//
-// Dynamic op
-//===----------------------------------------------------------------------===//
-
-// -----
-
-// CHECK-LABEL: func @succeededDynamicOpVerifier
-func @succeededDynamicOpVerifier(%a: f32) {
-  // CHECK: "test.generic_dynamic_op"() : () -> ()
-  // CHECK-NEXT: %{{.*}} = "test.generic_dynamic_op"(%{{.*}}) : (f32) -> f64
-  // CHECK-NEXT: %{{.*}}:2 = "test.one_operand_two_results"(%{{.*}}) : (f32) -> (f64, f64)
-  "test.generic_dynamic_op"() : () -> ()
-  "test.generic_dynamic_op"(%a) : (f32) -> f64
-  "test.one_operand_two_results"(%a) : (f32) -> (f64, f64)
-  return
-}
-
-// -----
-
-func @failedDynamicOpVerifier() {
-  // expected-error at +1 {{expected 1 operand, but had 0}}
-  "test.one_operand_two_results"() : () -> (f64, f64)
-  return
-}
-
-// -----
-
-func @failedDynamicOpVerifier2(%a: f32) {
-  // expected-error at +1 {{expected 2 results, but had 0}}
-  "test.one_operand_two_results"(%a) : (f32) -> ()
-  return
-}
-
-// -----
-
-// CHECK-LABEL: func @customOpParserPrinter
-func @customOpParserPrinter() {
-  // CHECK: test.custom_parser_printer_dynamic_op custom_keyword
-  test.custom_parser_printer_dynamic_op custom_keyword
-  return
-}

diff  --git a/mlir/test/lib/Dialect/Test/TestAttributes.cpp b/mlir/test/lib/Dialect/Test/TestAttributes.cpp
index 87460e76a29af..3a860994f0e84 100644
--- a/mlir/test/lib/Dialect/Test/TestAttributes.cpp
+++ b/mlir/test/lib/Dialect/Test/TestAttributes.cpp
@@ -15,14 +15,12 @@
 #include "TestDialect.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/DialectImplementation.h"
-#include "mlir/IR/ExtensibleDialect.h"
 #include "mlir/IR/Types.h"
 #include "mlir/Support/LogicalResult.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/TypeSwitch.h"
 #include "llvm/ADT/bit.h"
-#include "llvm/Support/ErrorHandling.h"
 
 using namespace mlir;
 using namespace test;
@@ -218,74 +216,6 @@ SubElementAttrInterface TestSubElementsAccessAttr::replaceImmediateSubAttribute(
 #define GET_ATTRDEF_CLASSES
 #include "TestAttrDefs.cpp.inc"
 
-//===----------------------------------------------------------------------===//
-// Dynamic Attributes
-//===----------------------------------------------------------------------===//
-
-/// Define a singleton dynamic attribute.
-static std::unique_ptr<DynamicAttrDefinition>
-getSingletonDynamicAttr(TestDialect *testDialect) {
-  return DynamicAttrDefinition::get(
-      "singleton_dynattr", testDialect,
-      [](function_ref<InFlightDiagnostic()> emitError,
-         ArrayRef<Attribute> args) {
-        if (!args.empty()) {
-          emitError() << "expected 0 attribute arguments, but had "
-                      << args.size();
-          return failure();
-        }
-        return success();
-      });
-}
-
-/// Define a dynamic attribute representing a pair or attributes.
-static std::unique_ptr<DynamicAttrDefinition>
-getPairDynamicAttr(TestDialect *testDialect) {
-  return DynamicAttrDefinition::get(
-      "pair_dynattr", testDialect,
-      [](function_ref<InFlightDiagnostic()> emitError,
-         ArrayRef<Attribute> args) {
-        if (args.size() != 2) {
-          emitError() << "expected 2 attribute arguments, but had "
-                      << args.size();
-          return failure();
-        }
-        return success();
-      });
-}
-
-static std::unique_ptr<DynamicAttrDefinition>
-getCustomAssemblyFormatDynamicAttr(TestDialect *testDialect) {
-  auto verifier = [](function_ref<InFlightDiagnostic()> emitError,
-                     ArrayRef<Attribute> args) {
-    if (args.size() != 2) {
-      emitError() << "expected 2 attribute arguments, but had " << args.size();
-      return failure();
-    }
-    return success();
-  };
-
-  auto parser = [](AsmParser &parser,
-                   llvm::SmallVectorImpl<Attribute> &parsedParams) {
-    Attribute leftAttr, rightAttr;
-    if (parser.parseLess() || parser.parseAttribute(leftAttr) ||
-        parser.parseColon() || parser.parseAttribute(rightAttr) ||
-        parser.parseGreater())
-      return failure();
-    parsedParams.push_back(leftAttr);
-    parsedParams.push_back(rightAttr);
-    return success();
-  };
-
-  auto printer = [](AsmPrinter &printer, ArrayRef<Attribute> params) {
-    printer << "<" << params[0] << ":" << params[1] << ">";
-  };
-
-  return DynamicAttrDefinition::get("custom_assembly_format_dynattr",
-                                    testDialect, std::move(verifier),
-                                    std::move(parser), std::move(printer));
-}
-
 //===----------------------------------------------------------------------===//
 // TestDialect
 //===----------------------------------------------------------------------===//
@@ -295,7 +225,4 @@ void TestDialect::registerAttributes() {
 #define GET_ATTRDEF_LIST
 #include "TestAttrDefs.cpp.inc"
       >();
-  registerDynamicAttr(getSingletonDynamicAttr(this));
-  registerDynamicAttr(getPairDynamicAttr(this));
-  registerDynamicAttr(getCustomAssemblyFormatDynamicAttr(this));
 }

diff  --git a/mlir/test/lib/Dialect/Test/TestDialect.cpp b/mlir/test/lib/Dialect/Test/TestDialect.cpp
index 768e2dfc0ce7d..e0c5eea373b0d 100644
--- a/mlir/test/lib/Dialect/Test/TestDialect.cpp
+++ b/mlir/test/lib/Dialect/Test/TestDialect.cpp
@@ -16,7 +16,6 @@
 #include "mlir/Dialect/Tensor/IR/Tensor.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/DialectImplementation.h"
-#include "mlir/IR/ExtensibleDialect.h"
 #include "mlir/IR/PatternMatch.h"
 #include "mlir/IR/TypeUtilities.h"
 #include "mlir/Reducer/ReductionPatternInterface.h"
@@ -207,58 +206,6 @@ struct TestReductionPatternInterface : public DialectReductionPatternInterface {
 
 } // namespace
 
-//===----------------------------------------------------------------------===//
-// Dynamic operations
-//===----------------------------------------------------------------------===//
-
-std::unique_ptr<DynamicOpDefinition> getGenericDynamicOp(TestDialect *dialect) {
-  return DynamicOpDefinition::get(
-      "generic_dynamic_op", dialect, [](Operation *op) { return success(); },
-      [](Operation *op) { return success(); });
-}
-
-std::unique_ptr<DynamicOpDefinition>
-getOneOperandTwoResultsDynamicOp(TestDialect *dialect) {
-  return DynamicOpDefinition::get(
-      "one_operand_two_results", dialect,
-      [](Operation *op) {
-        if (op->getNumOperands() != 1) {
-          op->emitOpError()
-              << "expected 1 operand, but had " << op->getNumOperands();
-          return failure();
-        }
-        if (op->getNumResults() != 2) {
-          op->emitOpError()
-              << "expected 2 results, but had " << op->getNumResults();
-          return failure();
-        }
-        return success();
-      },
-      [](Operation *op) { return success(); });
-}
-
-std::unique_ptr<DynamicOpDefinition>
-getCustomParserPrinterDynamicOp(TestDialect *dialect) {
-  auto verifier = [](Operation *op) {
-    if (op->getNumOperands() == 0 && op->getNumResults() == 0)
-      return success();
-    op->emitError() << "operation should have no operands and no results";
-    return failure();
-  };
-  auto regionVerifier = [](Operation *op) { return success(); };
-
-  auto parser = [](OpAsmParser &parser, OperationState &state) {
-    return parser.parseKeyword("custom_keyword");
-  };
-
-  auto printer = [](Operation *op, OpAsmPrinter &printer, llvm::StringRef) {
-    printer << op->getName() << " custom_keyword";
-  };
-
-  return DynamicOpDefinition::get("custom_parser_printer_dynamic_op", dialect,
-                                  verifier, regionVerifier, parser, printer);
-}
-
 //===----------------------------------------------------------------------===//
 // TestDialect
 //===----------------------------------------------------------------------===//
@@ -293,10 +240,6 @@ void TestDialect::initialize() {
 #define GET_OP_LIST
 #include "TestOps.cpp.inc"
       >();
-  registerDynamicOp(getGenericDynamicOp(this));
-  registerDynamicOp(getOneOperandTwoResultsDynamicOp(this));
-  registerDynamicOp(getCustomParserPrinterDynamicOp(this));
-
   addInterfaces<TestOpAsmInterface, TestDialectFoldInterface,
                 TestInlinerInterface, TestReductionPatternInterface>();
   allowUnknownOperations();

diff  --git a/mlir/test/lib/Dialect/Test/TestDialect.h b/mlir/test/lib/Dialect/Test/TestDialect.h
index b3d31e971484a..7ce2be79da5f6 100644
--- a/mlir/test/lib/Dialect/Test/TestDialect.h
+++ b/mlir/test/lib/Dialect/Test/TestDialect.h
@@ -23,7 +23,6 @@
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/BuiltinTypes.h"
 #include "mlir/IR/Dialect.h"
-#include "mlir/IR/ExtensibleDialect.h"
 #include "mlir/IR/OpDefinition.h"
 #include "mlir/IR/OpImplementation.h"
 #include "mlir/IR/RegionKindInterface.h"

diff  --git a/mlir/test/lib/Dialect/Test/TestDialect.td b/mlir/test/lib/Dialect/Test/TestDialect.td
index d51ddbaf43d0b..2ac446f04834c 100644
--- a/mlir/test/lib/Dialect/Test/TestDialect.td
+++ b/mlir/test/lib/Dialect/Test/TestDialect.td
@@ -23,8 +23,6 @@ def Test_Dialect : Dialect {
   let hasOperationInterfaceFallback = 1;
   let hasNonDefaultDestructor = 1;
   let useDefaultTypePrinterParser = 0;
-  let useDefaultAttributePrinterParser = 1;
-  let isExtensible = 1;
   let dependentDialects = ["::mlir::DLTIDialect"];
 
   let extraClassDeclaration = [{
@@ -45,10 +43,6 @@ def Test_Dialect : Dialect {
     // Storage for a custom fallback interface.
     void *fallbackEffectOpInterfaces;
 
-    ::mlir::Type parseTestType(::mlir::AsmParser &parser,
-                               ::llvm::SetVector<::mlir::Type> &stack) const;
-    void printTestType(::mlir::Type type, ::mlir::AsmPrinter &printer,
-                       ::llvm::SetVector<::mlir::Type> &stack) const;
   }];
 }
 

diff  --git a/mlir/test/lib/Dialect/Test/TestTypes.cpp b/mlir/test/lib/Dialect/Test/TestTypes.cpp
index 0f9cd7245e313..9b65f2fc06a37 100644
--- a/mlir/test/lib/Dialect/Test/TestTypes.cpp
+++ b/mlir/test/lib/Dialect/Test/TestTypes.cpp
@@ -16,7 +16,6 @@
 #include "mlir/Dialect/LLVMIR/LLVMTypes.h"
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/DialectImplementation.h"
-#include "mlir/IR/ExtensibleDialect.h"
 #include "mlir/IR/Types.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SetVector.h"
@@ -216,72 +215,6 @@ unsigned TestTypeWithLayoutType::extractKind(DataLayoutEntryListRef params,
 #define GET_TYPEDEF_CLASSES
 #include "TestTypeDefs.cpp.inc"
 
-//===----------------------------------------------------------------------===//
-// Dynamic Types
-//===----------------------------------------------------------------------===//
-
-/// Define a singleton dynamic type.
-static std::unique_ptr<DynamicTypeDefinition>
-getSingletonDynamicType(TestDialect *testDialect) {
-  return DynamicTypeDefinition::get(
-      "singleton_dyntype", testDialect,
-      [](function_ref<InFlightDiagnostic()> emitError,
-         ArrayRef<Attribute> args) {
-        if (!args.empty()) {
-          emitError() << "expected 0 type arguments, but had " << args.size();
-          return failure();
-        }
-        return success();
-      });
-}
-
-/// Define a dynamic type representing a pair.
-static std::unique_ptr<DynamicTypeDefinition>
-getPairDynamicType(TestDialect *testDialect) {
-  return DynamicTypeDefinition::get(
-      "pair_dyntype", testDialect,
-      [](function_ref<InFlightDiagnostic()> emitError,
-         ArrayRef<Attribute> args) {
-        if (args.size() != 2) {
-          emitError() << "expected 2 type arguments, but had " << args.size();
-          return failure();
-        }
-        return success();
-      });
-}
-
-static std::unique_ptr<DynamicTypeDefinition>
-getCustomAssemblyFormatDynamicType(TestDialect *testDialect) {
-  auto verifier = [](function_ref<InFlightDiagnostic()> emitError,
-                     ArrayRef<Attribute> args) {
-    if (args.size() != 2) {
-      emitError() << "expected 2 type arguments, but had " << args.size();
-      return failure();
-    }
-    return success();
-  };
-
-  auto parser = [](AsmParser &parser,
-                   llvm::SmallVectorImpl<Attribute> &parsedParams) {
-    Attribute leftAttr, rightAttr;
-    if (parser.parseLess() || parser.parseAttribute(leftAttr) ||
-        parser.parseColon() || parser.parseAttribute(rightAttr) ||
-        parser.parseGreater())
-      return failure();
-    parsedParams.push_back(leftAttr);
-    parsedParams.push_back(rightAttr);
-    return success();
-  };
-
-  auto printer = [](AsmPrinter &printer, ArrayRef<Attribute> params) {
-    printer << "<" << params[0] << ":" << params[1] << ">";
-  };
-
-  return DynamicTypeDefinition::get("custom_assembly_format_dyntype",
-                                    testDialect, std::move(verifier),
-                                    std::move(parser), std::move(printer));
-}
-
 //===----------------------------------------------------------------------===//
 // TestDialect
 //===----------------------------------------------------------------------===//
@@ -299,14 +232,9 @@ void TestDialect::registerTypes() {
 #include "TestTypeDefs.cpp.inc"
            >();
   SimpleAType::attachInterface<PtrElementModel>(*getContext());
-
-  registerDynamicType(getSingletonDynamicType(this));
-  registerDynamicType(getPairDynamicType(this));
-  registerDynamicType(getCustomAssemblyFormatDynamicType(this));
 }
 
-Type TestDialect::parseTestType(AsmParser &parser,
-                                SetVector<Type> &stack) const {
+static Type parseTestType(AsmParser &parser, SetVector<Type> &stack) {
   StringRef typeTag;
   if (failed(parser.parseKeyword(&typeTag)))
     return Type();
@@ -318,16 +246,6 @@ Type TestDialect::parseTestType(AsmParser &parser,
       return genType;
   }
 
-  {
-    Type dynType;
-    auto parseResult = parseOptionalDynamicType(typeTag, parser, dynType);
-    if (parseResult.hasValue()) {
-      if (succeeded(parseResult.getValue()))
-        return dynType;
-      return Type();
-    }
-  }
-
   if (typeTag != "test_rec") {
     parser.emitError(parser.getNameLoc()) << "unknown type!";
     return Type();
@@ -363,14 +281,11 @@ Type TestDialect::parseType(DialectAsmParser &parser) const {
   return parseTestType(parser, stack);
 }
 
-void TestDialect::printTestType(Type type, AsmPrinter &printer,
-                                SetVector<Type> &stack) const {
+static void printTestType(Type type, AsmPrinter &printer,
+                          SetVector<Type> &stack) {
   if (succeeded(generatedTypePrinter(type, printer)))
     return;
 
-  if (succeeded(printIfDynamicType(type, printer)))
-    return;
-
   auto rec = type.cast<TestRecursiveType>();
   printer << "test_rec<" << rec.getName();
   if (!stack.contains(rec)) {

diff  --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index 552dbaf95d618..c6db1c0418846 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -734,8 +734,6 @@ void DefGenerator::emitTypeDefList(ArrayRef<AttrOrTypeDef> defs) {
 
 /// The code block for default attribute parser/printer dispatch boilerplate.
 /// {0}: the dialect fully qualified class name.
-/// {1}: the optional code for the dynamic attribute parser dispatch.
-/// {2}: the optional code for the dynamic attribute printer dispatch.
 static const char *const dialectDefaultAttrPrinterParserDispatch = R"(
 /// Parse an attribute registered to this dialect.
 ::mlir::Attribute {0}::parseAttribute(::mlir::DialectAsmParser &parser,
@@ -750,7 +748,6 @@ ::mlir::Attribute {0}::parseAttribute(::mlir::DialectAsmParser &parser,
     if (parseResult.hasValue())
       return attr;
   }
-  {1}
   parser.emitError(typeLoc) << "unknown attribute `"
       << attrTag << "` in dialect `" << getNamespace() << "`";
   return {{};
@@ -760,33 +757,11 @@ void {0}::printAttribute(::mlir::Attribute attr,
                          ::mlir::DialectAsmPrinter &printer) const {{
   if (::mlir::succeeded(generatedAttributePrinter(attr, printer)))
     return;
-  {2}
 }
 )";
 
-/// The code block for dynamic attribute parser dispatch boilerplate.
-static const char *const dialectDynamicAttrParserDispatch = R"(
-  {
-    ::mlir::Attribute genAttr;
-    auto parseResult = parseOptionalDynamicAttr(attrTag, parser, genAttr);
-    if (parseResult.hasValue()) {
-      if (::mlir::succeeded(parseResult.getValue()))
-        return genAttr;
-      return Attribute();
-    }
-  }
-)";
-
-/// The code block for dynamic type printer dispatch boilerplate.
-static const char *const dialectDynamicAttrPrinterDispatch = R"(
-  if (::mlir::succeeded(printIfDynamicAttr(attr, printer)))
-    return;
-)";
-
 /// The code block for default type parser/printer dispatch boilerplate.
 /// {0}: the dialect fully qualified class name.
-/// {1}: the optional code for the dynamic type parser dispatch.
-/// {2}: the optional code for the dynamic type printer dispatch.
 static const char *const dialectDefaultTypePrinterParserDispatch = R"(
 /// Parse a type registered to this dialect.
 ::mlir::Type {0}::parseType(::mlir::DialectAsmParser &parser) const {{
@@ -798,7 +773,6 @@ ::mlir::Type {0}::parseType(::mlir::DialectAsmParser &parser) const {{
   auto parseResult = generatedTypeParser(parser, mnemonic, genType);
   if (parseResult.hasValue())
     return genType;
-  {1}
   parser.emitError(typeLoc) << "unknown  type `"
       << mnemonic << "` in dialect `" << getNamespace() << "`";
   return {{};
@@ -808,28 +782,9 @@ void {0}::printType(::mlir::Type type,
                     ::mlir::DialectAsmPrinter &printer) const {{
   if (::mlir::succeeded(generatedTypePrinter(type, printer)))
     return;
-  {2}
 }
 )";
 
-/// The code block for dynamic type parser dispatch boilerplate.
-static const char *const dialectDynamicTypeParserDispatch = R"(
-  {
-    auto parseResult = parseOptionalDynamicType(mnemonic, parser, genType);
-    if (parseResult.hasValue()) {
-      if (::mlir::succeeded(parseResult.getValue()))
-        return genType;
-      return Type();
-    }
-  }
-)";
-
-/// The code block for dynamic type printer dispatch boilerplate.
-static const char *const dialectDynamicTypePrinterDispatch = R"(
-  if (::mlir::succeeded(printIfDynamicType(type, printer)))
-    return;
-)";
-
 /// Emit the dialect printer/parser dispatcher. User's code should call these
 /// functions from their dialect's print/parse methods.
 void DefGenerator::emitParsePrintDispatch(ArrayRef<AttrOrTypeDef> defs) {
@@ -925,30 +880,16 @@ bool DefGenerator::emitDefs(StringRef selectedDialect) {
   if (valueType == "Attribute" && needsDialectParserPrinter &&
       firstDialect.useDefaultAttributePrinterParser()) {
     NamespaceEmitter nsEmitter(os, firstDialect);
-    if (firstDialect.isExtensible()) {
-      os << llvm::formatv(dialectDefaultAttrPrinterParserDispatch,
-                          firstDialect.getCppClassName(),
-                          dialectDynamicAttrParserDispatch,
-                          dialectDynamicAttrPrinterDispatch);
-    } else {
-      os << llvm::formatv(dialectDefaultAttrPrinterParserDispatch,
-                          firstDialect.getCppClassName(), "", "");
-    }
+    os << llvm::formatv(dialectDefaultAttrPrinterParserDispatch,
+                        firstDialect.getCppClassName());
   }
 
   // Emit the default parser/printer for Types if the dialect asked for it.
   if (valueType == "Type" && needsDialectParserPrinter &&
       firstDialect.useDefaultTypePrinterParser()) {
     NamespaceEmitter nsEmitter(os, firstDialect);
-    if (firstDialect.isExtensible()) {
-      os << llvm::formatv(dialectDefaultTypePrinterParserDispatch,
-                          firstDialect.getCppClassName(),
-                          dialectDynamicTypeParserDispatch,
-                          dialectDynamicTypePrinterDispatch);
-    } else {
-      os << llvm::formatv(dialectDefaultTypePrinterParserDispatch,
-                          firstDialect.getCppClassName(), "", "");
-    }
+    os << llvm::formatv(dialectDefaultTypePrinterParserDispatch,
+                        firstDialect.getCppClassName());
   }
 
   return false;

diff  --git a/mlir/tools/mlir-tblgen/DialectGen.cpp b/mlir/tools/mlir-tblgen/DialectGen.cpp
index 7efa2b9437f63..6338cf19d1b96 100644
--- a/mlir/tools/mlir-tblgen/DialectGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectGen.cpp
@@ -90,9 +90,9 @@ findSelectedDialect(ArrayRef<const llvm::Record *> dialectDefs) {
 /// {2}: initialization code that is emitted in the ctor body before calling
 /// initialize()
 static const char *const dialectDeclBeginStr = R"(
-class {0} : public ::mlir::{3} {
+class {0} : public ::mlir::Dialect {
   explicit {0}(::mlir::MLIRContext *context)
-    : ::mlir::{3}(getDialectNamespace(), context,
+    : ::mlir::Dialect(getDialectNamespace(), context,
       ::mlir::TypeID::get<{0}>()) {{
     {2}
     initialize();
@@ -205,10 +205,8 @@ emitDialectDecl(Dialect &dialect,
 
     // Emit the start of the decl.
     std::string cppName = dialect.getCppClassName();
-    StringRef superClassName =
-        dialect.isExtensible() ? "ExtensibleDialect" : "Dialect";
     os << llvm::formatv(dialectDeclBeginStr, cppName, dialect.getName(),
-                        dependentDialectRegistrations, superClassName);
+                        dependentDialectRegistrations);
 
     // Check for any attributes/types registered to this dialect.  If there are,
     // add the hooks for parsing/printing.


        


More information about the Mlir-commits mailing list