[flang-commits] [mlir] [flang] [mlir] Expose type and attribute names in the MLIRContext and abstract type/attr classes (PR #72189)

Fehr Mathieu via flang-commits flang-commits at lists.llvm.org
Wed Nov 29 20:14:15 PST 2023


https://github.com/math-fehr updated https://github.com/llvm/llvm-project/pull/72189

>From 7dbc7196d9fd0c1370e79e25a527791d66df54f9 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Thu, 19 Oct 2023 02:20:07 +0100
Subject: [PATCH 01/16] Add names to AbtsractType and Type

---
 mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h | 39 ++++++++++---
 mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h  | 17 +++---
 mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td |  4 ++
 mlir/include/mlir/Dialect/Quant/QuantTypes.h  |  8 +++
 .../mlir/Dialect/SPIRV/IR/SPIRVTypes.h        | 20 +++++++
 mlir/include/mlir/IR/AttrTypeBase.td          |  3 +
 mlir/include/mlir/IR/BuiltinTypes.td          | 57 ++++++++++---------
 mlir/include/mlir/IR/TypeSupport.h            | 22 +++++--
 mlir/include/mlir/TableGen/AttrOrTypeDef.h    |  3 +
 mlir/lib/IR/ExtensibleDialect.cpp             |  6 +-
 mlir/lib/IR/MLIRContext.cpp                   | 24 +++++++-
 mlir/lib/TableGen/AttrOrTypeDef.cpp           |  4 ++
 mlir/test/lib/Dialect/Test/TestTypes.h        |  2 +
 mlir/test/mlir-tblgen/op-decl-and-defs.td     |  4 +-
 mlir/test/mlir-tblgen/typedefs.td             |  2 +
 mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp   | 11 ++++
 mlir/unittests/IR/TypeTest.cpp                |  5 ++
 .../Interfaces/DataLayoutInterfacesTest.cpp   |  4 ++
 18 files changed, 184 insertions(+), 51 deletions(-)

diff --git a/mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h b/mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h
index 14a1fac5fd255f3..29ba15f8fe073a6 100644
--- a/mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h
+++ b/mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h
@@ -45,6 +45,8 @@ class AsyncTokenType
 public:
   // Used for generic hooks in TypeBase.
   using Base::Base;
+
+  static constexpr StringRef getTypeName() { return "gpu.async_token"; }
 };
 
 /// MMAMatrixType storage and uniquing. Array is uniqued based on its shape
@@ -128,6 +130,8 @@ class MMAMatrixType
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "gpu.mma_matrix"; }
+
   /// Get MMAMatrixType and verify construction Invariants.
   static MMAMatrixType get(ArrayRef<int64_t> shape, Type elementType,
                            StringRef operand);
@@ -168,18 +172,39 @@ void addAsyncDependency(Operation *op, Value token);
 // Handle types for sparse.
 enum class SparseHandleKind { SpMat, DnTensor, SpGEMMOp };
 
-template <SparseHandleKind K>
-class SparseHandleType
-    : public Type::TypeBase<SparseHandleType<K>, Type, TypeStorage> {
+class SparseDnTensorHandleType
+    : public Type::TypeBase<SparseDnTensorHandleType, Type, TypeStorage> {
+public:
+  using Base = typename Type::TypeBase<SparseDnTensorHandleType, Type,
+                                       TypeStorage>::Base;
+  using Base::Base;
+
+  static constexpr StringRef getTypeName() {
+    return "gpu.sparse.dntensor_handle";
+  }
+};
+
+class SparseSpMatHandleType
+    : public Type::TypeBase<SparseSpMatHandleType, Type, TypeStorage> {
 public:
   using Base =
-      typename Type::TypeBase<SparseHandleType<K>, Type, TypeStorage>::Base;
+      typename Type::TypeBase<SparseSpMatHandleType, Type, TypeStorage>::Base;
   using Base::Base;
+
+  static constexpr StringRef getTypeName() { return "gpu.sparse.spmat_handle"; }
 };
 
-using SparseDnTensorHandleType = SparseHandleType<SparseHandleKind::DnTensor>;
-using SparseSpMatHandleType = SparseHandleType<SparseHandleKind::SpMat>;
-using SparseSpGEMMOpHandleType = SparseHandleType<SparseHandleKind::SpGEMMOp>;
+class SparseSpGEMMOpHandleType
+    : public Type::TypeBase<SparseSpGEMMOpHandleType, Type, TypeStorage> {
+public:
+  using Base = typename Type::TypeBase<SparseSpGEMMOpHandleType, Type,
+                                       TypeStorage>::Base;
+  using Base::Base;
+
+  static constexpr StringRef getTypeName() {
+    return "gpu.sparse.spgemmop_handle";
+  }
+};
 
 } // namespace gpu
 } // namespace mlir
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
index ba2f14f173aa0c3..66d9a11a1693bc7 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
@@ -58,18 +58,19 @@ namespace LLVM {
 //===----------------------------------------------------------------------===//
 
 // Batch-define trivial types.
-#define DEFINE_TRIVIAL_LLVM_TYPE(ClassName)                                    \
+#define DEFINE_TRIVIAL_LLVM_TYPE(ClassName, TypeName)                          \
   class ClassName : public Type::TypeBase<ClassName, Type, TypeStorage> {      \
   public:                                                                      \
     using Base::Base;                                                          \
+    static constexpr StringRef getTypeName() { return TypeName; }              \
   }
 
-DEFINE_TRIVIAL_LLVM_TYPE(LLVMVoidType);
-DEFINE_TRIVIAL_LLVM_TYPE(LLVMPPCFP128Type);
-DEFINE_TRIVIAL_LLVM_TYPE(LLVMX86MMXType);
-DEFINE_TRIVIAL_LLVM_TYPE(LLVMTokenType);
-DEFINE_TRIVIAL_LLVM_TYPE(LLVMLabelType);
-DEFINE_TRIVIAL_LLVM_TYPE(LLVMMetadataType);
+DEFINE_TRIVIAL_LLVM_TYPE(LLVMVoidType, "llvm.void");
+DEFINE_TRIVIAL_LLVM_TYPE(LLVMPPCFP128Type, "llvm.ppc_fp128");
+DEFINE_TRIVIAL_LLVM_TYPE(LLVMX86MMXType, "llvm.x86_mmx");
+DEFINE_TRIVIAL_LLVM_TYPE(LLVMTokenType, "llvm.token");
+DEFINE_TRIVIAL_LLVM_TYPE(LLVMLabelType, "llvm.label");
+DEFINE_TRIVIAL_LLVM_TYPE(LLVMMetadataType, "llvm.metadata");
 
 #undef DEFINE_TRIVIAL_LLVM_TYPE
 
@@ -110,6 +111,8 @@ class LLVMStructType
   /// Inherit base constructors.
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "llvm.struct"; }
+
   /// Checks if the given type can be contained in a structure type.
   static bool isValidElementType(Type type);
 
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
index 0bd068c1be7c90a..96cdbf01b4bd91f 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td
@@ -162,6 +162,8 @@ def LLVMFixedVectorType : LLVMType<"LLVMFixedVector", "vec"> {
     elements can be processed as one in SIMD context.
   }];
 
+  let typeName = "llvm.fixed_vec";
+
   let parameters = (ins "Type":$elementType, "unsigned":$numElements);
   let assemblyFormat = [{
     `<` $numElements `x` custom<PrettyLLVMType>($elementType) `>`
@@ -192,6 +194,8 @@ def LLVMScalableVectorType : LLVMType<"LLVMScalableVector", "vec"> {
     elements can be processed as one in SIMD context.
   }];
 
+  let typeName = "llvm.scalable_vec";
+
   let parameters = (ins "Type":$elementType, "unsigned":$minNumElements);
   let assemblyFormat = [{
     `<` `?` `x` $minNumElements `x` ` ` custom<PrettyLLVMType>($elementType) `>`
diff --git a/mlir/include/mlir/Dialect/Quant/QuantTypes.h b/mlir/include/mlir/Dialect/Quant/QuantTypes.h
index 2776b3e6e17ba50..f0300ea8cbb8ab2 100644
--- a/mlir/include/mlir/Dialect/Quant/QuantTypes.h
+++ b/mlir/include/mlir/Dialect/Quant/QuantTypes.h
@@ -198,6 +198,8 @@ class AnyQuantizedType
   using Base::Base;
   using Base::getChecked;
 
+  static constexpr StringRef getTypeName() { return "quant.any"; }
+
   /// Gets an instance of the type with all parameters specified but not
   /// checked.
   static AnyQuantizedType get(unsigned flags, Type storageType,
@@ -257,6 +259,8 @@ class UniformQuantizedType
   using Base::Base;
   using Base::getChecked;
 
+  static constexpr StringRef getTypeName() { return "quant.uniform"; }
+
   /// Gets an instance of the type with all parameters specified but not
   /// checked.
   static UniformQuantizedType get(unsigned flags, Type storageType,
@@ -315,6 +319,8 @@ class UniformQuantizedPerAxisType
   using Base::Base;
   using Base::getChecked;
 
+  static constexpr StringRef getTypeName() { return "quant.uniform_per_axis"; }
+
   /// Gets an instance of the type with all parameters specified but not
   /// checked.
   static UniformQuantizedPerAxisType
@@ -383,6 +389,8 @@ class CalibratedQuantizedType
   using Base::Base;
   using Base::getChecked;
 
+  static constexpr StringRef getTypeName() { return "quant.calibrated"; }
+
   /// Gets an instance of the type with all parameters specified but not
   /// checked.
   static CalibratedQuantizedType get(Type expressedType, double min,
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTypes.h b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTypes.h
index 4be2582f8fd68cc..e536adc8dce4abb 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTypes.h
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTypes.h
@@ -132,6 +132,8 @@ class ArrayType : public Type::TypeBase<ArrayType, CompositeType,
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.array"; }
+
   static ArrayType get(Type elementType, unsigned elementCount);
 
   /// Returns an array type with the given stride in bytes.
@@ -162,6 +164,8 @@ class ImageType
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.image"; }
+
   static ImageType
   get(Type elementType, Dim dim,
       ImageDepthInfo depth = ImageDepthInfo::DepthUnknown,
@@ -201,6 +205,8 @@ class PointerType : public Type::TypeBase<PointerType, SPIRVType,
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.pointer"; }
+
   static PointerType get(Type pointeeType, StorageClass storageClass);
 
   Type getPointeeType() const;
@@ -220,6 +226,8 @@ class RuntimeArrayType
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.rtarray"; }
+
   static RuntimeArrayType get(Type elementType);
 
   /// Returns a runtime array type with the given stride in bytes.
@@ -244,6 +252,8 @@ class SampledImageType
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.sampled_image"; }
+
   static SampledImageType get(Type imageType);
 
   static SampledImageType
@@ -288,6 +298,8 @@ class StructType
   // Type for specifying the offset of the struct members
   using OffsetInfo = uint32_t;
 
+  static constexpr StringRef getTypeName() { return "spirv.struct"; }
+
   // Type for specifying the decoration(s) on struct members
   struct MemberDecorationInfo {
     uint32_t memberIndex : 31;
@@ -387,6 +399,8 @@ class CooperativeMatrixType
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.coopmatrix"; }
+
   static CooperativeMatrixType get(Type elementType, uint32_t rows,
                                    uint32_t columns, Scope scope,
                                    CooperativeMatrixUseKHR use);
@@ -414,6 +428,8 @@ class CooperativeMatrixNVType
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.NV.coopmatrix"; }
+
   static CooperativeMatrixNVType get(Type elementType, Scope scope,
                                      unsigned rows, unsigned columns);
   Type getElementType() const;
@@ -438,6 +454,8 @@ class JointMatrixINTELType
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.jointmatrix"; }
+
   static JointMatrixINTELType get(Type elementType, Scope scope, unsigned rows,
                                   unsigned columns, MatrixLayout matrixLayout);
   Type getElementType() const;
@@ -464,6 +482,8 @@ class MatrixType : public Type::TypeBase<MatrixType, CompositeType,
 public:
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "spirv.matrix"; }
+
   static MatrixType get(Type columnType, uint32_t columnCount);
 
   static MatrixType getChecked(function_ref<InFlightDiagnostic()> emitError,
diff --git a/mlir/include/mlir/IR/AttrTypeBase.td b/mlir/include/mlir/IR/AttrTypeBase.td
index 42a611ee8e42205..89c1e746f01559d 100644
--- a/mlir/include/mlir/IR/AttrTypeBase.td
+++ b/mlir/include/mlir/IR/AttrTypeBase.td
@@ -289,6 +289,9 @@ class TypeDef<Dialect dialect, string name, list<Trait> traits = [],
   // Make it possible to use such type as parameters for other types.
   string cppType = dialect.cppNamespace # "::" # cppClassName;
 
+  // The unique type name.
+  string typeName = dialect.name # "." # mnemonic;
+
   // A constant builder provided when the type has no parameters.
   let builderCall = !if(!empty(parameters),
                            "$_builder.getType<" # dialect.cppNamespace #
diff --git a/mlir/include/mlir/IR/BuiltinTypes.td b/mlir/include/mlir/IR/BuiltinTypes.td
index 5ec986ac26de06b..208287be789b6b4 100644
--- a/mlir/include/mlir/IR/BuiltinTypes.td
+++ b/mlir/include/mlir/IR/BuiltinTypes.td
@@ -23,17 +23,18 @@ include "mlir/IR/BuiltinTypeInterfaces.td"
 // remove the definitions in OpBase.td, and repoint users to this file instead.
 
 // Base class for Builtin dialect types.
-class Builtin_Type<string name, list<Trait> traits = [],
+class Builtin_Type<string name, string typeMnemonic, list<Trait> traits = [],
                    string baseCppClass = "::mlir::Type">
     : TypeDef<Builtin_Dialect, name, traits, baseCppClass> {
   let mnemonic = ?;
+  let typeName = "builtin." # typeMnemonic;
 }
 
 //===----------------------------------------------------------------------===//
 // ComplexType
 //===----------------------------------------------------------------------===//
 
-def Builtin_Complex : Builtin_Type<"Complex"> {
+def Builtin_Complex : Builtin_Type<"Complex", "complex"> {
   let summary = "Complex number with a parameterized element type";
   let description = [{
     Syntax:
@@ -68,8 +69,8 @@ def Builtin_Complex : Builtin_Type<"Complex"> {
 //===----------------------------------------------------------------------===//
 
 // Base class for Builtin dialect float types.
-class Builtin_FloatType<string name>
-    : Builtin_Type<name, /*traits=*/[], "::mlir::FloatType"> {
+class Builtin_FloatType<string name, string mnemonic>
+    : Builtin_Type<name, mnemonic, /*traits=*/[], "::mlir::FloatType"> {
   let extraClassDeclaration = [{
     static }] # name # [{Type get(MLIRContext *context);
   }];
@@ -78,7 +79,7 @@ class Builtin_FloatType<string name>
 //===----------------------------------------------------------------------===//
 // Float8E5M2Type
 
-def Builtin_Float8E5M2 : Builtin_FloatType<"Float8E5M2"> {
+def Builtin_Float8E5M2 : Builtin_FloatType<"Float8E5M2", "f8E5M2"> {
   let summary = "8-bit floating point with 2 bit mantissa";
   let description = [{
     An 8-bit floating point type with 1 sign bit, 5 bits exponent and 2 bits
@@ -99,7 +100,7 @@ def Builtin_Float8E5M2 : Builtin_FloatType<"Float8E5M2"> {
 //===----------------------------------------------------------------------===//
 // Float8E4M3FNType
 
-def Builtin_Float8E4M3FN : Builtin_FloatType<"Float8E4M3FN"> {
+def Builtin_Float8E4M3FN : Builtin_FloatType<"Float8E4M3FN", "f8E4M3FN"> {
   let summary = "8-bit floating point with 3 bit mantissa";
   let description = [{
     An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits
@@ -121,7 +122,7 @@ def Builtin_Float8E4M3FN : Builtin_FloatType<"Float8E4M3FN"> {
 //===----------------------------------------------------------------------===//
 // Float8E5M2FNUZType
 
-def Builtin_Float8E5M2FNUZ : Builtin_FloatType<"Float8E5M2FNUZ"> {
+def Builtin_Float8E5M2FNUZ : Builtin_FloatType<"Float8E5M2FNUZ", "f8E5M2FNUZ"> {
   let summary = "8-bit floating point with 2 bit mantissa";
   let description = [{
     An 8-bit floating point type with 1 sign bit, 5 bits exponent and 2 bits
@@ -143,7 +144,7 @@ def Builtin_Float8E5M2FNUZ : Builtin_FloatType<"Float8E5M2FNUZ"> {
 //===----------------------------------------------------------------------===//
 // Float8E4M3FNUZType
 
-def Builtin_Float8E4M3FNUZ : Builtin_FloatType<"Float8E4M3FNUZ"> {
+def Builtin_Float8E4M3FNUZ : Builtin_FloatType<"Float8E4M3FNUZ", "f8E4M3FNUZ"> {
   let summary = "8-bit floating point with 3 bit mantissa";
   let description = [{
     An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits
@@ -165,7 +166,7 @@ def Builtin_Float8E4M3FNUZ : Builtin_FloatType<"Float8E4M3FNUZ"> {
 //===----------------------------------------------------------------------===//
 // Float8E4M3B11FNUZType
 
-def Builtin_Float8E4M3B11FNUZ : Builtin_FloatType<"Float8E4M3B11FNUZ"> {
+def Builtin_Float8E4M3B11FNUZ : Builtin_FloatType<"Float8E4M3B11FNUZ", "f8E4M3B11FNUZ"> {
   let summary = "8-bit floating point with 3 bit mantissa";
   let description = [{
     An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits
@@ -187,49 +188,49 @@ def Builtin_Float8E4M3B11FNUZ : Builtin_FloatType<"Float8E4M3B11FNUZ"> {
 //===----------------------------------------------------------------------===//
 // BFloat16Type
 
-def Builtin_BFloat16 : Builtin_FloatType<"BFloat16"> {
+def Builtin_BFloat16 : Builtin_FloatType<"BFloat16", "bf16"> {
   let summary = "bfloat16 floating-point type";
 }
 
 //===----------------------------------------------------------------------===//
 // Float16Type
 
-def Builtin_Float16 : Builtin_FloatType<"Float16"> {
+def Builtin_Float16 : Builtin_FloatType<"Float16", "f16"> {
   let summary = "16-bit floating-point type";
 }
 
 //===----------------------------------------------------------------------===//
 // FloatTF32Type
 
-def Builtin_FloatTF32 : Builtin_FloatType<"FloatTF32"> {
+def Builtin_FloatTF32 : Builtin_FloatType<"FloatTF32", "tf32"> {
   let summary = "TF32 floating-point type";
 }
 
 //===----------------------------------------------------------------------===//
 // Float32Type
 
-def Builtin_Float32 : Builtin_FloatType<"Float32"> {
+def Builtin_Float32 : Builtin_FloatType<"Float32", "f32"> {
   let summary = "32-bit floating-point type";
 }
 
 //===----------------------------------------------------------------------===//
 // Float64Type
 
-def Builtin_Float64 : Builtin_FloatType<"Float64"> {
+def Builtin_Float64 : Builtin_FloatType<"Float64", "f64"> {
   let summary = "64-bit floating-point type";
 }
 
 //===----------------------------------------------------------------------===//
 // Float80Type
 
-def Builtin_Float80 : Builtin_FloatType<"Float80"> {
+def Builtin_Float80 : Builtin_FloatType<"Float80", "f80"> {
   let summary = "80-bit floating-point type";
 }
 
 //===----------------------------------------------------------------------===//
 // Float128Type
 
-def Builtin_Float128 : Builtin_FloatType<"Float128"> {
+def Builtin_Float128 : Builtin_FloatType<"Float128", "f128"> {
   let summary = "128-bit floating-point type";
 }
 
@@ -237,7 +238,7 @@ def Builtin_Float128 : Builtin_FloatType<"Float128"> {
 // FunctionType
 //===----------------------------------------------------------------------===//
 
-def Builtin_Function : Builtin_Type<"Function"> {
+def Builtin_Function : Builtin_Type<"Function", "function"> {
   let summary = "Map from a list of inputs to a list of results";
   let description = [{
     Syntax:
@@ -289,7 +290,7 @@ def Builtin_Function : Builtin_Type<"Function"> {
 // IndexType
 //===----------------------------------------------------------------------===//
 
-def Builtin_Index : Builtin_Type<"Index"> {
+def Builtin_Index : Builtin_Type<"Index", "index"> {
   let summary = "Integer-like type with unknown platform-dependent bit width";
   let description = [{
     Syntax:
@@ -319,7 +320,7 @@ def Builtin_Index : Builtin_Type<"Index"> {
 // IntegerType
 //===----------------------------------------------------------------------===//
 
-def Builtin_Integer : Builtin_Type<"Integer"> {
+def Builtin_Integer : Builtin_Type<"Integer", "integer"> {
   let summary = "Integer type with arbitrary precision up to a fixed limit";
   let description = [{
     Syntax:
@@ -383,7 +384,7 @@ def Builtin_Integer : Builtin_Type<"Integer"> {
 // MemRefType
 //===----------------------------------------------------------------------===//
 
-def Builtin_MemRef : Builtin_Type<"MemRef", [
+def Builtin_MemRef : Builtin_Type<"MemRef", "memref", [
     ShapedTypeInterface
   ], "BaseMemRefType"> {
   let summary = "Shaped reference to a region of memory";
@@ -536,7 +537,7 @@ def Builtin_MemRef : Builtin_Type<"MemRef", [
     %B = alloc() : memref<16x32x64xf32>
     // Remove rank info
     %A_u = memref_cast %A : memref<16x32xf32> -> memref<*xf32>
-    %B_u = memref_cast %B : memref<16x32x64xf32> -> memref<*xf32>
+    %B_u = memref_cast %B : memr>f<16x32x64xf32> -> memref<*xf32>
     // call same function with dynamic ranks
     call @helper(%A_u) : (memref<*xf32>)->()
     call @helper(%B_u) : (memref<*xf32>)->()
@@ -663,7 +664,7 @@ def Builtin_MemRef : Builtin_Type<"MemRef", [
 // NoneType
 //===----------------------------------------------------------------------===//
 
-def Builtin_None : Builtin_Type<"None"> {
+def Builtin_None : Builtin_Type<"None", "none"> {
   let summary = "A unit type";
   let description = [{
     NoneType is a unit type, i.e. a type with exactly one possible value, where
@@ -678,7 +679,7 @@ def Builtin_None : Builtin_Type<"None"> {
 // OpaqueType
 //===----------------------------------------------------------------------===//
 
-def Builtin_Opaque : Builtin_Type<"Opaque"> {
+def Builtin_Opaque : Builtin_Type<"Opaque", "opaque"> {
   let summary = "Type of a non-registered dialect";
   let description = [{
     Syntax:
@@ -718,7 +719,7 @@ def Builtin_Opaque : Builtin_Type<"Opaque"> {
 // RankedTensorType
 //===----------------------------------------------------------------------===//
 
-def Builtin_RankedTensor : Builtin_Type<"RankedTensor", [
+def Builtin_RankedTensor : Builtin_Type<"RankedTensor", "tensor", [
     ShapedTypeInterface
   ], "TensorType"> {
   let summary = "Multi-dimensional array with a fixed number of dimensions";
@@ -829,7 +830,7 @@ def Builtin_RankedTensor : Builtin_Type<"RankedTensor", [
 // TupleType
 //===----------------------------------------------------------------------===//
 
-def Builtin_Tuple : Builtin_Type<"Tuple"> {
+def Builtin_Tuple : Builtin_Type<"Tuple", "tuple"> {
   let summary = "Fixed-sized collection of other types";
   let description = [{
     Syntax:
@@ -896,7 +897,7 @@ def Builtin_Tuple : Builtin_Type<"Tuple"> {
 // UnrankedMemRefType
 //===----------------------------------------------------------------------===//
 
-def Builtin_UnrankedMemRef : Builtin_Type<"UnrankedMemRef", [
+def Builtin_UnrankedMemRef : Builtin_Type<"UnrankedMemRef", "unranked_memref", [
     ShapedTypeInterface
   ], "BaseMemRefType"> {
   let summary = "Shaped reference, with unknown rank, to a region of memory";
@@ -974,7 +975,7 @@ def Builtin_UnrankedMemRef : Builtin_Type<"UnrankedMemRef", [
 // UnrankedTensorType
 //===----------------------------------------------------------------------===//
 
-def Builtin_UnrankedTensor : Builtin_Type<"UnrankedTensor", [
+def Builtin_UnrankedTensor : Builtin_Type<"UnrankedTensor", "unranked_tensor", [
     ShapedTypeInterface
   ], "TensorType"> {
   let summary = "Multi-dimensional array with unknown dimensions";
@@ -1023,7 +1024,7 @@ def Builtin_UnrankedTensor : Builtin_Type<"UnrankedTensor", [
 // VectorType
 //===----------------------------------------------------------------------===//
 
-def Builtin_Vector : Builtin_Type<"Vector", [ShapedTypeInterface], "Type"> {
+def Builtin_Vector : Builtin_Type<"Vector", "vector", [ShapedTypeInterface], "Type"> {
   let summary = "Multi-dimensional SIMD vector type";
   let description = [{
     Syntax:
diff --git a/mlir/include/mlir/IR/TypeSupport.h b/mlir/include/mlir/IR/TypeSupport.h
index 2aa6b1a59e86960..18386a5ced2f801 100644
--- a/mlir/include/mlir/IR/TypeSupport.h
+++ b/mlir/include/mlir/IR/TypeSupport.h
@@ -39,13 +39,19 @@ class AbstractType {
   /// reference to it.
   static const AbstractType &lookup(TypeID typeID, MLIRContext *context);
 
+  /// Look up the specified abstract type in the MLIRContext and return a
+  /// reference to it if it exists.
+  static std::optional<std::reference_wrapper<const AbstractType>>
+  lookup(StringRef name, MLIRContext *context);
+
   /// This method is used by Dialect objects when they register the list of
   /// types they contain.
   template <typename T>
   static AbstractType get(Dialect &dialect) {
     return AbstractType(dialect, T::getInterfaceMap(), T::getHasTraitFn(),
                         T::getWalkImmediateSubElementsFn(),
-                        T::getReplaceImmediateSubElementsFn(), T::getTypeID());
+                        T::getReplaceImmediateSubElementsFn(), T::getTypeID(),
+                        T::getTypeName());
   }
 
   /// This method is used by Dialect objects to register types with
@@ -57,10 +63,10 @@ class AbstractType {
       HasTraitFn &&hasTrait,
       WalkImmediateSubElementsFn walkImmediateSubElementsFn,
       ReplaceImmediateSubElementsFn replaceImmediateSubElementsFn,
-      TypeID typeID) {
+      TypeID typeID, StringRef name) {
     return AbstractType(dialect, std::move(interfaceMap), std::move(hasTrait),
                         walkImmediateSubElementsFn,
-                        replaceImmediateSubElementsFn, typeID);
+                        replaceImmediateSubElementsFn, typeID, name);
   }
 
   /// Return the dialect this type was registered to.
@@ -100,17 +106,20 @@ class AbstractType {
   /// Return the unique identifier representing the concrete type class.
   TypeID getTypeID() const { return typeID; }
 
+  /// Return the unique name representing the type.
+  StringRef getName() const { return name; }
+
 private:
   AbstractType(Dialect &dialect, detail::InterfaceMap &&interfaceMap,
                HasTraitFn &&hasTrait,
                WalkImmediateSubElementsFn walkImmediateSubElementsFn,
                ReplaceImmediateSubElementsFn replaceImmediateSubElementsFn,
-               TypeID typeID)
+               TypeID typeID, StringRef name)
       : dialect(dialect), interfaceMap(std::move(interfaceMap)),
         hasTraitFn(std::move(hasTrait)),
         walkImmediateSubElementsFn(walkImmediateSubElementsFn),
         replaceImmediateSubElementsFn(replaceImmediateSubElementsFn),
-        typeID(typeID) {}
+        typeID(typeID), name(name) {}
 
   /// Give StorageUserBase access to the mutable lookup.
   template <typename ConcreteT, typename BaseT, typename StorageT,
@@ -139,6 +148,9 @@ class AbstractType {
 
   /// The unique identifier of the derived Type class.
   const TypeID typeID;
+
+  /// The type name.
+  const StringRef name;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/TableGen/AttrOrTypeDef.h b/mlir/include/mlir/TableGen/AttrOrTypeDef.h
index bcf7b6dce00dcd4..61f896067353879 100644
--- a/mlir/include/mlir/TableGen/AttrOrTypeDef.h
+++ b/mlir/include/mlir/TableGen/AttrOrTypeDef.h
@@ -184,6 +184,9 @@ class AttrOrTypeDef {
   /// supposed to auto-generate them.
   std::optional<StringRef> getMnemonic() const;
 
+  /// Get the type name.
+  StringRef getTypeName() const;
+
   /// Returns if the attribute or type has a custom assembly format implemented
   /// in C++. Corresponds to the `hasCustomAssemblyFormat` field.
   bool hasCustomAssemblyFormat() const;
diff --git a/mlir/lib/IR/ExtensibleDialect.cpp b/mlir/lib/IR/ExtensibleDialect.cpp
index 2225a8f2d1b9185..c828f26aa77b665 100644
--- a/mlir/lib/IR/ExtensibleDialect.cpp
+++ b/mlir/lib/IR/ExtensibleDialect.cpp
@@ -407,10 +407,14 @@ void ExtensibleDialect::registerDynamicType(
   assert(registered &&
          "Trying to create a new dynamic type with an existing name");
 
+  MLIRContext *ctx = getContext();
+  auto nameAttr =
+      StringAttr::get(ctx, getNamespace() + "." + typePtr->getName());
+
   auto abstractType = AbstractType::get(
       *dialect, DynamicAttr::getInterfaceMap(), DynamicType::getHasTraitFn(),
       DynamicType::getWalkImmediateSubElementsFn(),
-      DynamicType::getReplaceImmediateSubElementsFn(), typeID);
+      DynamicType::getReplaceImmediateSubElementsFn(), typeID, nameAttr);
 
   /// Add the type to the dialect and the type uniquer.
   addType(typeID, std::move(abstractType));
diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index e5a397c9d65c1ab..67aa5fbec0b6564 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -212,6 +212,9 @@ class MLIRContextImpl {
   DenseMap<TypeID, AbstractType *> registeredTypes;
   StorageUniquer typeUniquer;
 
+  /// This is a mapping from type name to the abstract type describing it.
+  llvm::StringMap<AbstractType *> nameToType;
+
   /// Cached Type Instances.
   Float8E5M2Type f8E5M2Ty;
   Float8E4M3FNType f8E4M3FNTy;
@@ -236,6 +239,10 @@ class MLIRContextImpl {
   DenseMap<TypeID, AbstractAttribute *> registeredAttributes;
   StorageUniquer attributeUniquer;
 
+  /// This is a mapping from attribute name to the abstract attribute describing
+  /// it.
+  llvm::StringMap<AbstractAttribute *> nameToAttribute;
+
   /// Cached Attribute Instances.
   BoolAttr falseAttr, trueAttr;
   UnitAttr unitAttr;
@@ -697,6 +704,9 @@ void Dialect::addType(TypeID typeID, AbstractType &&typeInfo) {
           AbstractType(std::move(typeInfo));
   if (!impl.registeredTypes.insert({typeID, newInfo}).second)
     llvm::report_fatal_error("Dialect Type already registered.");
+  if (!impl.nameToType.insert({newInfo->getName(), newInfo}).second)
+    llvm::report_fatal_error("Dialect Type with name " + newInfo->getName() +
+                             " already registered.");
 }
 
 void Dialect::addAttribute(TypeID typeID, AbstractAttribute &&attrInfo) {
@@ -864,8 +874,8 @@ void OperationName::UnregisteredOpModel::copyProperties(OpaqueProperties lhs,
                                                         OpaqueProperties rhs) {
   *lhs.as<Attribute *>() = *rhs.as<Attribute *>();
 }
-bool OperationName::UnregisteredOpModel::compareProperties(OpaqueProperties lhs,
-                                                        OpaqueProperties rhs) {
+bool OperationName::UnregisteredOpModel::compareProperties(
+    OpaqueProperties lhs, OpaqueProperties rhs) {
   return *lhs.as<Attribute *>() == *rhs.as<Attribute *>();
 }
 llvm::hash_code
@@ -945,6 +955,16 @@ AbstractType *AbstractType::lookupMutable(TypeID typeID, MLIRContext *context) {
   return impl.registeredTypes.lookup(typeID);
 }
 
+std::optional<std::reference_wrapper<const AbstractType>>
+AbstractType::lookup(StringRef name, MLIRContext *context) {
+  MLIRContextImpl &impl = context->getImpl();
+  const AbstractType *type = impl.nameToType.lookup(name);
+
+  if (!type)
+    return std::nullopt;
+  return {*type};
+}
+
 //===----------------------------------------------------------------------===//
 // Type uniquing
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/TableGen/AttrOrTypeDef.cpp b/mlir/lib/TableGen/AttrOrTypeDef.cpp
index 56c96ffd159cfd6..04c5c6301a46d73 100644
--- a/mlir/lib/TableGen/AttrOrTypeDef.cpp
+++ b/mlir/lib/TableGen/AttrOrTypeDef.cpp
@@ -168,6 +168,10 @@ std::optional<StringRef> AttrOrTypeDef::getMnemonic() const {
   return def->getValueAsOptionalString("mnemonic");
 }
 
+StringRef AttrOrTypeDef::getTypeName() const {
+  return def->getValueAsString("typeName");
+}
+
 bool AttrOrTypeDef::hasCustomAssemblyFormat() const {
   return def->getValueAsBit("hasCustomAssemblyFormat");
 }
diff --git a/mlir/test/lib/Dialect/Test/TestTypes.h b/mlir/test/lib/Dialect/Test/TestTypes.h
index 0ce86dd70ab9048..e9cb581c9f37455 100644
--- a/mlir/test/lib/Dialect/Test/TestTypes.h
+++ b/mlir/test/lib/Dialect/Test/TestTypes.h
@@ -132,6 +132,8 @@ class TestRecursiveType
 public:
   using Base::Base;
 
+  static constexpr ::mlir::StringRef getTypeName() { return "test.recursive"; }
+
   static TestRecursiveType get(::mlir::MLIRContext *ctx,
                                ::llvm::StringRef name) {
     return Base::get(ctx, name);
diff --git a/mlir/test/mlir-tblgen/op-decl-and-defs.td b/mlir/test/mlir-tblgen/op-decl-and-defs.td
index 85d68cc42ccbd70..ca133fafdcb5768 100644
--- a/mlir/test/mlir-tblgen/op-decl-and-defs.td
+++ b/mlir/test/mlir-tblgen/op-decl-and-defs.td
@@ -358,7 +358,9 @@ def Test_Dialect2 : Dialect {
   let name = "test";
   let cppNamespace = "::mlir::dialect2";
 }
-def TestDialect2Type : TypeDef<Test_Dialect2, "Dialect2Type">;
+def TestDialect2Type : TypeDef<Test_Dialect2, "Dialect2Type"> {
+  let typeName = "test.type";
+}
 
 def NS_ResultWithDialectTypeOp : NS_Op<"op_with_dialect_type", []> {
   let results = (outs TestDialect2Type);
diff --git a/mlir/test/mlir-tblgen/typedefs.td b/mlir/test/mlir-tblgen/typedefs.td
index 51006635a75a4ae..705da4e41b78b77 100644
--- a/mlir/test/mlir-tblgen/typedefs.td
+++ b/mlir/test/mlir-tblgen/typedefs.td
@@ -45,6 +45,7 @@ class TestType<string name> : TypeDef<Test_Dialect, name> { }
 
 def A_SimpleTypeA : TestType<"SimpleA"> {
 // DECL: class SimpleAType : public ::mlir::Type
+  let typeName = "test.simple_a";
 }
 
 def RTLValueType : Type<CPred<"isRTLValueType($_self)">, "Type"> {
@@ -97,6 +98,7 @@ def C_IndexType : TestType<"Index"> {
 }
 
 def D_SingleParameterType : TestType<"SingleParameter"> {
+  let typeName = "test.d_single_parameter";
   let parameters = (ins
     "int": $num
   );
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index 8889dff7a587242..f4eedb02b72b7a1 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -87,6 +87,8 @@ class DefGen {
   /// Emit top-level declarations: using declarations and any extra class
   /// declarations.
   void emitTopLevelDeclarations();
+  /// Emit the function that returns the type or attribute name.
+  void emitName();
   /// Emit attribute or type builders.
   void emitBuilders();
   /// Emit a verifier for the def.
@@ -180,6 +182,9 @@ DefGen::DefGen(const AttrOrTypeDef &def)
   // Emit builders for defs with parameters
   if (storageCls)
     emitBuilders();
+  // Emit the type name.
+  if (valueType == "Type")
+    emitName();
   // Emit the verifier.
   if (storageCls && def.genVerifyDecl())
     emitVerifier();
@@ -264,6 +269,12 @@ void DefGen::emitTopLevelDeclarations() {
                                         std::move(extraDef));
 }
 
+void DefGen::emitName() {
+  auto *mnemonic = defCls.addStaticMethod<Method::Constexpr>(
+      "::llvm::StringLiteral", "getTypeName");
+  mnemonic->body().indent() << strfmt("return \"{0}\";", def.getTypeName());
+}
+
 void DefGen::emitBuilders() {
   if (!def.skipDefaultBuilders()) {
     emitDefaultBuilder();
diff --git a/mlir/unittests/IR/TypeTest.cpp b/mlir/unittests/IR/TypeTest.cpp
index 1bb9d077d8ed596..e600fed25b5db08 100644
--- a/mlir/unittests/IR/TypeTest.cpp
+++ b/mlir/unittests/IR/TypeTest.cpp
@@ -19,6 +19,9 @@ struct LeafType;
 
 struct MiddleType : Type::TypeBase<MiddleType, Type, TypeStorage> {
   using Base::Base;
+
+  static constexpr StringRef getTypeName() { return "test.middle"; }
+
   static bool classof(Type ty) {
     return ty.getTypeID() == TypeID::get<LeafType>() || Base::classof(ty);
   }
@@ -26,6 +29,8 @@ struct MiddleType : Type::TypeBase<MiddleType, Type, TypeStorage> {
 
 struct LeafType : Type::TypeBase<LeafType, MiddleType, TypeStorage> {
   using Base::Base;
+
+  static constexpr StringRef getTypeName() { return "test.leaf"; }
 };
 
 struct FakeDialect : Dialect {
diff --git a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
index dcb7d9684bb358b..dd212cc8015ee7a 100644
--- a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
+++ b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
@@ -83,6 +83,8 @@ struct SingleQueryType
 
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "test.single_query"; }
+
   static SingleQueryType get(MLIRContext *ctx) { return Base::get(ctx); }
 
   unsigned getTypeSizeInBits(const DataLayout &layout,
@@ -131,6 +133,8 @@ struct TypeNoLayout : public Type::TypeBase<TypeNoLayout, Type, TypeStorage> {
 
   using Base::Base;
 
+  static constexpr StringRef getTypeName() { return "test.no_layout"; }
+
   static TypeNoLayout get(MLIRContext *ctx) { return Base::get(ctx); }
 };
 

>From 3f3f62a0cb38a2e40330a9aa80c327395812d6eb Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Mon, 23 Oct 2023 18:17:52 +0100
Subject: [PATCH 02/16] Add names to attributes too

---
 mlir/include/mlir/Dialect/DLTI/DLTI.h           |  8 ++++++++
 .../mlir/Dialect/SPIRV/IR/SPIRVAttributes.h     |  6 ++++++
 mlir/include/mlir/IR/AttrTypeBase.td            |  9 ++++++---
 mlir/include/mlir/IR/AttributeSupport.h         | 16 +++++++++++-----
 mlir/include/mlir/IR/BuiltinAttributes.h        |  2 ++
 mlir/include/mlir/IR/BuiltinAttributes.td       | 17 +++++++++++++++++
 .../mlir/IR/BuiltinLocationAttributes.td        |  6 ++++++
 mlir/include/mlir/IR/TypeSupport.h              |  2 +-
 mlir/include/mlir/TableGen/AttrOrTypeDef.h      |  3 +++
 mlir/lib/IR/ExtensibleDialect.cpp               |  6 +++++-
 mlir/lib/TableGen/AttrOrTypeDef.cpp             |  4 ++++
 mlir/test/mlir-tblgen/attrdefs.td               |  5 +++++
 mlir/test/mlir-tblgen/op-attribute.td           |  1 +
 mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp     |  8 ++++----
 .../Interfaces/DataLayoutInterfacesTest.cpp     |  5 +++++
 15 files changed, 84 insertions(+), 14 deletions(-)

diff --git a/mlir/include/mlir/Dialect/DLTI/DLTI.h b/mlir/include/mlir/Dialect/DLTI/DLTI.h
index cf78b2312c24609..6dabbaa7ae1ad36 100644
--- a/mlir/include/mlir/Dialect/DLTI/DLTI.h
+++ b/mlir/include/mlir/Dialect/DLTI/DLTI.h
@@ -55,6 +55,10 @@ class DataLayoutEntryAttr
 
   /// Prints this attribute.
   void print(AsmPrinter &os) const;
+
+  static constexpr StringRef getAttrName() {
+    return "builtin.data_layout_entry";
+  }
 };
 
 //===----------------------------------------------------------------------===//
@@ -109,6 +113,10 @@ class DataLayoutSpecAttr
 
   /// Prints this attribute.
   void print(AsmPrinter &os) const;
+
+  static constexpr StringRef getAttrName() {
+    return "builtin.data_layout_spec";
+  }
 };
 
 } // namespace mlir
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAttributes.h b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAttributes.h
index 3b914dc4cc82f11..8de961295153b8d 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAttributes.h
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAttributes.h
@@ -79,6 +79,8 @@ class InterfaceVarABIAttr
   static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
                               IntegerAttr descriptorSet, IntegerAttr binding,
                               IntegerAttr storageClass);
+
+  static constexpr StringRef getAttrName() { return "spirv.interface_var_abi"; }
 };
 
 /// An attribute that specifies the SPIR-V (version, capabilities, extensions)
@@ -129,6 +131,8 @@ class VerCapExtAttr
   static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
                               IntegerAttr version, ArrayAttr capabilities,
                               ArrayAttr extensions);
+
+  static constexpr StringRef getAttrName() { return "spirv.ver_cap_ext"; }
 };
 
 /// An attribute that specifies the target version, allowed extensions and
@@ -183,6 +187,8 @@ class TargetEnvAttr
 
   /// Returns the target resource limits.
   ResourceLimitsAttr getResourceLimits() const;
+
+  static constexpr StringRef getAttrName() { return "spirv.target_env"; }
 };
 } // namespace spirv
 } // namespace mlir
diff --git a/mlir/include/mlir/IR/AttrTypeBase.td b/mlir/include/mlir/IR/AttrTypeBase.td
index 89c1e746f01559d..91c9283de8bd415 100644
--- a/mlir/include/mlir/IR/AttrTypeBase.td
+++ b/mlir/include/mlir/IR/AttrTypeBase.td
@@ -264,6 +264,9 @@ class AttrDef<Dialect dialect, string name, list<Trait> traits = [],
   // Make it possible to use such attributes as parameters for other attributes.
   string cppType = dialect.cppNamespace # "::" # cppClassName;
 
+  // The unique attribute name.
+  string attrName = dialect.name # "." # mnemonic;
+
   // The call expression to convert from the storage type to the return
   // type. For example, an enum can be stored as an int but returned as an
   // enum class.
@@ -434,15 +437,15 @@ class AttributeSelfTypeParameter<string desc,
 /// This class defines an attribute that contains an array of elements. The
 /// elements can be any type, but if they are attributes, the nested elements
 /// are parsed and printed using the custom attribute syntax.
-class ArrayOfAttr<Dialect dialect, string attrName, string attrMnemonic,
+class ArrayOfAttr<Dialect dialect, string name, string attrMnemonic,
                   string eltName, list<Trait> traits = []>
-    : AttrDef<dialect, attrName, traits> {
+    : AttrDef<dialect, name, traits> {
   let parameters = (ins OptionalArrayRefParameter<eltName>:$value);
   let mnemonic = attrMnemonic;
   let assemblyFormat = "`[` (`]`) : ($value^ `]`)?";
 
   let returnType = "::llvm::ArrayRef<" # eltName # ">";
-  let constBuilderCall = "$_builder.getAttr<" # attrName # "Attr>($0)";
+  let constBuilderCall = "$_builder.getAttr<" # name # "Attr>($0)";
   let convertFromStorage = "$_self.getValue()";
 
   let extraClassDeclaration = [{
diff --git a/mlir/include/mlir/IR/AttributeSupport.h b/mlir/include/mlir/IR/AttributeSupport.h
index 75ea1ce24753c97..104f5570e3bfb31 100644
--- a/mlir/include/mlir/IR/AttributeSupport.h
+++ b/mlir/include/mlir/IR/AttributeSupport.h
@@ -45,7 +45,7 @@ class AbstractAttribute {
     return AbstractAttribute(dialect, T::getInterfaceMap(), T::getHasTraitFn(),
                              T::getWalkImmediateSubElementsFn(),
                              T::getReplaceImmediateSubElementsFn(),
-                             T::getTypeID());
+                             T::getTypeID(), T::getAttrName());
   }
 
   /// This method is used by Dialect objects to register attributes with
@@ -57,10 +57,10 @@ class AbstractAttribute {
       HasTraitFn &&hasTrait,
       WalkImmediateSubElementsFn walkImmediateSubElementsFn,
       ReplaceImmediateSubElementsFn replaceImmediateSubElementsFn,
-      TypeID typeID) {
+      TypeID typeID, StringRef name) {
     return AbstractAttribute(dialect, std::move(interfaceMap),
                              std::move(hasTrait), walkImmediateSubElementsFn,
-                             replaceImmediateSubElementsFn, typeID);
+                             replaceImmediateSubElementsFn, typeID, name);
   }
 
   /// Return the dialect this attribute was registered to.
@@ -102,17 +102,20 @@ class AbstractAttribute {
   /// Return the unique identifier representing the concrete attribute class.
   TypeID getTypeID() const { return typeID; }
 
+  /// Return the unique name representing the type.
+  StringRef getName() const { return name; }
+
 private:
   AbstractAttribute(Dialect &dialect, detail::InterfaceMap &&interfaceMap,
                     HasTraitFn &&hasTraitFn,
                     WalkImmediateSubElementsFn walkImmediateSubElementsFn,
                     ReplaceImmediateSubElementsFn replaceImmediateSubElementsFn,
-                    TypeID typeID)
+                    TypeID typeID, StringRef name)
       : dialect(dialect), interfaceMap(std::move(interfaceMap)),
         hasTraitFn(std::move(hasTraitFn)),
         walkImmediateSubElementsFn(walkImmediateSubElementsFn),
         replaceImmediateSubElementsFn(replaceImmediateSubElementsFn),
-        typeID(typeID) {}
+        typeID(typeID), name(name) {}
 
   /// Give StorageUserBase access to the mutable lookup.
   template <typename ConcreteT, typename BaseT, typename StorageT,
@@ -141,6 +144,9 @@ class AbstractAttribute {
 
   /// The unique identifier of the derived Attribute class.
   const TypeID typeID;
+
+  /// The unique name of this type.
+  const StringRef name;
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/IR/BuiltinAttributes.h b/mlir/include/mlir/IR/BuiltinAttributes.h
index c8161604aad3503..c45473ceccfe371 100644
--- a/mlir/include/mlir/IR/BuiltinAttributes.h
+++ b/mlir/include/mlir/IR/BuiltinAttributes.h
@@ -1044,6 +1044,8 @@ class DistinctAttr
   /// Creates a distinct attribute that associates a referenced attribute with a
   /// unique identifier.
   static DistinctAttr create(Attribute referencedAttr);
+
+  static constexpr StringRef getAttrName() { return "builtin.distinct"; }
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td
index 390231da662e2d4..f4a42ccf736bfea 100644
--- a/mlir/include/mlir/IR/BuiltinAttributes.td
+++ b/mlir/include/mlir/IR/BuiltinAttributes.td
@@ -64,6 +64,7 @@ def Builtin_AffineMapAttr : Builtin_Attr<"AffineMap", [
     AffineMap getAffineMap() const { return getValue(); }
   }];
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.affine_map";
 }
 
 //===----------------------------------------------------------------------===//
@@ -134,6 +135,7 @@ def Builtin_ArrayAttr : Builtin_Attr<"Array"> {
       });
     }
   }];
+  let attrName = "builtin.array";
 }
 
 //===----------------------------------------------------------------------===//
@@ -211,6 +213,7 @@ def Builtin_DenseArray : Builtin_Attr<"DenseArray"> {
     /// Return true if there are no elements in the dense array.
     bool empty() const { return !size(); }
   }];
+  let attrName = "builtin.dense_array";
 }
 
 //===----------------------------------------------------------------------===//
@@ -352,6 +355,7 @@ def Builtin_DenseIntOrFPElementsAttr : Builtin_Attr<
   let genAccessors = 0;
   let genStorageClass = 0;
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.dense_int_or_fp_elements";
 }
 
 //===----------------------------------------------------------------------===//
@@ -423,6 +427,7 @@ def Builtin_DenseStringElementsAttr : Builtin_Attr<
   let genAccessors = 0;
   let genStorageClass = 0;
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.dense_string_elements";
 }
 
 //===----------------------------------------------------------------------===//
@@ -481,6 +486,7 @@ def Builtin_DenseResourceElementsAttr : Builtin_Attr<"DenseResourceElements", [
   ];
 
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.dense_resource_elements";
 }
 
 //===----------------------------------------------------------------------===//
@@ -579,6 +585,7 @@ def Builtin_DictionaryAttr : Builtin_Attr<"Dictionary"> {
   public:
   }];
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.dictionary";
 }
 
 //===----------------------------------------------------------------------===//
@@ -642,6 +649,7 @@ def Builtin_FloatAttr : Builtin_Attr<"Float", [TypedAttrInterface]> {
   }];
   let genVerifyDecl = 1;
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.float";
 }
 
 //===----------------------------------------------------------------------===//
@@ -730,6 +738,7 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer", [TypedAttrInterface]> {
   }];
   let genVerifyDecl = 1;
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.integer";
 }
 
 //===----------------------------------------------------------------------===//
@@ -759,6 +768,7 @@ def Builtin_IntegerSetAttr : Builtin_Attr<"IntegerSet"> {
   ];
   let extraClassDeclaration = "using ValueType = IntegerSet;";
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.integer_set";
 }
 
 //===----------------------------------------------------------------------===//
@@ -796,6 +806,7 @@ def Builtin_OpaqueAttr : Builtin_Attr<"Opaque", [TypedAttrInterface]> {
   ];
   let genVerifyDecl = 1;
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.opaque";
 }
 
 //===----------------------------------------------------------------------===//
@@ -952,6 +963,7 @@ def Builtin_SparseElementsAttr : Builtin_Attr<
   }];
   let genVerifyDecl = 1;
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.sparse_elements";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1005,6 +1017,7 @@ def StridedLayoutAttr : Builtin_Attr<"StridedLayout",
     /// Print the attribute to the given output stream.
     void print(raw_ostream &os) const;
   }];
+  let attrName = "builtin.strided_elements";
 }
 
 
@@ -1087,6 +1100,7 @@ def Builtin_StringAttr : Builtin_Attr<"String", [TypedAttrInterface]> {
   }];
   let genStorageClass = 0;
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.string";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1153,6 +1167,7 @@ def Builtin_SymbolRefAttr : Builtin_Attr<"SymbolRef"> {
     StringAttr getLeafReference() const;
   }];
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.symbol_ref";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1186,6 +1201,7 @@ def Builtin_TypeAttr : Builtin_Attr<"Type"> {
   ];
   let extraClassDeclaration = "using ValueType = Type;";
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.type";
 }
 
 //===----------------------------------------------------------------------===//
@@ -1227,6 +1243,7 @@ def Builtin_UnitAttr : Builtin_Attr<"Unit"> {
   let extraClassDeclaration = [{
     static UnitAttr get(MLIRContext *context);
   }];
+  let attrName = "builtin.unit";
 }
 
 #endif // BUILTIN_ATTRIBUTES
diff --git a/mlir/include/mlir/IR/BuiltinLocationAttributes.td b/mlir/include/mlir/IR/BuiltinLocationAttributes.td
index 3c9d2c57f4d1bd5..e1656f268795d01 100644
--- a/mlir/include/mlir/IR/BuiltinLocationAttributes.td
+++ b/mlir/include/mlir/IR/BuiltinLocationAttributes.td
@@ -56,6 +56,7 @@ def CallSiteLoc : Builtin_LocationAttr<"CallSiteLoc"> {
                                         "ArrayRef<Location>":$frames)>
   ];
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.call_site_loc";
 }
 
 //===----------------------------------------------------------------------===//
@@ -98,6 +99,7 @@ def FileLineColLoc : Builtin_LocationAttr<"FileLineColLoc"> {
     }]>
   ];
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.file_line_loc";
 }
 
 //===----------------------------------------------------------------------===//
@@ -137,6 +139,7 @@ def FusedLoc : Builtin_LocationAttr<"FusedLoc"> {
       return get(locs, Attribute(), context);
     }
   }];
+  let attrName = "builtin.fused_loc";
 }
 
 //===----------------------------------------------------------------------===//
@@ -174,6 +177,7 @@ def NameLoc : Builtin_LocationAttr<"NameLoc"> {
     }]>
   ];
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.name_loc";
 }
 
 //===----------------------------------------------------------------------===//
@@ -239,6 +243,7 @@ def OpaqueLoc : Builtin_LocationAttr<"OpaqueLoc"> {
     }
   }];
   let skipDefaultBuilders = 1;
+  let attrName = "builtin.opaque_loc";
 }
 
 //===----------------------------------------------------------------------===//
@@ -268,6 +273,7 @@ def UnknownLoc : Builtin_LocationAttr<"UnknownLoc"> {
   let extraClassDeclaration = [{
     static UnknownLoc get(MLIRContext *context);
   }];
+  let attrName = "builtin.unknown_loc";
 }
 
 #endif // BUILTIN_LOCATION_ATTRIBUTES_TD
diff --git a/mlir/include/mlir/IR/TypeSupport.h b/mlir/include/mlir/IR/TypeSupport.h
index 18386a5ced2f801..f4c840bf4ab5d42 100644
--- a/mlir/include/mlir/IR/TypeSupport.h
+++ b/mlir/include/mlir/IR/TypeSupport.h
@@ -149,7 +149,7 @@ class AbstractType {
   /// The unique identifier of the derived Type class.
   const TypeID typeID;
 
-  /// The type name.
+  /// The unique name of this type.
   const StringRef name;
 };
 
diff --git a/mlir/include/mlir/TableGen/AttrOrTypeDef.h b/mlir/include/mlir/TableGen/AttrOrTypeDef.h
index 61f896067353879..f62621966bac8c3 100644
--- a/mlir/include/mlir/TableGen/AttrOrTypeDef.h
+++ b/mlir/include/mlir/TableGen/AttrOrTypeDef.h
@@ -187,6 +187,9 @@ class AttrOrTypeDef {
   /// Get the type name.
   StringRef getTypeName() const;
 
+  /// Get the attribute name.
+  StringRef getAttrName() const;
+
   /// Returns if the attribute or type has a custom assembly format implemented
   /// in C++. Corresponds to the `hasCustomAssemblyFormat` field.
   bool hasCustomAssemblyFormat() const;
diff --git a/mlir/lib/IR/ExtensibleDialect.cpp b/mlir/lib/IR/ExtensibleDialect.cpp
index c828f26aa77b665..c2e3e9c951b0a79 100644
--- a/mlir/lib/IR/ExtensibleDialect.cpp
+++ b/mlir/lib/IR/ExtensibleDialect.cpp
@@ -441,10 +441,14 @@ void ExtensibleDialect::registerDynamicAttr(
   assert(registered &&
          "Trying to create a new dynamic attribute with an existing name");
 
+  MLIRContext *ctx = getContext();
+  auto nameAttr =
+      StringAttr::get(ctx, getNamespace() + "." + attrPtr->getName());
+
   auto abstractAttr = AbstractAttribute::get(
       *dialect, DynamicAttr::getInterfaceMap(), DynamicAttr::getHasTraitFn(),
       DynamicAttr::getWalkImmediateSubElementsFn(),
-      DynamicAttr::getReplaceImmediateSubElementsFn(), typeID);
+      DynamicAttr::getReplaceImmediateSubElementsFn(), typeID, nameAttr);
 
   /// Add the type to the dialect and the type uniquer.
   addAttribute(typeID, std::move(abstractAttr));
diff --git a/mlir/lib/TableGen/AttrOrTypeDef.cpp b/mlir/lib/TableGen/AttrOrTypeDef.cpp
index 04c5c6301a46d73..229dd4438935abd 100644
--- a/mlir/lib/TableGen/AttrOrTypeDef.cpp
+++ b/mlir/lib/TableGen/AttrOrTypeDef.cpp
@@ -168,6 +168,10 @@ std::optional<StringRef> AttrOrTypeDef::getMnemonic() const {
   return def->getValueAsOptionalString("mnemonic");
 }
 
+StringRef AttrOrTypeDef::getAttrName() const {
+  return def->getValueAsString("attrName");
+}
+
 StringRef AttrOrTypeDef::getTypeName() const {
   return def->getValueAsString("typeName");
 }
diff --git a/mlir/test/mlir-tblgen/attrdefs.td b/mlir/test/mlir-tblgen/attrdefs.td
index 0fb6958799b2ecf..5683f343c6bbc8e 100644
--- a/mlir/test/mlir-tblgen/attrdefs.td
+++ b/mlir/test/mlir-tblgen/attrdefs.td
@@ -63,6 +63,7 @@ def C_IndexAttr : TestAttr<"Index"> {
 }
 
 def A_SimpleAttrA : TestAttr<"SimpleA"> {
+  let attrName = "test.simple";
 // DECL: class SimpleAAttr : public ::mlir::Attribute
 }
 
@@ -123,6 +124,7 @@ def D_SingleParameterAttr : TestAttr<"SingleParameter"> {
     ins
     "int": $num
   );
+  let attrName = "test.single_parameter";
 // DECL-LABEL: struct SingleParameterAttrStorage;
 // DECL-LABEL: class SingleParameterAttr
 // DECL-SAME:  detail::SingleParameterAttrStorage
@@ -130,6 +132,7 @@ def D_SingleParameterAttr : TestAttr<"SingleParameter"> {
 
 def F_ParamWithAccessorTypeAttr : TestAttr<"ParamWithAccessorType"> {
   let parameters = (ins AttrParameter<"std::string", "", "StringRef">:$param);
+  let attrName = "test.param_with_accessor_type";
 }
 
 // DECL-LABEL: class ParamWithAccessorTypeAttr
@@ -142,6 +145,7 @@ def G_BuilderWithReturnTypeAttr : TestAttr<"BuilderWithReturnType"> {
   let parameters = (ins "int":$a);
   let genVerifyDecl = 1;
   let builders = [AttrBuilder<(ins), [{ return {}; }], "::mlir::Attribute">];
+  let attrName = "test.builder_with_return_type";
 }
 
 // DECL-LABEL: class BuilderWithReturnTypeAttr
@@ -158,6 +162,7 @@ def H_TestExtraClassAttr : TestAttr<"TestExtraClass"> {
       return i+1;
     }
   }];
+  let attrName = "test.test_extra_class";
 }
 
 // DECL-LABEL: TestExtraClassAttr : public ::mlir::Attribute
diff --git a/mlir/test/mlir-tblgen/op-attribute.td b/mlir/test/mlir-tblgen/op-attribute.td
index f81fc3df857ec26..07636f53c1e15ce 100644
--- a/mlir/test/mlir-tblgen/op-attribute.td
+++ b/mlir/test/mlir-tblgen/op-attribute.td
@@ -22,6 +22,7 @@ def SomeAttr : Attr<CPred<"some-condition">, "some attribute kind"> {
 }
 
 def SomeAttrDef : AttrDef<Test_Dialect, "SomeAttr"> {
+  let attrName = "test.some_attr";
 }
 
 
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index f4eedb02b72b7a1..32687d79ad277a0 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -183,8 +183,7 @@ DefGen::DefGen(const AttrOrTypeDef &def)
   if (storageCls)
     emitBuilders();
   // Emit the type name.
-  if (valueType == "Type")
-    emitName();
+  emitName();
   // Emit the verifier.
   if (storageCls && def.genVerifyDecl())
     emitVerifier();
@@ -271,8 +270,9 @@ void DefGen::emitTopLevelDeclarations() {
 
 void DefGen::emitName() {
   auto *mnemonic = defCls.addStaticMethod<Method::Constexpr>(
-      "::llvm::StringLiteral", "getTypeName");
-  mnemonic->body().indent() << strfmt("return \"{0}\";", def.getTypeName());
+      "::llvm::StringLiteral", "get" + defType + "Name");
+  StringRef name = defType == "Type" ? def.getTypeName() : def.getAttrName();
+  mnemonic->body().indent() << strfmt("return \"{0}\";", name);
 }
 
 void DefGen::emitBuilders() {
diff --git a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
index dd212cc8015ee7a..e4a314a7725abfa 100644
--- a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
+++ b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
@@ -56,6 +56,11 @@ struct CustomDataLayoutSpec
   MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(CustomDataLayoutSpec)
 
   using Base::Base;
+
+  static constexpr StringRef getAttrName() {
+    return "test.custom_data_layout_spec";
+  }
+
   static CustomDataLayoutSpec get(MLIRContext *ctx,
                                   ArrayRef<DataLayoutEntryInterface> entries) {
     return Base::get(ctx, entries);

>From 5d7f5adc5c8d46bba50f1987f21cb41df67d6844 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Tue, 24 Oct 2023 17:58:52 +0100
Subject: [PATCH 03/16] Fix unwnated change

---
 mlir/include/mlir/IR/BuiltinTypes.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/include/mlir/IR/BuiltinTypes.td b/mlir/include/mlir/IR/BuiltinTypes.td
index 208287be789b6b4..1d7772810ae6e8f 100644
--- a/mlir/include/mlir/IR/BuiltinTypes.td
+++ b/mlir/include/mlir/IR/BuiltinTypes.td
@@ -537,7 +537,7 @@ def Builtin_MemRef : Builtin_Type<"MemRef", "memref", [
     %B = alloc() : memref<16x32x64xf32>
     // Remove rank info
     %A_u = memref_cast %A : memref<16x32xf32> -> memref<*xf32>
-    %B_u = memref_cast %B : memr>f<16x32x64xf32> -> memref<*xf32>
+    %B_u = memref_cast %B : memref<16x32x64xf32> -> memref<*xf32>
     // call same function with dynamic ranks
     call @helper(%A_u) : (memref<*xf32>)->()
     call @helper(%B_u) : (memref<*xf32>)->()

>From 448d0386f33e804284daefec5458368987c662e8 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Tue, 24 Oct 2023 18:30:08 +0100
Subject: [PATCH 04/16] Cleanup AttrOrTypeDef

---
 mlir/include/mlir/TableGen/AttrOrTypeDef.h  | 14 ++++++------
 mlir/lib/TableGen/AttrOrTypeDef.cpp         | 24 ++++++++++++++-------
 mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp | 10 +++++++--
 3 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/mlir/include/mlir/TableGen/AttrOrTypeDef.h b/mlir/include/mlir/TableGen/AttrOrTypeDef.h
index f62621966bac8c3..19c3a9183ec2cfb 100644
--- a/mlir/include/mlir/TableGen/AttrOrTypeDef.h
+++ b/mlir/include/mlir/TableGen/AttrOrTypeDef.h
@@ -184,12 +184,6 @@ class AttrOrTypeDef {
   /// supposed to auto-generate them.
   std::optional<StringRef> getMnemonic() const;
 
-  /// Get the type name.
-  StringRef getTypeName() const;
-
-  /// Get the attribute name.
-  StringRef getAttrName() const;
-
   /// Returns if the attribute or type has a custom assembly format implemented
   /// in C++. Corresponds to the `hasCustomAssemblyFormat` field.
   bool hasCustomAssemblyFormat() const;
@@ -263,6 +257,9 @@ class AttrDef : public AttrOrTypeDef {
   std::optional<StringRef> getTypeBuilder() const;
 
   static bool classof(const AttrOrTypeDef *def);
+
+  /// Get the unique attribute name "dialect.attrname".
+  StringRef getAttrName() const;
 };
 
 //===----------------------------------------------------------------------===//
@@ -273,6 +270,11 @@ class AttrDef : public AttrOrTypeDef {
 class TypeDef : public AttrOrTypeDef {
 public:
   using AttrOrTypeDef::AttrOrTypeDef;
+
+  static bool classof(const AttrOrTypeDef *def);
+
+  /// Get the unique type name "dialect.typename".
+  StringRef getTypeName() const;
 };
 
 } // namespace tblgen
diff --git a/mlir/lib/TableGen/AttrOrTypeDef.cpp b/mlir/lib/TableGen/AttrOrTypeDef.cpp
index 229dd4438935abd..c9dbb3bc76b1fa0 100644
--- a/mlir/lib/TableGen/AttrOrTypeDef.cpp
+++ b/mlir/lib/TableGen/AttrOrTypeDef.cpp
@@ -168,14 +168,6 @@ std::optional<StringRef> AttrOrTypeDef::getMnemonic() const {
   return def->getValueAsOptionalString("mnemonic");
 }
 
-StringRef AttrOrTypeDef::getAttrName() const {
-  return def->getValueAsString("attrName");
-}
-
-StringRef AttrOrTypeDef::getTypeName() const {
-  return def->getValueAsString("typeName");
-}
-
 bool AttrOrTypeDef::hasCustomAssemblyFormat() const {
   return def->getValueAsBit("hasCustomAssemblyFormat");
 }
@@ -228,6 +220,22 @@ bool AttrDef::classof(const AttrOrTypeDef *def) {
   return def->getDef()->isSubClassOf("AttrDef");
 }
 
+StringRef AttrDef::getAttrName() const {
+  return def->getValueAsString("attrName");
+}
+
+//===----------------------------------------------------------------------===//
+// TypeDef
+//===----------------------------------------------------------------------===//
+
+bool TypeDef::classof(const AttrOrTypeDef *def) {
+  return def->getDef()->isSubClassOf("TypeDef");
+}
+
+StringRef TypeDef::getTypeName() const {
+  return def->getValueAsString("typeName");
+}
+
 //===----------------------------------------------------------------------===//
 // AttrOrTypeParameter
 //===----------------------------------------------------------------------===//
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index 32687d79ad277a0..a0b4c549b7b3493 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -271,8 +271,14 @@ void DefGen::emitTopLevelDeclarations() {
 void DefGen::emitName() {
   auto *mnemonic = defCls.addStaticMethod<Method::Constexpr>(
       "::llvm::StringLiteral", "get" + defType + "Name");
-  StringRef name = defType == "Type" ? def.getTypeName() : def.getAttrName();
-  mnemonic->body().indent() << strfmt("return \"{0}\";", name);
+  if (auto *attrDef = dyn_cast<AttrDef>(&def)) {
+    mnemonic->body().indent()
+        << strfmt("return \"{0}\";", attrDef->getAttrName());
+    return;
+  }
+  auto *typeDef = cast<TypeDef>(&def);
+  mnemonic->body().indent()
+      << strfmt("return \"{0}\";", typeDef->getTypeName());
 }
 
 void DefGen::emitBuilders() {

>From d2a4bfbe36f3ec69ba0e2acc811df3e38255c762 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Tue, 24 Oct 2023 19:02:04 +0100
Subject: [PATCH 05/16] Add comment

---
 mlir/lib/IR/ExtensibleDialect.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/mlir/lib/IR/ExtensibleDialect.cpp b/mlir/lib/IR/ExtensibleDialect.cpp
index c2e3e9c951b0a79..ca7b0e1cbb6b39b 100644
--- a/mlir/lib/IR/ExtensibleDialect.cpp
+++ b/mlir/lib/IR/ExtensibleDialect.cpp
@@ -407,6 +407,8 @@ void ExtensibleDialect::registerDynamicType(
   assert(registered &&
          "Trying to create a new dynamic type with an existing name");
 
+  // The StringAttr allocates the type name StringRef for the duration of the
+  // MLIR context.
   MLIRContext *ctx = getContext();
   auto nameAttr =
       StringAttr::get(ctx, getNamespace() + "." + typePtr->getName());
@@ -441,6 +443,8 @@ void ExtensibleDialect::registerDynamicAttr(
   assert(registered &&
          "Trying to create a new dynamic attribute with an existing name");
 
+  // The StringAttr allocates the attribute name StringRef for the duration of
+  // the MLIR context.
   MLIRContext *ctx = getContext();
   auto nameAttr =
       StringAttr::get(ctx, getNamespace() + "." + attrPtr->getName());

>From a00d2b9e165c95a6a43adb164e0a8464f253c53b Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Tue, 24 Oct 2023 19:06:50 +0100
Subject: [PATCH 06/16] Insert attribute name to context

---
 mlir/lib/IR/MLIRContext.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index 67aa5fbec0b6564..d34cb2c0028bd25 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -706,7 +706,7 @@ void Dialect::addType(TypeID typeID, AbstractType &&typeInfo) {
     llvm::report_fatal_error("Dialect Type already registered.");
   if (!impl.nameToType.insert({newInfo->getName(), newInfo}).second)
     llvm::report_fatal_error("Dialect Type with name " + newInfo->getName() +
-                             " already registered.");
+                             " is already registered.");
 }
 
 void Dialect::addAttribute(TypeID typeID, AbstractAttribute &&attrInfo) {
@@ -719,6 +719,9 @@ void Dialect::addAttribute(TypeID typeID, AbstractAttribute &&attrInfo) {
           AbstractAttribute(std::move(attrInfo));
   if (!impl.registeredAttributes.insert({typeID, newInfo}).second)
     llvm::report_fatal_error("Dialect Attribute already registered.");
+  if (!impl.nameToAttribute.insert({newInfo->getName(), newInfo}).second)
+    llvm::report_fatal_error("Dialect Attribute with name " +
+                             newInfo->getName() + " is already registered.");
 }
 
 //===----------------------------------------------------------------------===//

>From cbe7c6a0a03c74459ed368cdf9df4d0db67de4b7 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Tue, 14 Nov 2023 03:26:28 +0000
Subject: [PATCH 07/16] Add missing name in toy tutorial type

---
 mlir/examples/toy/Ch7/include/toy/Dialect.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mlir/examples/toy/Ch7/include/toy/Dialect.h b/mlir/examples/toy/Ch7/include/toy/Dialect.h
index bbcc6cd7f0b1843..fc7bbe3b9b922b1 100644
--- a/mlir/examples/toy/Ch7/include/toy/Dialect.h
+++ b/mlir/examples/toy/Ch7/include/toy/Dialect.h
@@ -72,6 +72,9 @@ class StructType : public mlir::Type::TypeBase<StructType, mlir::Type,
 
   /// Returns the number of element type held by this struct.
   size_t getNumElementTypes() { return getElementTypes().size(); }
+
+  /// Returns the name of this struct type.
+  static constexpr StringRef getTypeName() { return "toy.struct"; }
 };
 } // namespace toy
 } // namespace mlir

>From 8c3a5cd9e1bcecf03717219403d66984e7888b8f Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Tue, 14 Nov 2023 15:23:20 +0000
Subject: [PATCH 08/16] Make name a parameter of Builtin_Attr

---
 mlir/include/mlir/IR/BuiltinAttributes.td | 60 +++++++++--------------
 1 file changed, 23 insertions(+), 37 deletions(-)

diff --git a/mlir/include/mlir/IR/BuiltinAttributes.td b/mlir/include/mlir/IR/BuiltinAttributes.td
index f4a42ccf736bfea..be9cbec768d7b23 100644
--- a/mlir/include/mlir/IR/BuiltinAttributes.td
+++ b/mlir/include/mlir/IR/BuiltinAttributes.td
@@ -25,17 +25,18 @@ include "mlir/IR/OpAsmInterface.td"
 // to this file instead.
 
 // Base class for Builtin dialect attributes.
-class Builtin_Attr<string name, list<Trait> traits = [],
+class Builtin_Attr<string name, string attrMnemonic, list<Trait> traits = [],
                    string baseCppClass = "::mlir::Attribute">
     : AttrDef<Builtin_Dialect, name, traits, baseCppClass> {
   let mnemonic = ?;
+  let attrName = "builtin." # attrMnemonic;
 }
 
 //===----------------------------------------------------------------------===//
 // AffineMapAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_AffineMapAttr : Builtin_Attr<"AffineMap", [
+def Builtin_AffineMapAttr : Builtin_Attr<"AffineMap", "affine_map", [
     MemRefLayoutAttrInterface
   ]> {
   let summary = "An Attribute containing an AffineMap object";
@@ -64,14 +65,13 @@ def Builtin_AffineMapAttr : Builtin_Attr<"AffineMap", [
     AffineMap getAffineMap() const { return getValue(); }
   }];
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.affine_map";
 }
 
 //===----------------------------------------------------------------------===//
 // ArrayAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_ArrayAttr : Builtin_Attr<"Array"> {
+def Builtin_ArrayAttr : Builtin_Attr<"Array", "array"> {
   let summary = "A collection of other Attribute values";
   let description = [{
     Syntax:
@@ -135,7 +135,6 @@ def Builtin_ArrayAttr : Builtin_Attr<"Array"> {
       });
     }
   }];
-  let attrName = "builtin.array";
 }
 
 //===----------------------------------------------------------------------===//
@@ -154,7 +153,7 @@ def Builtin_DenseArrayRawDataParameter : ArrayRefParameter<
   }];
 }
 
-def Builtin_DenseArray : Builtin_Attr<"DenseArray"> {
+def Builtin_DenseArray : Builtin_Attr<"DenseArray", "dense_array"> {
   let summary = "A dense array of integer or floating point elements.";
   let description = [{
     A dense array attribute is an attribute that represents a dense array of
@@ -213,7 +212,6 @@ def Builtin_DenseArray : Builtin_Attr<"DenseArray"> {
     /// Return true if there are no elements in the dense array.
     bool empty() const { return !size(); }
   }];
-  let attrName = "builtin.dense_array";
 }
 
 //===----------------------------------------------------------------------===//
@@ -221,7 +219,7 @@ def Builtin_DenseArray : Builtin_Attr<"DenseArray"> {
 //===----------------------------------------------------------------------===//
 
 def Builtin_DenseIntOrFPElementsAttr : Builtin_Attr<
-    "DenseIntOrFPElements", [ElementsAttrInterface],
+    "DenseIntOrFPElements", "dense_int_or_fp_elements", [ElementsAttrInterface],
     "DenseElementsAttr"
   > {
   let summary = "An Attribute containing a dense multi-dimensional array of "
@@ -355,7 +353,6 @@ def Builtin_DenseIntOrFPElementsAttr : Builtin_Attr<
   let genAccessors = 0;
   let genStorageClass = 0;
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.dense_int_or_fp_elements";
 }
 
 //===----------------------------------------------------------------------===//
@@ -363,7 +360,7 @@ def Builtin_DenseIntOrFPElementsAttr : Builtin_Attr<
 //===----------------------------------------------------------------------===//
 
 def Builtin_DenseStringElementsAttr : Builtin_Attr<
-    "DenseStringElements", [ElementsAttrInterface],
+    "DenseStringElements", "dense_string_elements", [ElementsAttrInterface],
     "DenseElementsAttr"
   > {
   let summary = "An Attribute containing a dense multi-dimensional array of "
@@ -427,16 +424,14 @@ def Builtin_DenseStringElementsAttr : Builtin_Attr<
   let genAccessors = 0;
   let genStorageClass = 0;
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.dense_string_elements";
 }
 
 //===----------------------------------------------------------------------===//
 // DenseResourceElementsAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_DenseResourceElementsAttr : Builtin_Attr<"DenseResourceElements", [
-    ElementsAttrInterface
-  ]> {
+def Builtin_DenseResourceElementsAttr : Builtin_Attr<"DenseResourceElements",
+    "dense_resource_elements", [ElementsAttrInterface]> {
   let summary = "An Attribute containing a dense multi-dimensional array "
                 "backed by a resource";
   let description = [{
@@ -486,14 +481,13 @@ def Builtin_DenseResourceElementsAttr : Builtin_Attr<"DenseResourceElements", [
   ];
 
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.dense_resource_elements";
 }
 
 //===----------------------------------------------------------------------===//
 // DictionaryAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_DictionaryAttr : Builtin_Attr<"Dictionary"> {
+def Builtin_DictionaryAttr : Builtin_Attr<"Dictionary", "dictionary"> {
   let summary = "An dictionary of named Attribute values";
   let description = [{
     Syntax:
@@ -585,14 +579,13 @@ def Builtin_DictionaryAttr : Builtin_Attr<"Dictionary"> {
   public:
   }];
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.dictionary";
 }
 
 //===----------------------------------------------------------------------===//
 // FloatAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_FloatAttr : Builtin_Attr<"Float", [TypedAttrInterface]> {
+def Builtin_FloatAttr : Builtin_Attr<"Float", "float", [TypedAttrInterface]> {
   let summary = "An Attribute containing a floating-point value";
   let description = [{
     Syntax:
@@ -649,14 +642,14 @@ def Builtin_FloatAttr : Builtin_Attr<"Float", [TypedAttrInterface]> {
   }];
   let genVerifyDecl = 1;
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.float";
 }
 
 //===----------------------------------------------------------------------===//
 // IntegerAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_IntegerAttr : Builtin_Attr<"Integer", [TypedAttrInterface]> {
+def Builtin_IntegerAttr : Builtin_Attr<"Integer", "integer",
+    [TypedAttrInterface]> {
   let summary = "An Attribute containing a integer value";
   let description = [{
     Syntax:
@@ -738,14 +731,13 @@ def Builtin_IntegerAttr : Builtin_Attr<"Integer", [TypedAttrInterface]> {
   }];
   let genVerifyDecl = 1;
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.integer";
 }
 
 //===----------------------------------------------------------------------===//
 // IntegerSetAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_IntegerSetAttr : Builtin_Attr<"IntegerSet"> {
+def Builtin_IntegerSetAttr : Builtin_Attr<"IntegerSet", "integer_set"> {
   let summary = "An Attribute containing an IntegerSet object";
   let description = [{
     Syntax:
@@ -768,14 +760,14 @@ def Builtin_IntegerSetAttr : Builtin_Attr<"IntegerSet"> {
   ];
   let extraClassDeclaration = "using ValueType = IntegerSet;";
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.integer_set";
 }
 
 //===----------------------------------------------------------------------===//
 // OpaqueAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_OpaqueAttr : Builtin_Attr<"Opaque", [TypedAttrInterface]> {
+def Builtin_OpaqueAttr : Builtin_Attr<"Opaque", "opaque",
+    [TypedAttrInterface]> {
   let summary = "An opaque representation of another Attribute";
   let description = [{
     Syntax:
@@ -806,7 +798,6 @@ def Builtin_OpaqueAttr : Builtin_Attr<"Opaque", [TypedAttrInterface]> {
   ];
   let genVerifyDecl = 1;
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.opaque";
 }
 
 //===----------------------------------------------------------------------===//
@@ -814,7 +805,7 @@ def Builtin_OpaqueAttr : Builtin_Attr<"Opaque", [TypedAttrInterface]> {
 //===----------------------------------------------------------------------===//
 
 def Builtin_SparseElementsAttr : Builtin_Attr<
-    "SparseElements", [ElementsAttrInterface]
+    "SparseElements", "sparse_elements", [ElementsAttrInterface]
   > {
   let summary = "An opaque representation of a multi-dimensional array";
   let description = [{
@@ -963,14 +954,13 @@ def Builtin_SparseElementsAttr : Builtin_Attr<
   }];
   let genVerifyDecl = 1;
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.sparse_elements";
 }
 
 //===----------------------------------------------------------------------===//
 // StridedLayoutAttr
 //===----------------------------------------------------------------------===//
 
-def StridedLayoutAttr : Builtin_Attr<"StridedLayout",
+def StridedLayoutAttr : Builtin_Attr<"StridedLayout", "strided_layout",
     [DeclareAttrInterfaceMethods<MemRefLayoutAttrInterface,
                                  ["verifyLayout"]>]> {
   let summary = "An Attribute representing a strided layout of a shaped type";
@@ -1017,7 +1007,6 @@ def StridedLayoutAttr : Builtin_Attr<"StridedLayout",
     /// Print the attribute to the given output stream.
     void print(raw_ostream &os) const;
   }];
-  let attrName = "builtin.strided_elements";
 }
 
 
@@ -1025,7 +1014,8 @@ def StridedLayoutAttr : Builtin_Attr<"StridedLayout",
 // StringAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_StringAttr : Builtin_Attr<"String", [TypedAttrInterface]> {
+def Builtin_StringAttr : Builtin_Attr<"String", "string",
+    [TypedAttrInterface]> {
   let summary = "An Attribute containing a string";
   let description = [{
     Syntax:
@@ -1100,14 +1090,13 @@ def Builtin_StringAttr : Builtin_Attr<"String", [TypedAttrInterface]> {
   }];
   let genStorageClass = 0;
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.string";
 }
 
 //===----------------------------------------------------------------------===//
 // SymbolRefAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_SymbolRefAttr : Builtin_Attr<"SymbolRef"> {
+def Builtin_SymbolRefAttr : Builtin_Attr<"SymbolRef", "symbol_ref"> {
   let summary = "An Attribute containing a symbolic reference to an Operation";
   let description = [{
     Syntax:
@@ -1167,14 +1156,13 @@ def Builtin_SymbolRefAttr : Builtin_Attr<"SymbolRef"> {
     StringAttr getLeafReference() const;
   }];
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.symbol_ref";
 }
 
 //===----------------------------------------------------------------------===//
 // TypeAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_TypeAttr : Builtin_Attr<"Type"> {
+def Builtin_TypeAttr : Builtin_Attr<"Type", "type"> {
   let summary = "An Attribute containing a Type";
   let description = [{
     Syntax:
@@ -1201,14 +1189,13 @@ def Builtin_TypeAttr : Builtin_Attr<"Type"> {
   ];
   let extraClassDeclaration = "using ValueType = Type;";
   let skipDefaultBuilders = 1;
-  let attrName = "builtin.type";
 }
 
 //===----------------------------------------------------------------------===//
 // UnitAttr
 //===----------------------------------------------------------------------===//
 
-def Builtin_UnitAttr : Builtin_Attr<"Unit"> {
+def Builtin_UnitAttr : Builtin_Attr<"Unit", "unit"> {
   let summary = "An Attribute value of `unit` type";
   let description = [{
     Syntax:
@@ -1243,7 +1230,6 @@ def Builtin_UnitAttr : Builtin_Attr<"Unit"> {
   let extraClassDeclaration = [{
     static UnitAttr get(MLIRContext *context);
   }];
-  let attrName = "builtin.unit";
 }
 
 #endif // BUILTIN_ATTRIBUTES

>From 07d6e50f38165a16f0fc5e01c8471910cc624ae7 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Mon, 20 Nov 2023 04:29:41 +0000
Subject: [PATCH 09/16] Use StringLiteral instead of StringRef, and use fields
 rather than methods

---
 .../include/flang/Optimizer/Dialect/FIRAttr.h |  8 +++++
 mlir/examples/toy/Ch7/include/toy/Dialect.h   |  4 +--
 mlir/include/mlir/Dialect/DLTI/DLTI.h         |  8 ++---
 mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h | 14 +++-----
 mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h  |  4 +--
 mlir/include/mlir/Dialect/Quant/QuantTypes.h  |  8 ++---
 .../mlir/Dialect/SPIRV/IR/SPIRVAttributes.h   |  6 ++--
 .../mlir/Dialect/SPIRV/IR/SPIRVTypes.h        | 20 +++++------
 mlir/include/mlir/IR/AttributeSupport.h       | 14 +++++++-
 mlir/include/mlir/IR/BuiltinAttributes.h      |  2 +-
 mlir/include/mlir/IR/TypeSupport.h            |  8 ++++-
 mlir/lib/IR/MLIRContext.cpp                   | 34 ++++++++++++++++---
 mlir/test/lib/Dialect/Test/TestTypes.h        |  4 +--
 mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp   | 16 ++++-----
 mlir/unittests/IR/TypeTest.cpp                |  4 +--
 .../Interfaces/DataLayoutInterfacesTest.cpp   |  4 +--
 16 files changed, 100 insertions(+), 58 deletions(-)

diff --git a/flang/include/flang/Optimizer/Dialect/FIRAttr.h b/flang/include/flang/Optimizer/Dialect/FIRAttr.h
index 2b14e15c906c3c5..c427a6576b5dab9 100644
--- a/flang/include/flang/Optimizer/Dialect/FIRAttr.h
+++ b/flang/include/flang/Optimizer/Dialect/FIRAttr.h
@@ -38,6 +38,7 @@ class ExactTypeAttr
   using Base::Base;
   using ValueType = mlir::Type;
 
+  static constexpr llvm::StringLiteral name = "fir.type_is";
   static constexpr llvm::StringRef getAttrName() { return "type_is"; }
   static ExactTypeAttr get(mlir::Type value);
 
@@ -51,6 +52,7 @@ class SubclassAttr
   using Base::Base;
   using ValueType = mlir::Type;
 
+  static constexpr llvm::StringLiteral name = "fir.class_is";
   static constexpr llvm::StringRef getAttrName() { return "class_is"; }
   static SubclassAttr get(mlir::Type value);
 
@@ -63,6 +65,7 @@ class MustBeHeapAttr : public mlir::BoolAttr {
 public:
   using BoolAttr::BoolAttr;
 
+  static constexpr llvm::StringLiteral name = "fir.must_be_heap";
   static constexpr llvm::StringRef getAttrName() { return "fir.must_be_heap"; }
 };
 
@@ -78,6 +81,7 @@ class ClosedIntervalAttr
 public:
   using Base::Base;
 
+  static constexpr llvm::StringLiteral name = "fir.interval";
   static constexpr llvm::StringRef getAttrName() { return "interval"; }
   static ClosedIntervalAttr get(mlir::MLIRContext *ctxt);
 };
@@ -92,6 +96,7 @@ class UpperBoundAttr
 public:
   using Base::Base;
 
+  static constexpr llvm::StringLiteral name = "fir.upper";
   static constexpr llvm::StringRef getAttrName() { return "upper"; }
   static UpperBoundAttr get(mlir::MLIRContext *ctxt);
 };
@@ -106,6 +111,7 @@ class LowerBoundAttr
 public:
   using Base::Base;
 
+  static constexpr llvm::StringLiteral name = "fir.lower";
   static constexpr llvm::StringRef getAttrName() { return "lower"; }
   static LowerBoundAttr get(mlir::MLIRContext *ctxt);
 };
@@ -120,6 +126,7 @@ class PointIntervalAttr
 public:
   using Base::Base;
 
+  static constexpr llvm::StringLiteral name = "fir.point";
   static constexpr llvm::StringRef getAttrName() { return "point"; }
   static PointIntervalAttr get(mlir::MLIRContext *ctxt);
 };
@@ -135,6 +142,7 @@ class RealAttr
   using Base::Base;
   using ValueType = std::pair<int, llvm::APFloat>;
 
+  static constexpr llvm::StringLiteral name = "fir.real";
   static constexpr llvm::StringRef getAttrName() { return "real"; }
   static RealAttr get(mlir::MLIRContext *ctxt, const ValueType &key);
 
diff --git a/mlir/examples/toy/Ch7/include/toy/Dialect.h b/mlir/examples/toy/Ch7/include/toy/Dialect.h
index fc7bbe3b9b922b1..64094c3515915d3 100644
--- a/mlir/examples/toy/Ch7/include/toy/Dialect.h
+++ b/mlir/examples/toy/Ch7/include/toy/Dialect.h
@@ -73,8 +73,8 @@ class StructType : public mlir::Type::TypeBase<StructType, mlir::Type,
   /// Returns the number of element type held by this struct.
   size_t getNumElementTypes() { return getElementTypes().size(); }
 
-  /// Returns the name of this struct type.
-  static constexpr StringRef getTypeName() { return "toy.struct"; }
+  /// The name of this struct type.
+  static constexpr StringLiteral name = "toy.struct";
 };
 } // namespace toy
 } // namespace mlir
diff --git a/mlir/include/mlir/Dialect/DLTI/DLTI.h b/mlir/include/mlir/Dialect/DLTI/DLTI.h
index 6dabbaa7ae1ad36..b9a8763eb44989e 100644
--- a/mlir/include/mlir/Dialect/DLTI/DLTI.h
+++ b/mlir/include/mlir/Dialect/DLTI/DLTI.h
@@ -56,9 +56,7 @@ class DataLayoutEntryAttr
   /// Prints this attribute.
   void print(AsmPrinter &os) const;
 
-  static constexpr StringRef getAttrName() {
-    return "builtin.data_layout_entry";
-  }
+  static constexpr StringLiteral name = "builtin.data_layout_entry";
 };
 
 //===----------------------------------------------------------------------===//
@@ -114,9 +112,7 @@ class DataLayoutSpecAttr
   /// Prints this attribute.
   void print(AsmPrinter &os) const;
 
-  static constexpr StringRef getAttrName() {
-    return "builtin.data_layout_spec";
-  }
+  static constexpr StringLiteral name = "builtin.data_layout_spec";
 };
 
 } // namespace mlir
diff --git a/mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h b/mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h
index 29ba15f8fe073a6..58c0719c6a410c8 100644
--- a/mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h
+++ b/mlir/include/mlir/Dialect/GPU/IR/GPUDialect.h
@@ -46,7 +46,7 @@ class AsyncTokenType
   // Used for generic hooks in TypeBase.
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "gpu.async_token"; }
+  static constexpr StringLiteral name = "gpu.async_token";
 };
 
 /// MMAMatrixType storage and uniquing. Array is uniqued based on its shape
@@ -130,7 +130,7 @@ class MMAMatrixType
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "gpu.mma_matrix"; }
+  static constexpr StringLiteral name = "gpu.mma_matrix";
 
   /// Get MMAMatrixType and verify construction Invariants.
   static MMAMatrixType get(ArrayRef<int64_t> shape, Type elementType,
@@ -179,9 +179,7 @@ class SparseDnTensorHandleType
                                        TypeStorage>::Base;
   using Base::Base;
 
-  static constexpr StringRef getTypeName() {
-    return "gpu.sparse.dntensor_handle";
-  }
+  static constexpr StringLiteral name = "gpu.sparse.dntensor_handle";
 };
 
 class SparseSpMatHandleType
@@ -191,7 +189,7 @@ class SparseSpMatHandleType
       typename Type::TypeBase<SparseSpMatHandleType, Type, TypeStorage>::Base;
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "gpu.sparse.spmat_handle"; }
+  static constexpr StringLiteral name = "gpu.sparse.spmat_handle";
 };
 
 class SparseSpGEMMOpHandleType
@@ -201,9 +199,7 @@ class SparseSpGEMMOpHandleType
                                        TypeStorage>::Base;
   using Base::Base;
 
-  static constexpr StringRef getTypeName() {
-    return "gpu.sparse.spgemmop_handle";
-  }
+  static constexpr StringLiteral name = "gpu.sparse.spgemmop_handle";
 };
 
 } // namespace gpu
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
index 66d9a11a1693bc7..4ab1bec912e3839 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.h
@@ -62,7 +62,7 @@ namespace LLVM {
   class ClassName : public Type::TypeBase<ClassName, Type, TypeStorage> {      \
   public:                                                                      \
     using Base::Base;                                                          \
-    static constexpr StringRef getTypeName() { return TypeName; }              \
+    static constexpr StringLiteral name = TypeName;                            \
   }
 
 DEFINE_TRIVIAL_LLVM_TYPE(LLVMVoidType, "llvm.void");
@@ -111,7 +111,7 @@ class LLVMStructType
   /// Inherit base constructors.
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "llvm.struct"; }
+  static constexpr StringLiteral name = "llvm.struct";
 
   /// Checks if the given type can be contained in a structure type.
   static bool isValidElementType(Type type);
diff --git a/mlir/include/mlir/Dialect/Quant/QuantTypes.h b/mlir/include/mlir/Dialect/Quant/QuantTypes.h
index f0300ea8cbb8ab2..de5aed0a91a2096 100644
--- a/mlir/include/mlir/Dialect/Quant/QuantTypes.h
+++ b/mlir/include/mlir/Dialect/Quant/QuantTypes.h
@@ -198,7 +198,7 @@ class AnyQuantizedType
   using Base::Base;
   using Base::getChecked;
 
-  static constexpr StringRef getTypeName() { return "quant.any"; }
+  static constexpr StringLiteral name = "quant.any";
 
   /// Gets an instance of the type with all parameters specified but not
   /// checked.
@@ -259,7 +259,7 @@ class UniformQuantizedType
   using Base::Base;
   using Base::getChecked;
 
-  static constexpr StringRef getTypeName() { return "quant.uniform"; }
+  static constexpr StringLiteral name = "quant.uniform";
 
   /// Gets an instance of the type with all parameters specified but not
   /// checked.
@@ -319,7 +319,7 @@ class UniformQuantizedPerAxisType
   using Base::Base;
   using Base::getChecked;
 
-  static constexpr StringRef getTypeName() { return "quant.uniform_per_axis"; }
+  static constexpr StringLiteral name = "quant.uniform_per_axis";
 
   /// Gets an instance of the type with all parameters specified but not
   /// checked.
@@ -389,7 +389,7 @@ class CalibratedQuantizedType
   using Base::Base;
   using Base::getChecked;
 
-  static constexpr StringRef getTypeName() { return "quant.calibrated"; }
+  static constexpr StringLiteral name = "quant.calibrated";
 
   /// Gets an instance of the type with all parameters specified but not
   /// checked.
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAttributes.h b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAttributes.h
index 8de961295153b8d..5ebfa9ca5ec25cc 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAttributes.h
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVAttributes.h
@@ -80,7 +80,7 @@ class InterfaceVarABIAttr
                               IntegerAttr descriptorSet, IntegerAttr binding,
                               IntegerAttr storageClass);
 
-  static constexpr StringRef getAttrName() { return "spirv.interface_var_abi"; }
+  static constexpr StringLiteral name = "spirv.interface_var_abi";
 };
 
 /// An attribute that specifies the SPIR-V (version, capabilities, extensions)
@@ -132,7 +132,7 @@ class VerCapExtAttr
                               IntegerAttr version, ArrayAttr capabilities,
                               ArrayAttr extensions);
 
-  static constexpr StringRef getAttrName() { return "spirv.ver_cap_ext"; }
+  static constexpr StringLiteral name = "spirv.ver_cap_ext";
 };
 
 /// An attribute that specifies the target version, allowed extensions and
@@ -188,7 +188,7 @@ class TargetEnvAttr
   /// Returns the target resource limits.
   ResourceLimitsAttr getResourceLimits() const;
 
-  static constexpr StringRef getAttrName() { return "spirv.target_env"; }
+  static constexpr StringLiteral name = "spirv.target_env";
 };
 } // namespace spirv
 } // namespace mlir
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTypes.h b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTypes.h
index e536adc8dce4abb..d946d936d4e6cf6 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTypes.h
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVTypes.h
@@ -132,7 +132,7 @@ class ArrayType : public Type::TypeBase<ArrayType, CompositeType,
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.array"; }
+  static constexpr StringLiteral name = "spirv.array";
 
   static ArrayType get(Type elementType, unsigned elementCount);
 
@@ -164,7 +164,7 @@ class ImageType
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.image"; }
+  static constexpr StringLiteral name = "spirv.image";
 
   static ImageType
   get(Type elementType, Dim dim,
@@ -205,7 +205,7 @@ class PointerType : public Type::TypeBase<PointerType, SPIRVType,
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.pointer"; }
+  static constexpr StringLiteral name = "spirv.pointer";
 
   static PointerType get(Type pointeeType, StorageClass storageClass);
 
@@ -226,7 +226,7 @@ class RuntimeArrayType
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.rtarray"; }
+  static constexpr StringLiteral name = "spirv.rtarray";
 
   static RuntimeArrayType get(Type elementType);
 
@@ -252,7 +252,7 @@ class SampledImageType
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.sampled_image"; }
+  static constexpr StringLiteral name = "spirv.sampled_image";
 
   static SampledImageType get(Type imageType);
 
@@ -298,7 +298,7 @@ class StructType
   // Type for specifying the offset of the struct members
   using OffsetInfo = uint32_t;
 
-  static constexpr StringRef getTypeName() { return "spirv.struct"; }
+  static constexpr StringLiteral name = "spirv.struct";
 
   // Type for specifying the decoration(s) on struct members
   struct MemberDecorationInfo {
@@ -399,7 +399,7 @@ class CooperativeMatrixType
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.coopmatrix"; }
+  static constexpr StringLiteral name = "spirv.coopmatrix";
 
   static CooperativeMatrixType get(Type elementType, uint32_t rows,
                                    uint32_t columns, Scope scope,
@@ -428,7 +428,7 @@ class CooperativeMatrixNVType
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.NV.coopmatrix"; }
+  static constexpr StringLiteral name = "spirv.NV.coopmatrix";
 
   static CooperativeMatrixNVType get(Type elementType, Scope scope,
                                      unsigned rows, unsigned columns);
@@ -454,7 +454,7 @@ class JointMatrixINTELType
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.jointmatrix"; }
+  static constexpr StringLiteral name = "spirv.jointmatrix";
 
   static JointMatrixINTELType get(Type elementType, Scope scope, unsigned rows,
                                   unsigned columns, MatrixLayout matrixLayout);
@@ -482,7 +482,7 @@ class MatrixType : public Type::TypeBase<MatrixType, CompositeType,
 public:
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "spirv.matrix"; }
+  static constexpr StringLiteral name = "spirv.matrix";
 
   static MatrixType get(Type columnType, uint32_t columnCount);
 
diff --git a/mlir/include/mlir/IR/AttributeSupport.h b/mlir/include/mlir/IR/AttributeSupport.h
index 104f5570e3bfb31..50e06fb75f8f719 100644
--- a/mlir/include/mlir/IR/AttributeSupport.h
+++ b/mlir/include/mlir/IR/AttributeSupport.h
@@ -20,6 +20,8 @@
 #include "llvm/ADT/Twine.h"
 
 namespace mlir {
+class StringAttr;
+
 //===----------------------------------------------------------------------===//
 // AbstractAttribute
 //===----------------------------------------------------------------------===//
@@ -38,6 +40,16 @@ class AbstractAttribute {
   /// reference to it.
   static const AbstractAttribute &lookup(TypeID typeID, MLIRContext *context);
 
+  /// Look up the specified abstract attribute in the MLIRContext and return a
+  /// reference to it if it exists.
+  static std::optional<std::reference_wrapper<const AbstractAttribute>>
+  lookup(StringRef name, MLIRContext *context);
+
+  /// Look up the specified abstract attribute in the MLIRContext and return a
+  /// reference to it if it exists.
+  static std::optional<std::reference_wrapper<const AbstractAttribute>>
+  lookup(StringAttr name, MLIRContext *context);
+
   /// This method is used by Dialect objects when they register the list of
   /// attributes they contain.
   template <typename T>
@@ -45,7 +57,7 @@ class AbstractAttribute {
     return AbstractAttribute(dialect, T::getInterfaceMap(), T::getHasTraitFn(),
                              T::getWalkImmediateSubElementsFn(),
                              T::getReplaceImmediateSubElementsFn(),
-                             T::getTypeID(), T::getAttrName());
+                             T::getTypeID(), T::name);
   }
 
   /// This method is used by Dialect objects to register attributes with
diff --git a/mlir/include/mlir/IR/BuiltinAttributes.h b/mlir/include/mlir/IR/BuiltinAttributes.h
index c45473ceccfe371..901df3a25a46f1b 100644
--- a/mlir/include/mlir/IR/BuiltinAttributes.h
+++ b/mlir/include/mlir/IR/BuiltinAttributes.h
@@ -1045,7 +1045,7 @@ class DistinctAttr
   /// unique identifier.
   static DistinctAttr create(Attribute referencedAttr);
 
-  static constexpr StringRef getAttrName() { return "builtin.distinct"; }
+  static constexpr StringLiteral name = "builtin.distinct";
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/IR/TypeSupport.h b/mlir/include/mlir/IR/TypeSupport.h
index f4c840bf4ab5d42..0e796bb172fd8cc 100644
--- a/mlir/include/mlir/IR/TypeSupport.h
+++ b/mlir/include/mlir/IR/TypeSupport.h
@@ -20,6 +20,7 @@
 namespace mlir {
 class Dialect;
 class MLIRContext;
+class StringAttr;
 
 //===----------------------------------------------------------------------===//
 // AbstractType
@@ -44,6 +45,11 @@ class AbstractType {
   static std::optional<std::reference_wrapper<const AbstractType>>
   lookup(StringRef name, MLIRContext *context);
 
+  /// Look up the specified abstract type in the MLIRContext and return a
+  /// reference to it if it exists.
+  static std::optional<std::reference_wrapper<const AbstractType>>
+  lookup(StringAttr name, MLIRContext *context);
+
   /// This method is used by Dialect objects when they register the list of
   /// types they contain.
   template <typename T>
@@ -51,7 +57,7 @@ class AbstractType {
     return AbstractType(dialect, T::getInterfaceMap(), T::getHasTraitFn(),
                         T::getWalkImmediateSubElementsFn(),
                         T::getReplaceImmediateSubElementsFn(), T::getTypeID(),
-                        T::getTypeName());
+                        T::name);
   }
 
   /// This method is used by Dialect objects to register types with
diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index d34cb2c0028bd25..9d0b8b0f8003141 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -213,7 +213,8 @@ class MLIRContextImpl {
   StorageUniquer typeUniquer;
 
   /// This is a mapping from type name to the abstract type describing it.
-  llvm::StringMap<AbstractType *> nameToType;
+  /// It is used by `AbstractType::lookup` to get an `AbstractType` from a name.
+  llvm::DenseMap<StringAttr, AbstractType *> nameToType;
 
   /// Cached Type Instances.
   Float8E5M2Type f8E5M2Ty;
@@ -240,8 +241,9 @@ class MLIRContextImpl {
   StorageUniquer attributeUniquer;
 
   /// This is a mapping from attribute name to the abstract attribute describing
-  /// it.
-  llvm::StringMap<AbstractAttribute *> nameToAttribute;
+  /// it. It is used by `AbstractAttribute::lookup` to get an
+  /// `AbstractAttribute` from a name.
+  llvm::DenseMap<StringAttr, AbstractAttribute *> nameToAttribute;
 
   /// Cached Attribute Instances.
   BoolAttr falseAttr, trueAttr;
@@ -704,7 +706,8 @@ void Dialect::addType(TypeID typeID, AbstractType &&typeInfo) {
           AbstractType(std::move(typeInfo));
   if (!impl.registeredTypes.insert({typeID, newInfo}).second)
     llvm::report_fatal_error("Dialect Type already registered.");
-  if (!impl.nameToType.insert({newInfo->getName(), newInfo}).second)
+  auto name = StringAttr::get(context, newInfo->getName());
+  if (!impl.nameToType.insert({name, newInfo}).second)
     llvm::report_fatal_error("Dialect Type with name " + newInfo->getName() +
                              " is already registered.");
 }
@@ -719,7 +722,8 @@ void Dialect::addAttribute(TypeID typeID, AbstractAttribute &&attrInfo) {
           AbstractAttribute(std::move(attrInfo));
   if (!impl.registeredAttributes.insert({typeID, newInfo}).second)
     llvm::report_fatal_error("Dialect Attribute already registered.");
-  if (!impl.nameToAttribute.insert({newInfo->getName(), newInfo}).second)
+  auto name = StringAttr::get(context, newInfo->getName());
+  if (!impl.nameToAttribute.insert({name, newInfo}).second)
     llvm::report_fatal_error("Dialect Attribute with name " +
                              newInfo->getName() + " is already registered.");
 }
@@ -744,6 +748,21 @@ AbstractAttribute *AbstractAttribute::lookupMutable(TypeID typeID,
   return impl.registeredAttributes.lookup(typeID);
 }
 
+std::optional<std::reference_wrapper<const AbstractAttribute>>
+AbstractAttribute::lookup(StringRef name, MLIRContext *context) {
+  return lookup(StringAttr::get(context, name), context);
+}
+
+std::optional<std::reference_wrapper<const AbstractAttribute>>
+AbstractAttribute::lookup(StringAttr name, MLIRContext *context) {
+  MLIRContextImpl &impl = context->getImpl();
+  const AbstractAttribute *type = impl.nameToAttribute.lookup(name);
+
+  if (!type)
+    return std::nullopt;
+  return {*type};
+}
+
 //===----------------------------------------------------------------------===//
 // OperationName
 //===----------------------------------------------------------------------===//
@@ -960,6 +979,11 @@ AbstractType *AbstractType::lookupMutable(TypeID typeID, MLIRContext *context) {
 
 std::optional<std::reference_wrapper<const AbstractType>>
 AbstractType::lookup(StringRef name, MLIRContext *context) {
+  return lookup(StringAttr::get(context, name), context);
+}
+
+std::optional<std::reference_wrapper<const AbstractType>>
+AbstractType::lookup(StringAttr name, MLIRContext *context) {
   MLIRContextImpl &impl = context->getImpl();
   const AbstractType *type = impl.nameToType.lookup(name);
 
diff --git a/mlir/test/lib/Dialect/Test/TestTypes.h b/mlir/test/lib/Dialect/Test/TestTypes.h
index e9cb581c9f37455..b1b5921d8faddd1 100644
--- a/mlir/test/lib/Dialect/Test/TestTypes.h
+++ b/mlir/test/lib/Dialect/Test/TestTypes.h
@@ -14,8 +14,8 @@
 #ifndef MLIR_TESTTYPES_H
 #define MLIR_TESTTYPES_H
 
-#include <tuple>
 #include <optional>
+#include <tuple>
 
 #include "TestTraits.h"
 #include "mlir/IR/Diagnostics.h"
@@ -132,7 +132,7 @@ class TestRecursiveType
 public:
   using Base::Base;
 
-  static constexpr ::mlir::StringRef getTypeName() { return "test.recursive"; }
+  static constexpr ::mlir::StringLiteral name = "test.recursive";
 
   static TestRecursiveType get(::mlir::MLIRContext *ctx,
                                ::llvm::StringRef name) {
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index a0b4c549b7b3493..0504126d0d472cb 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -269,16 +269,16 @@ void DefGen::emitTopLevelDeclarations() {
 }
 
 void DefGen::emitName() {
-  auto *mnemonic = defCls.addStaticMethod<Method::Constexpr>(
-      "::llvm::StringLiteral", "get" + defType + "Name");
+  std::string name;
   if (auto *attrDef = dyn_cast<AttrDef>(&def)) {
-    mnemonic->body().indent()
-        << strfmt("return \"{0}\";", attrDef->getAttrName());
-    return;
+    name = attrDef->getAttrName();
+  } else {
+    auto *typeDef = cast<TypeDef>(&def);
+    name = typeDef->getTypeName();
   }
-  auto *typeDef = cast<TypeDef>(&def);
-  mnemonic->body().indent()
-      << strfmt("return \"{0}\";", typeDef->getTypeName());
+  std::string nameDecl =
+      strfmt("static constexpr ::llvm::StringLiteral name = \"{0}\";\n", name);
+  defCls.declare<ExtraClassDeclaration>(std::move(nameDecl));
 }
 
 void DefGen::emitBuilders() {
diff --git a/mlir/unittests/IR/TypeTest.cpp b/mlir/unittests/IR/TypeTest.cpp
index e600fed25b5db08..30f6642a9ca71d0 100644
--- a/mlir/unittests/IR/TypeTest.cpp
+++ b/mlir/unittests/IR/TypeTest.cpp
@@ -20,7 +20,7 @@ struct LeafType;
 struct MiddleType : Type::TypeBase<MiddleType, Type, TypeStorage> {
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "test.middle"; }
+  static constexpr StringLiteral name = "test.middle";
 
   static bool classof(Type ty) {
     return ty.getTypeID() == TypeID::get<LeafType>() || Base::classof(ty);
@@ -30,7 +30,7 @@ struct MiddleType : Type::TypeBase<MiddleType, Type, TypeStorage> {
 struct LeafType : Type::TypeBase<LeafType, MiddleType, TypeStorage> {
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "test.leaf"; }
+  static constexpr StringLiteral name = "test.leaf";
 };
 
 struct FakeDialect : Dialect {
diff --git a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
index e4a314a7725abfa..2c84cee81a7d2cd 100644
--- a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
+++ b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
@@ -88,7 +88,7 @@ struct SingleQueryType
 
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "test.single_query"; }
+  static constexpr StringLiteral name = "test.single_query";
 
   static SingleQueryType get(MLIRContext *ctx) { return Base::get(ctx); }
 
@@ -138,7 +138,7 @@ struct TypeNoLayout : public Type::TypeBase<TypeNoLayout, Type, TypeStorage> {
 
   using Base::Base;
 
-  static constexpr StringRef getTypeName() { return "test.no_layout"; }
+  static constexpr StringLiteral name = "test.no_layout";
 
   static TypeNoLayout get(MLIRContext *ctx) { return Base::get(ctx); }
 };

>From 21468a8d6525e24856f93761f377db859896f702 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Wed, 22 Nov 2023 03:08:59 +0000
Subject: [PATCH 10/16] Remove use of StringAttr in the MLIRContext and fix one
 attr

---
 mlir/include/mlir/IR/AttributeSupport.h       | 12 -------
 mlir/include/mlir/IR/TypeSupport.h            |  6 ----
 mlir/lib/IR/MLIRContext.cpp                   | 34 +++----------------
 mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp   |  2 +-
 .../Interfaces/DataLayoutInterfacesTest.cpp   |  4 +--
 5 files changed, 7 insertions(+), 51 deletions(-)

diff --git a/mlir/include/mlir/IR/AttributeSupport.h b/mlir/include/mlir/IR/AttributeSupport.h
index 50e06fb75f8f719..8795ddbc800ef3f 100644
--- a/mlir/include/mlir/IR/AttributeSupport.h
+++ b/mlir/include/mlir/IR/AttributeSupport.h
@@ -20,8 +20,6 @@
 #include "llvm/ADT/Twine.h"
 
 namespace mlir {
-class StringAttr;
-
 //===----------------------------------------------------------------------===//
 // AbstractAttribute
 //===----------------------------------------------------------------------===//
@@ -40,16 +38,6 @@ class AbstractAttribute {
   /// reference to it.
   static const AbstractAttribute &lookup(TypeID typeID, MLIRContext *context);
 
-  /// Look up the specified abstract attribute in the MLIRContext and return a
-  /// reference to it if it exists.
-  static std::optional<std::reference_wrapper<const AbstractAttribute>>
-  lookup(StringRef name, MLIRContext *context);
-
-  /// Look up the specified abstract attribute in the MLIRContext and return a
-  /// reference to it if it exists.
-  static std::optional<std::reference_wrapper<const AbstractAttribute>>
-  lookup(StringAttr name, MLIRContext *context);
-
   /// This method is used by Dialect objects when they register the list of
   /// attributes they contain.
   template <typename T>
diff --git a/mlir/include/mlir/IR/TypeSupport.h b/mlir/include/mlir/IR/TypeSupport.h
index 0e796bb172fd8cc..d92f93ffbd6bd3c 100644
--- a/mlir/include/mlir/IR/TypeSupport.h
+++ b/mlir/include/mlir/IR/TypeSupport.h
@@ -20,7 +20,6 @@
 namespace mlir {
 class Dialect;
 class MLIRContext;
-class StringAttr;
 
 //===----------------------------------------------------------------------===//
 // AbstractType
@@ -45,11 +44,6 @@ class AbstractType {
   static std::optional<std::reference_wrapper<const AbstractType>>
   lookup(StringRef name, MLIRContext *context);
 
-  /// Look up the specified abstract type in the MLIRContext and return a
-  /// reference to it if it exists.
-  static std::optional<std::reference_wrapper<const AbstractType>>
-  lookup(StringAttr name, MLIRContext *context);
-
   /// This method is used by Dialect objects when they register the list of
   /// types they contain.
   template <typename T>
diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index 9d0b8b0f8003141..d34cb2c0028bd25 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -213,8 +213,7 @@ class MLIRContextImpl {
   StorageUniquer typeUniquer;
 
   /// This is a mapping from type name to the abstract type describing it.
-  /// It is used by `AbstractType::lookup` to get an `AbstractType` from a name.
-  llvm::DenseMap<StringAttr, AbstractType *> nameToType;
+  llvm::StringMap<AbstractType *> nameToType;
 
   /// Cached Type Instances.
   Float8E5M2Type f8E5M2Ty;
@@ -241,9 +240,8 @@ class MLIRContextImpl {
   StorageUniquer attributeUniquer;
 
   /// This is a mapping from attribute name to the abstract attribute describing
-  /// it. It is used by `AbstractAttribute::lookup` to get an
-  /// `AbstractAttribute` from a name.
-  llvm::DenseMap<StringAttr, AbstractAttribute *> nameToAttribute;
+  /// it.
+  llvm::StringMap<AbstractAttribute *> nameToAttribute;
 
   /// Cached Attribute Instances.
   BoolAttr falseAttr, trueAttr;
@@ -706,8 +704,7 @@ void Dialect::addType(TypeID typeID, AbstractType &&typeInfo) {
           AbstractType(std::move(typeInfo));
   if (!impl.registeredTypes.insert({typeID, newInfo}).second)
     llvm::report_fatal_error("Dialect Type already registered.");
-  auto name = StringAttr::get(context, newInfo->getName());
-  if (!impl.nameToType.insert({name, newInfo}).second)
+  if (!impl.nameToType.insert({newInfo->getName(), newInfo}).second)
     llvm::report_fatal_error("Dialect Type with name " + newInfo->getName() +
                              " is already registered.");
 }
@@ -722,8 +719,7 @@ void Dialect::addAttribute(TypeID typeID, AbstractAttribute &&attrInfo) {
           AbstractAttribute(std::move(attrInfo));
   if (!impl.registeredAttributes.insert({typeID, newInfo}).second)
     llvm::report_fatal_error("Dialect Attribute already registered.");
-  auto name = StringAttr::get(context, newInfo->getName());
-  if (!impl.nameToAttribute.insert({name, newInfo}).second)
+  if (!impl.nameToAttribute.insert({newInfo->getName(), newInfo}).second)
     llvm::report_fatal_error("Dialect Attribute with name " +
                              newInfo->getName() + " is already registered.");
 }
@@ -748,21 +744,6 @@ AbstractAttribute *AbstractAttribute::lookupMutable(TypeID typeID,
   return impl.registeredAttributes.lookup(typeID);
 }
 
-std::optional<std::reference_wrapper<const AbstractAttribute>>
-AbstractAttribute::lookup(StringRef name, MLIRContext *context) {
-  return lookup(StringAttr::get(context, name), context);
-}
-
-std::optional<std::reference_wrapper<const AbstractAttribute>>
-AbstractAttribute::lookup(StringAttr name, MLIRContext *context) {
-  MLIRContextImpl &impl = context->getImpl();
-  const AbstractAttribute *type = impl.nameToAttribute.lookup(name);
-
-  if (!type)
-    return std::nullopt;
-  return {*type};
-}
-
 //===----------------------------------------------------------------------===//
 // OperationName
 //===----------------------------------------------------------------------===//
@@ -979,11 +960,6 @@ AbstractType *AbstractType::lookupMutable(TypeID typeID, MLIRContext *context) {
 
 std::optional<std::reference_wrapper<const AbstractType>>
 AbstractType::lookup(StringRef name, MLIRContext *context) {
-  return lookup(StringAttr::get(context, name), context);
-}
-
-std::optional<std::reference_wrapper<const AbstractType>>
-AbstractType::lookup(StringAttr name, MLIRContext *context) {
   MLIRContextImpl &impl = context->getImpl();
   const AbstractType *type = impl.nameToType.lookup(name);
 
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index 0504126d0d472cb..b9a72119790e5ab 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -269,7 +269,7 @@ void DefGen::emitTopLevelDeclarations() {
 }
 
 void DefGen::emitName() {
-  std::string name;
+  StringRef name;
   if (auto *attrDef = dyn_cast<AttrDef>(&def)) {
     name = attrDef->getAttrName();
   } else {
diff --git a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
index 2c84cee81a7d2cd..47cdf9066d14251 100644
--- a/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
+++ b/mlir/unittests/Interfaces/DataLayoutInterfacesTest.cpp
@@ -57,9 +57,7 @@ struct CustomDataLayoutSpec
 
   using Base::Base;
 
-  static constexpr StringRef getAttrName() {
-    return "test.custom_data_layout_spec";
-  }
+  static constexpr StringLiteral name = "test.custom_data_layout_spec";
 
   static CustomDataLayoutSpec get(MLIRContext *ctx,
                                   ArrayRef<DataLayoutEntryInterface> entries) {

>From 0ca9ad39d194c378af73ddc939536ad2cfcbbfb2 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Thu, 23 Nov 2023 00:47:20 +0000
Subject: [PATCH 11/16] Add the missing AbstractAttribute::lookup

---
 mlir/include/mlir/IR/AttributeSupport.h |  5 +++++
 mlir/lib/IR/MLIRContext.cpp             | 10 ++++++++++
 2 files changed, 15 insertions(+)

diff --git a/mlir/include/mlir/IR/AttributeSupport.h b/mlir/include/mlir/IR/AttributeSupport.h
index 8795ddbc800ef3f..96c18b7c70aca29 100644
--- a/mlir/include/mlir/IR/AttributeSupport.h
+++ b/mlir/include/mlir/IR/AttributeSupport.h
@@ -38,6 +38,11 @@ class AbstractAttribute {
   /// reference to it.
   static const AbstractAttribute &lookup(TypeID typeID, MLIRContext *context);
 
+  /// Look up the specified abstract attribute in the MLIRContext and return a
+  /// reference to it if it exists.
+  static std::optional<std::reference_wrapper<const AbstractAttribute>>
+  lookup(StringRef name, MLIRContext *context);
+
   /// This method is used by Dialect objects when they register the list of
   /// attributes they contain.
   template <typename T>
diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index d34cb2c0028bd25..96fc7778842555d 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -744,6 +744,16 @@ AbstractAttribute *AbstractAttribute::lookupMutable(TypeID typeID,
   return impl.registeredAttributes.lookup(typeID);
 }
 
+std::optional<std::reference_wrapper<const AbstractAttribute>>
+AbstractAttribute::lookup(StringRef name, MLIRContext *context) {
+  MLIRContextImpl &impl = context->getImpl();
+  const AbstractAttribute *type = impl.nameToAttribute.lookup(name);
+
+  if (!type)
+    return std::nullopt;
+  return {*type};
+}
+
 //===----------------------------------------------------------------------===//
 // OperationName
 //===----------------------------------------------------------------------===//

>From ddfaf8bcbc2ba0979cbd25b4e975bf99f5fcd0d9 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Thu, 23 Nov 2023 00:47:35 +0000
Subject: [PATCH 12/16] Add a test for AbstractType::lookup and
 AbstractAttribute::lookup.

---
 mlir/unittests/IR/CMakeLists.txt        |  1 +
 mlir/unittests/IR/TypeAttrNamesTest.cpp | 90 +++++++++++++++++++++++++
 2 files changed, 91 insertions(+)
 create mode 100644 mlir/unittests/IR/TypeAttrNamesTest.cpp

diff --git a/mlir/unittests/IR/CMakeLists.txt b/mlir/unittests/IR/CMakeLists.txt
index 6d05af193dfae01..1ed46869c2c8a96 100644
--- a/mlir/unittests/IR/CMakeLists.txt
+++ b/mlir/unittests/IR/CMakeLists.txt
@@ -10,6 +10,7 @@ add_mlir_unittest(MLIRIRTests
   ShapedTypeTest.cpp
   SymbolTableTest.cpp
   TypeTest.cpp
+  TypeAttrNamesTest.cpp
   OpPropertiesTest.cpp
 
   DEPENDS
diff --git a/mlir/unittests/IR/TypeAttrNamesTest.cpp b/mlir/unittests/IR/TypeAttrNamesTest.cpp
new file mode 100644
index 000000000000000..2fb3fb00e89c686
--- /dev/null
+++ b/mlir/unittests/IR/TypeAttrNamesTest.cpp
@@ -0,0 +1,90 @@
+//===- TypeAttrNamesTest.cpp - Type API unit tests ------------------------===//
+//
+// Part of the LLVM Project, 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 test the lookup of AbstractType / AbstractAttribute by name.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/IR/Attributes.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/Dialect.h"
+#include "mlir/IR/Types.h"
+#include "mlir/IR/Value.h"
+#include "mlir/Support/TypeID.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+
+namespace {
+struct FooType : Type::TypeBase<FooType, Type, TypeStorage> {
+  using Base::Base;
+
+  static constexpr StringLiteral name = "fake.foo";
+
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(FooType)
+};
+
+struct BarAttr : Attribute::AttrBase<BarAttr, Attribute, AttributeStorage> {
+  using Base::Base;
+
+  static constexpr StringLiteral name = "fake.bar";
+
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(BarAttr)
+};
+
+struct FakeDialect : Dialect {
+  FakeDialect(MLIRContext *context)
+      : Dialect(getDialectNamespace(), context, TypeID::get<FakeDialect>()) {
+    addTypes<FooType>();
+    addAttributes<BarAttr>();
+  }
+
+  static constexpr ::llvm::StringLiteral getDialectNamespace() {
+    return ::llvm::StringLiteral("fake");
+  }
+
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(FakeDialect)
+};
+} // namespace
+
+TEST(AbstractType, LookupWithString) {
+  MLIRContext ctx;
+  ctx.loadDialect<FakeDialect>();
+
+  // Check that we can lookup an abstract type by name.
+  auto fooAbstractType = AbstractType::lookup("fake.foo", &ctx);
+  EXPECT_TRUE(fooAbstractType.has_value());
+  EXPECT_TRUE(fooAbstractType->get().getName() == "fake.foo");
+
+  // Check that the abstract type is the same as the one used by the type.
+  auto fooType = FooType::get(&ctx);
+  EXPECT_TRUE(&fooType.getAbstractType() == &fooAbstractType->get());
+
+  // Check that lookups of non-existing types returns nullopt.
+  // Even if an attribute with the same name exists.
+  EXPECT_FALSE(AbstractType::lookup("fake.bar", &ctx).has_value());
+}
+
+TEST(AbstractAttribute, LookupWithString) {
+  MLIRContext ctx;
+  ctx.loadDialect<FakeDialect>();
+
+  // Check that we can lookup an abstract type by name.
+  auto barAbstractAttr = AbstractAttribute::lookup("fake.bar", &ctx);
+  EXPECT_TRUE(barAbstractAttr.has_value());
+  EXPECT_TRUE(barAbstractAttr->get().getName() == "fake.bar");
+
+  // Check that the abstract Attribute is the same as the one used by the
+  // Attribute.
+  auto barAttr = BarAttr::get(&ctx);
+  EXPECT_TRUE(&barAttr.getAbstractAttribute() == &barAbstractAttr->get());
+
+  // Check that lookups of non-existing Attributes returns nullopt.
+  // Even if an attribute with the same name exists.
+  EXPECT_FALSE(AbstractAttribute::lookup("fake.foo", &ctx).has_value());
+}
\ No newline at end of file

>From ce4ace82226e524cc1b007cea2457809d3b3728f Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Thu, 30 Nov 2023 03:37:21 +0000
Subject: [PATCH 13/16] Add missing newline

---
 mlir/unittests/IR/TypeAttrNamesTest.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mlir/unittests/IR/TypeAttrNamesTest.cpp b/mlir/unittests/IR/TypeAttrNamesTest.cpp
index 2fb3fb00e89c686..488c164b23b4bdd 100644
--- a/mlir/unittests/IR/TypeAttrNamesTest.cpp
+++ b/mlir/unittests/IR/TypeAttrNamesTest.cpp
@@ -87,4 +87,4 @@ TEST(AbstractAttribute, LookupWithString) {
   // Check that lookups of non-existing Attributes returns nullopt.
   // Even if an attribute with the same name exists.
   EXPECT_FALSE(AbstractAttribute::lookup("fake.foo", &ctx).has_value());
-}
\ No newline at end of file
+}

>From e3b56795d4ebfd2ce20a0fd8d44f62aea29a82b8 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Thu, 30 Nov 2023 03:49:36 +0000
Subject: [PATCH 14/16] Add documentation that got removed

---
 mlir/lib/IR/MLIRContext.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index 96fc7778842555d..3b003d102590a95 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -213,6 +213,7 @@ class MLIRContextImpl {
   StorageUniquer typeUniquer;
 
   /// This is a mapping from type name to the abstract type describing it.
+  /// It is used by `AbstractType::lookup` to get an `AbstractType` from a name.
   llvm::StringMap<AbstractType *> nameToType;
 
   /// Cached Type Instances.
@@ -240,7 +241,8 @@ class MLIRContextImpl {
   StorageUniquer attributeUniquer;
 
   /// This is a mapping from attribute name to the abstract attribute describing
-  /// it.
+  /// it. It is used by `AbstractType::lookup` to get an `AbstractType` from a
+  /// name.
   llvm::StringMap<AbstractAttribute *> nameToAttribute;
 
   /// Cached Attribute Instances.

>From 534013036059e4af032589ad5872b6c35f2f1e42 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Thu, 30 Nov 2023 03:55:41 +0000
Subject: [PATCH 15/16] Comment why we don't use a DenseMap of StringAttr

---
 mlir/lib/IR/MLIRContext.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index 3b003d102590a95..8638b3047955cb6 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -214,6 +214,8 @@ class MLIRContextImpl {
 
   /// This is a mapping from type name to the abstract type describing it.
   /// It is used by `AbstractType::lookup` to get an `AbstractType` from a name.
+  /// As this map needs to be populated before `StringAttr` is loaded, we
+  /// cannot use `StringAttr` as the key, which would avoid string duplication.
   llvm::StringMap<AbstractType *> nameToType;
 
   /// Cached Type Instances.
@@ -243,6 +245,8 @@ class MLIRContextImpl {
   /// This is a mapping from attribute name to the abstract attribute describing
   /// it. It is used by `AbstractType::lookup` to get an `AbstractType` from a
   /// name.
+  /// As this map needs to be populated before `StringAttr` is loaded, we
+  /// cannot use `StringAttr` as the key, which would avoid string duplication.
   llvm::StringMap<AbstractAttribute *> nameToAttribute;
 
   /// Cached Attribute Instances.

>From 4b0d5f828a59c089faa1328415ee990ba0a2ef13 Mon Sep 17 00:00:00 2001
From: Mathieu Fehr <mathieu.fehr at gmail.com>
Date: Thu, 30 Nov 2023 04:13:37 +0000
Subject: [PATCH 16/16] Do not duplicate the names of types and attributes

---
 mlir/lib/IR/MLIRContext.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp
index 8638b3047955cb6..67169292d0b628f 100644
--- a/mlir/lib/IR/MLIRContext.cpp
+++ b/mlir/lib/IR/MLIRContext.cpp
@@ -215,8 +215,8 @@ class MLIRContextImpl {
   /// This is a mapping from type name to the abstract type describing it.
   /// It is used by `AbstractType::lookup` to get an `AbstractType` from a name.
   /// As this map needs to be populated before `StringAttr` is loaded, we
-  /// cannot use `StringAttr` as the key, which would avoid string duplication.
-  llvm::StringMap<AbstractType *> nameToType;
+  /// cannot use `StringAttr` as the key.
+  llvm::DenseMap<StringRef, AbstractType *> nameToType;
 
   /// Cached Type Instances.
   Float8E5M2Type f8E5M2Ty;
@@ -246,8 +246,8 @@ class MLIRContextImpl {
   /// it. It is used by `AbstractType::lookup` to get an `AbstractType` from a
   /// name.
   /// As this map needs to be populated before `StringAttr` is loaded, we
-  /// cannot use `StringAttr` as the key, which would avoid string duplication.
-  llvm::StringMap<AbstractAttribute *> nameToAttribute;
+  /// cannot use `StringAttr` as the key.
+  llvm::DenseMap<StringRef, AbstractAttribute *> nameToAttribute;
 
   /// Cached Attribute Instances.
   BoolAttr falseAttr, trueAttr;



More information about the flang-commits mailing list