[Mlir-commits] [mlir] 0c7890c - [mlir] Convert NamedAttribute to be a class

River Riddle llvmlistbot at llvm.org
Wed Nov 17 21:40:04 PST 2021


Author: River Riddle
Date: 2021-11-18T05:39:29Z
New Revision: 0c7890c844fdc7adb6d0cf58403e3fdd7407915d

URL: https://github.com/llvm/llvm-project/commit/0c7890c844fdc7adb6d0cf58403e3fdd7407915d
DIFF: https://github.com/llvm/llvm-project/commit/0c7890c844fdc7adb6d0cf58403e3fdd7407915d.diff

LOG: [mlir] Convert NamedAttribute to be a class

NamedAttribute is currently represented as an std::pair, but this
creates an extremely clunky .first/.second API. This commit
converts it to a class, with better accessors (getName/getValue)
and also opens the door for more convenient API in the future.

Differential Revision: https://reviews.llvm.org/D113956

Added: 
    

Modified: 
    flang/lib/Optimizer/Dialect/FIROps.cpp
    mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
    mlir/include/mlir/IR/Attributes.h
    mlir/include/mlir/IR/FunctionSupport.h
    mlir/include/mlir/IR/Operation.h
    mlir/include/mlir/IR/OperationSupport.h
    mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h
    mlir/lib/CAPI/IR/BuiltinAttributes.cpp
    mlir/lib/CAPI/IR/IR.cpp
    mlir/lib/Conversion/GPUCommon/GPUOpsLowering.cpp
    mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
    mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp
    mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp
    mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp
    mlir/lib/Dialect/DLTI/DLTI.cpp
    mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
    mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
    mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
    mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp
    mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
    mlir/lib/Dialect/Linalg/IR/LinalgTypes.cpp
    mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp
    mlir/lib/Dialect/SPIRV/Linking/ModuleCombiner/ModuleCombiner.cpp
    mlir/lib/Dialect/SPIRV/Transforms/DecorateCompositeTypeLayoutPass.cpp
    mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
    mlir/lib/Dialect/Shape/IR/Shape.cpp
    mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
    mlir/lib/Dialect/Vector/VectorOps.cpp
    mlir/lib/IR/AsmPrinter.cpp
    mlir/lib/IR/Attributes.cpp
    mlir/lib/IR/BuiltinAttributes.cpp
    mlir/lib/IR/BuiltinDialect.cpp
    mlir/lib/IR/OperationSupport.cpp
    mlir/lib/IR/Verifier.cpp
    mlir/lib/Parser/Parser.cpp
    mlir/lib/Target/Cpp/TranslateToCpp.cpp
    mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
    mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
    mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp
    mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
    mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp
    mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
    mlir/lib/Transforms/Utils/Utils.cpp
    mlir/lib/Transforms/ViewOpGraph.cpp
    mlir/test/lib/Dialect/Test/TestDialect.cpp
    mlir/test/lib/Dialect/Test/TestPatterns.cpp
    mlir/test/lib/IR/TestBuiltinAttributeInterfaces.cpp
    mlir/test/lib/IR/TestPrintNesting.cpp
    mlir/test/mlir-tblgen/op-result.td
    mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
    mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
    mlir/unittests/IR/OperationSupportTest.cpp
    mlir/unittests/TableGen/OpBuildGen.cpp
    mlir/unittests/TableGen/StructsGenTest.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp
index 32c3e8fd747db..2510e953b0968 100644
--- a/flang/lib/Optimizer/Dialect/FIROps.cpp
+++ b/flang/lib/Optimizer/Dialect/FIROps.cpp
@@ -2222,7 +2222,7 @@ getMutableSuccessorOperands(unsigned pos, mlir::MutableOperandRange operands,
   NamedAttribute targetOffsetAttr =
       *owner->getAttrDictionary().getNamed(offsetAttr);
   return getSubOperands(
-      pos, operands, targetOffsetAttr.second.cast<DenseIntElementsAttr>(),
+      pos, operands, targetOffsetAttr.getValue().cast<DenseIntElementsAttr>(),
       mlir::MutableOperandRange::OperandSegment(pos, targetOffsetAttr));
 }
 

diff  --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
index 055975ef58bcf..cd9fe10c5fdc2 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td
@@ -72,9 +72,8 @@ def LLVM_OneResultOpBuilder :
   [{
     if (resultType) $_state.addTypes(resultType);
     $_state.addOperands(operands);
-    for (auto namedAttr : attributes) {
-      $_state.addAttribute(namedAttr.first, namedAttr.second);
-    }
+    for (auto namedAttr : attributes)
+      $_state.addAttribute(namedAttr.getName(), namedAttr.getValue());
   }]>;
 
 def LLVM_ZeroResultOpBuilder :
@@ -82,9 +81,8 @@ def LLVM_ZeroResultOpBuilder :
     CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
   [{
     $_state.addOperands(operands);
-    for (auto namedAttr : attributes) {
-      $_state.addAttribute(namedAttr.first, namedAttr.second);
-    }
+    for (auto namedAttr : attributes)
+      $_state.addAttribute(namedAttr.getName(), namedAttr.getValue());
   }]>;
 
 // Compatibility builder that takes an instance of wrapped llvm::VoidType

diff  --git a/mlir/include/mlir/IR/Attributes.h b/mlir/include/mlir/IR/Attributes.h
index b7e3c089afa70..3a2e8b16eb9c3 100644
--- a/mlir/include/mlir/IR/Attributes.h
+++ b/mlir/include/mlir/IR/Attributes.h
@@ -136,13 +136,60 @@ inline ::llvm::hash_code hash_value(Attribute arg) {
 // NamedAttribute
 //===----------------------------------------------------------------------===//
 
-/// NamedAttribute is combination of a name, represented by a StringAttr, and a
-/// value, represented by an Attribute. The attribute pointer should always be
-/// non-null.
-using NamedAttribute = std::pair<StringAttr, Attribute>;
+/// NamedAttribute represents a combination of a name and an Attribute value.
+class NamedAttribute {
+public:
+  NamedAttribute(StringAttr name, Attribute value);
+
+  /// Return the name of the attribute.
+  StringAttr getName() const;
+
+  /// Return the dialect of the name of this attribute, if the name is prefixed
+  /// by a dialect namespace. For example, `llvm.fast_math` would return the
+  /// LLVM dialect (if it is loaded). Returns nullptr if the dialect isn't
+  /// loaded, or if the name is not prefixed by a dialect namespace.
+  Dialect *getNameDialect() const;
+
+  /// Return the value of the attribute.
+  Attribute getValue() const { return value; }
+
+  /// Set the name of this attribute.
+  void setName(StringAttr newName);
+
+  /// Set the value of this attribute.
+  void setValue(Attribute newValue) {
+    assert(value && "expected valid attribute value");
+    value = newValue;
+  }
+
+  /// Compare this attribute to the provided attribute, ordering by name.
+  bool operator<(const NamedAttribute &rhs) const;
+  /// Compare this attribute to the provided string, ordering by name.
+  bool operator<(StringRef rhs) const;
+
+  bool operator==(const NamedAttribute &rhs) const {
+    return name == rhs.name && value == rhs.value;
+  }
+  bool operator!=(const NamedAttribute &rhs) const { return !(*this == rhs); }
+
+private:
+  NamedAttribute(Attribute name, Attribute value) : name(name), value(value) {}
 
-bool operator<(const NamedAttribute &lhs, const NamedAttribute &rhs);
-bool operator<(const NamedAttribute &lhs, StringRef rhs);
+  /// Allow access to internals to enable hashing.
+  friend ::llvm::hash_code hash_value(const NamedAttribute &arg);
+  friend DenseMapInfo<NamedAttribute>;
+
+  /// The name of the attribute. This is represented as a StringAttr, but
+  /// type-erased to Attribute in the field.
+  Attribute name;
+  /// The value of the attribute.
+  Attribute value;
+};
+
+inline ::llvm::hash_code hash_value(const NamedAttribute &arg) {
+  using AttrPairT = std::pair<Attribute, Attribute>;
+  return DenseMapInfo<AttrPairT>::getHashValue(AttrPairT(arg.name, arg.value));
+}
 
 //===----------------------------------------------------------------------===//
 // AttributeTraitBase
@@ -227,6 +274,23 @@ template <> struct PointerLikeTypeTraits<mlir::Attribute> {
       mlir::AttributeStorage *>::NumLowBitsAvailable;
 };
 
+template <> struct DenseMapInfo<mlir::NamedAttribute> {
+  static mlir::NamedAttribute getEmptyKey() {
+    auto emptyAttr = llvm::DenseMapInfo<mlir::Attribute>::getEmptyKey();
+    return mlir::NamedAttribute(emptyAttr, emptyAttr);
+  }
+  static mlir::NamedAttribute getTombstoneKey() {
+    auto tombAttr = llvm::DenseMapInfo<mlir::Attribute>::getTombstoneKey();
+    return mlir::NamedAttribute(tombAttr, tombAttr);
+  }
+  static unsigned getHashValue(mlir::NamedAttribute val) {
+    return mlir::hash_value(val);
+  }
+  static bool isEqual(mlir::NamedAttribute lhs, mlir::NamedAttribute rhs) {
+    return lhs == rhs;
+  }
+};
+
 } // namespace llvm
 
 #endif

diff  --git a/mlir/include/mlir/IR/FunctionSupport.h b/mlir/include/mlir/IR/FunctionSupport.h
index 3add909d742e7..d86500fffa972 100644
--- a/mlir/include/mlir/IR/FunctionSupport.h
+++ b/mlir/include/mlir/IR/FunctionSupport.h
@@ -609,10 +609,10 @@ LogicalResult FunctionLike<ConcreteType>::verifyTrait(Operation *op) {
       // that they contain a dialect prefix in their name.  Call the dialect, if
       // registered, to verify the attributes themselves.
       for (auto attr : argAttrs) {
-        if (!attr.first.strref().contains('.'))
+        if (!attr.getName().strref().contains('.'))
           return funcOp.emitOpError(
               "arguments may only have dialect attributes");
-        if (Dialect *dialect = attr.first.getReferencedDialect()) {
+        if (Dialect *dialect = attr.getNameDialect()) {
           if (failed(dialect->verifyRegionArgAttribute(op, /*regionIndex=*/0,
                                                        /*argIndex=*/i, attr)))
             return failure();
@@ -643,9 +643,9 @@ LogicalResult FunctionLike<ConcreteType>::verifyTrait(Operation *op) {
       // that they contain a dialect prefix in their name.  Call the dialect, if
       // registered, to verify the attributes themselves.
       for (auto attr : resultAttrs) {
-        if (!attr.first.strref().contains('.'))
+        if (!attr.getName().strref().contains('.'))
           return funcOp.emitOpError("results may only have dialect attributes");
-        if (Dialect *dialect = attr.first.getReferencedDialect()) {
+        if (Dialect *dialect = attr.getNameDialect()) {
           if (failed(dialect->verifyRegionResultAttribute(op, /*regionIndex=*/0,
                                                           /*resultIndex=*/i,
                                                           attr)))

diff  --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h
index 243870a7b030d..e03986b688539 100644
--- a/mlir/include/mlir/IR/Operation.h
+++ b/mlir/include/mlir/IR/Operation.h
@@ -373,7 +373,7 @@ class alignas(8) Operation final
                                      bool (*)(NamedAttribute)> {
     static bool filter(NamedAttribute attr) {
       // Dialect attributes are prefixed by the dialect name, like operations.
-      return attr.first.strref().count('.');
+      return attr.getName().strref().count('.');
     }
 
     explicit dialect_attr_iterator(ArrayRef<NamedAttribute>::iterator it,
@@ -407,7 +407,7 @@ class alignas(8) Operation final
     NamedAttrList attrs;
     attrs.append(std::begin(dialectAttrs), std::end(dialectAttrs));
     for (auto attr : getAttrs())
-      if (!attr.first.strref().contains('.'))
+      if (!attr.getName().strref().contains('.'))
         attrs.push_back(attr);
     setAttrs(attrs.getDictionary(getContext()));
   }

diff  --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h
index ba81329867b6e..d16b19bf309be 100644
--- a/mlir/include/mlir/IR/OperationSupport.h
+++ b/mlir/include/mlir/IR/OperationSupport.h
@@ -382,7 +382,7 @@ template <typename IteratorT, typename NameT>
 std::pair<IteratorT, bool> findAttrUnsorted(IteratorT first, IteratorT last,
                                             NameT name) {
   for (auto it = first; it != last; ++it)
-    if (it->first == name)
+    if (it->getName() == name)
       return {it, true};
   return {last, false};
 }
@@ -399,7 +399,7 @@ std::pair<IteratorT, bool> findAttrSorted(IteratorT first, IteratorT last,
   while (length > 0) {
     ptr
diff _t half = length / 2;
     IteratorT mid = first + half;
-    int compare = mid->first.strref().compare(name);
+    int compare = mid->getName().strref().compare(name);
     if (compare < 0) {
       first = mid + 1;
       length = length - half - 1;

diff  --git a/mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h b/mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h
index 875c79903b1fd..0531c0ec953fe 100644
--- a/mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h
+++ b/mlir/include/mlir/Target/LLVMIR/LLVMTranslationInterface.h
@@ -81,7 +81,7 @@ class LLVMTranslationInterface
   amendOperation(Operation *op, NamedAttribute attribute,
                  LLVM::ModuleTranslation &moduleTranslation) const {
     if (const LLVMTranslationDialectInterface *iface =
-            getInterfaceFor(attribute.first.getReferencedDialect())) {
+            getInterfaceFor(attribute.getNameDialect())) {
       return iface->amendOperation(op, attribute, moduleTranslation);
     }
     return success();

diff  --git a/mlir/lib/CAPI/IR/BuiltinAttributes.cpp b/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
index 5ec7e34688dc1..c20548bd47597 100644
--- a/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
+++ b/mlir/lib/CAPI/IR/BuiltinAttributes.cpp
@@ -83,7 +83,7 @@ MlirNamedAttribute mlirDictionaryAttrGetElement(MlirAttribute attr,
                                                 intptr_t pos) {
   NamedAttribute attribute =
       unwrap(attr).cast<DictionaryAttr>().getValue()[pos];
-  return {wrap(attribute.first), wrap(attribute.second)};
+  return {wrap(attribute.getName()), wrap(attribute.getValue())};
 }
 
 MlirAttribute mlirDictionaryAttrGetElementByName(MlirAttribute attr,

diff  --git a/mlir/lib/CAPI/IR/IR.cpp b/mlir/lib/CAPI/IR/IR.cpp
index 11b0157ae688c..35a059275ffb2 100644
--- a/mlir/lib/CAPI/IR/IR.cpp
+++ b/mlir/lib/CAPI/IR/IR.cpp
@@ -432,7 +432,7 @@ intptr_t mlirOperationGetNumAttributes(MlirOperation op) {
 
 MlirNamedAttribute mlirOperationGetAttribute(MlirOperation op, intptr_t pos) {
   NamedAttribute attr = unwrap(op)->getAttrs()[pos];
-  return MlirNamedAttribute{wrap(attr.first), wrap(attr.second)};
+  return MlirNamedAttribute{wrap(attr.getName()), wrap(attr.getValue())};
 }
 
 MlirAttribute mlirOperationGetAttributeByName(MlirOperation op,

diff  --git a/mlir/lib/Conversion/GPUCommon/GPUOpsLowering.cpp b/mlir/lib/Conversion/GPUCommon/GPUOpsLowering.cpp
index 27be2cfe3ad5c..ba986aa87dbbc 100644
--- a/mlir/lib/Conversion/GPUCommon/GPUOpsLowering.cpp
+++ b/mlir/lib/Conversion/GPUCommon/GPUOpsLowering.cpp
@@ -55,9 +55,9 @@ GPUFuncOpLowering::matchAndRewrite(gpu::GPUFuncOp gpuFuncOp, OpAdaptor adaptor,
   // not specific to function modeling.
   SmallVector<NamedAttribute, 4> attributes;
   for (const auto &attr : gpuFuncOp->getAttrs()) {
-    if (attr.first == SymbolTable::getSymbolAttrName() ||
-        attr.first == function_like_impl::getTypeAttrName() ||
-        attr.first == gpu::GPUFuncOp::getNumWorkgroupAttributionsAttrName())
+    if (attr.getName() == SymbolTable::getSymbolAttrName() ||
+        attr.getName() == function_like_impl::getTypeAttrName() ||
+        attr.getName() == gpu::GPUFuncOp::getNumWorkgroupAttributionsAttrName())
       continue;
     attributes.push_back(attr);
   }

diff  --git a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
index fd047b2a43e07..7405f6f91a4fa 100644
--- a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
+++ b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
@@ -216,10 +216,10 @@ lowerAsEntryFunction(gpu::GPUFuncOp funcOp, TypeConverter &typeConverter,
       rewriter.getFunctionType(signatureConverter.getConvertedTypes(),
                                llvm::None));
   for (const auto &namedAttr : funcOp->getAttrs()) {
-    if (namedAttr.first == function_like_impl::getTypeAttrName() ||
-        namedAttr.first == SymbolTable::getSymbolAttrName())
+    if (namedAttr.getName() == function_like_impl::getTypeAttrName() ||
+        namedAttr.getName() == SymbolTable::getSymbolAttrName())
       continue;
-    newFuncOp->setAttr(namedAttr.first, namedAttr.second);
+    newFuncOp->setAttr(namedAttr.getName(), namedAttr.getValue());
   }
 
   rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(),

diff  --git a/mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp b/mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp
index 7142e968d51da..2e46ca18782dc 100644
--- a/mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp
+++ b/mlir/lib/Conversion/SCFToGPU/SCFToGPU.cpp
@@ -544,10 +544,10 @@ static LogicalResult processParallelLoop(
   // Propagate custom user defined optional attributes, that can be used at
   // later stage, such as extension data for GPU kernel dispatch
   for (const auto &namedAttr : parallelOp->getAttrs()) {
-    if (namedAttr.first == gpu::getMappingAttrName() ||
-        namedAttr.first == ParallelOp::getOperandSegmentSizeAttr())
+    if (namedAttr.getName() == gpu::getMappingAttrName() ||
+        namedAttr.getName() == ParallelOp::getOperandSegmentSizeAttr())
       continue;
-    launchOp->setAttr(namedAttr.first, namedAttr.second);
+    launchOp->setAttr(namedAttr.getName(), namedAttr.getValue());
   }
 
   Block *body = parallelOp.getBody();

diff  --git a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp
index 0aad8177b0d4d..83f45721d853a 100644
--- a/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp
+++ b/mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp
@@ -53,11 +53,11 @@ static void filterFuncAttributes(ArrayRef<NamedAttribute> attrs,
                                  bool filterArgAttrs,
                                  SmallVectorImpl<NamedAttribute> &result) {
   for (const auto &attr : attrs) {
-    if (attr.first == SymbolTable::getSymbolAttrName() ||
-        attr.first == function_like_impl::getTypeAttrName() ||
-        attr.first == "std.varargs" ||
+    if (attr.getName() == SymbolTable::getSymbolAttrName() ||
+        attr.getName() == function_like_impl::getTypeAttrName() ||
+        attr.getName() == "std.varargs" ||
         (filterArgAttrs &&
-         attr.first == function_like_impl::getArgDictAttrName()))
+         attr.getName() == function_like_impl::getArgDictAttrName()))
       continue;
     result.push_back(attr);
   }
@@ -255,7 +255,7 @@ struct FuncOpConversionBase : public ConvertOpToLLVMPattern<FuncOp> {
                                 rewriter.getArrayAttr(newArgAttrs)));
     }
     for (auto pair : llvm::enumerate(attributes)) {
-      if (pair.value().first == "llvm.linkage") {
+      if (pair.value().getName() == "llvm.linkage") {
         attributes.erase(attributes.begin() + pair.index());
         break;
       }
@@ -448,9 +448,9 @@ struct ConstantOpLowering : public ConvertOpToLLVMPattern<ConstantOp> {
       auto newOp = rewriter.create<LLVM::AddressOfOp>(op.getLoc(), type,
                                                       symbolRef.getValue());
       for (const NamedAttribute &attr : op->getAttrs()) {
-        if (attr.first.strref() == "value")
+        if (attr.getName().strref() == "value")
           continue;
-        newOp->setAttr(attr.first, attr.second);
+        newOp->setAttr(attr.getName(), attr.getValue());
       }
       rewriter.replaceOp(op, newOp->getResults());
       return success();

diff  --git a/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp b/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp
index 0861ec093517e..275338918fb0f 100644
--- a/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp
+++ b/mlir/lib/Dialect/Affine/Transforms/SimplifyAffineStructures.cpp
@@ -90,10 +90,10 @@ void SimplifyAffineStructures::runOnFunction() {
   SmallVector<Operation *> opsToSimplify;
   func.walk([&](Operation *op) {
     for (auto attr : op->getAttrs()) {
-      if (auto mapAttr = attr.second.dyn_cast<AffineMapAttr>())
-        simplifyAndUpdateAttribute(op, attr.first, mapAttr);
-      else if (auto setAttr = attr.second.dyn_cast<IntegerSetAttr>())
-        simplifyAndUpdateAttribute(op, attr.first, setAttr);
+      if (auto mapAttr = attr.getValue().dyn_cast<AffineMapAttr>())
+        simplifyAndUpdateAttribute(op, attr.getName(), mapAttr);
+      else if (auto setAttr = attr.getValue().dyn_cast<IntegerSetAttr>())
+        simplifyAndUpdateAttribute(op, attr.getName(), setAttr);
     }
 
     if (isa<AffineForOp, AffineIfOp, AffineApplyOp>(op))

diff  --git a/mlir/lib/Dialect/DLTI/DLTI.cpp b/mlir/lib/Dialect/DLTI/DLTI.cpp
index 86ad28b2823d2..c35572bbf1d44 100644
--- a/mlir/lib/Dialect/DLTI/DLTI.cpp
+++ b/mlir/lib/Dialect/DLTI/DLTI.cpp
@@ -367,8 +367,8 @@ void DLTIDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const {
 
 LogicalResult DLTIDialect::verifyOperationAttribute(Operation *op,
                                                     NamedAttribute attr) {
-  if (attr.first == DLTIDialect::kDataLayoutAttrName) {
-    if (!attr.second.isa<DataLayoutSpecAttr>()) {
+  if (attr.getName() == DLTIDialect::kDataLayoutAttrName) {
+    if (!attr.getValue().isa<DataLayoutSpecAttr>()) {
       return op->emitError() << "'" << DLTIDialect::kDataLayoutAttrName
                              << "' is expected to be a #dlti.dl_spec attribute";
     }
@@ -377,6 +377,6 @@ LogicalResult DLTIDialect::verifyOperationAttribute(Operation *op,
     return success();
   }
 
-  return op->emitError() << "attribute '" << attr.first.getValue()
+  return op->emitError() << "attribute '" << attr.getName().getValue()
                          << "' not supported by dialect";
 }

diff  --git a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
index 9baff7f53ca8f..aa276a42882b9 100644
--- a/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
+++ b/mlir/lib/Dialect/GPU/IR/GPUDialect.cpp
@@ -174,8 +174,8 @@ void GPUDialect::printType(Type type, DialectAsmPrinter &os) const {
 
 LogicalResult GPUDialect::verifyOperationAttribute(Operation *op,
                                                    NamedAttribute attr) {
-  if (!attr.second.isa<UnitAttr>() ||
-      attr.first != getContainerModuleAttrName())
+  if (!attr.getValue().isa<UnitAttr>() ||
+      attr.getName() != getContainerModuleAttrName())
     return success();
 
   auto module = dyn_cast<ModuleOp>(op);

diff  --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
index 0afc64b2ffce0..5577cecf8f52c 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
@@ -51,9 +51,9 @@ static constexpr const char kNonTemporalAttrName[] = "nontemporal";
 static auto processFMFAttr(ArrayRef<NamedAttribute> attrs) {
   SmallVector<NamedAttribute, 8> filteredAttrs(
       llvm::make_filter_range(attrs, [&](NamedAttribute attr) {
-        if (attr.first == "fastmathFlags") {
-          auto defAttr = FMFAttr::get(attr.second.getContext(), {});
-          return defAttr != attr.second;
+        if (attr.getName() == "fastmathFlags") {
+          auto defAttr = FMFAttr::get(attr.getValue().getContext(), {});
+          return defAttr != attr.getValue();
         }
         return true;
       }));
@@ -201,7 +201,8 @@ static ParseResult parseAllocaOp(OpAsmParser &parser, OperationState &result) {
   Optional<NamedAttribute> alignmentAttr =
       result.attributes.getNamed("alignment");
   if (alignmentAttr.hasValue()) {
-    auto alignmentInt = alignmentAttr.getValue().second.dyn_cast<IntegerAttr>();
+    auto alignmentInt =
+        alignmentAttr.getValue().getValue().dyn_cast<IntegerAttr>();
     if (!alignmentInt)
       return parser.emitError(parser.getNameLoc(),
                               "expected integer alignment");
@@ -2317,15 +2318,15 @@ LogicalResult LLVMDialect::verifyOperationAttribute(Operation *op,
                                                     NamedAttribute attr) {
   // If the `llvm.loop` attribute is present, enforce the following structure,
   // which the module translation can assume.
-  if (attr.first.strref() == LLVMDialect::getLoopAttrName()) {
-    auto loopAttr = attr.second.dyn_cast<DictionaryAttr>();
+  if (attr.getName() == LLVMDialect::getLoopAttrName()) {
+    auto loopAttr = attr.getValue().dyn_cast<DictionaryAttr>();
     if (!loopAttr)
       return op->emitOpError() << "expected '" << LLVMDialect::getLoopAttrName()
                                << "' to be a dictionary attribute";
     Optional<NamedAttribute> parallelAccessGroup =
         loopAttr.getNamed(LLVMDialect::getParallelAccessAttrName());
     if (parallelAccessGroup.hasValue()) {
-      auto accessGroups = parallelAccessGroup->second.dyn_cast<ArrayAttr>();
+      auto accessGroups = parallelAccessGroup->getValue().dyn_cast<ArrayAttr>();
       if (!accessGroups)
         return op->emitOpError()
                << "expected '" << LLVMDialect::getParallelAccessAttrName()
@@ -2353,7 +2354,8 @@ LogicalResult LLVMDialect::verifyOperationAttribute(Operation *op,
 
     Optional<NamedAttribute> loopOptions =
         loopAttr.getNamed(LLVMDialect::getLoopOptionsAttrName());
-    if (loopOptions.hasValue() && !loopOptions->second.isa<LoopOptionsAttr>())
+    if (loopOptions.hasValue() &&
+        !loopOptions->getValue().isa<LoopOptionsAttr>())
       return op->emitOpError()
              << "expected '" << LLVMDialect::getLoopOptionsAttrName()
              << "' to be a `loopopts` attribute";
@@ -2363,9 +2365,9 @@ LogicalResult LLVMDialect::verifyOperationAttribute(Operation *op,
   // syntax. Try parsing it and report errors in case of failure. Users of this
   // attribute may assume it is well-formed and can pass it to the (asserting)
   // llvm::DataLayout constructor.
-  if (attr.first.strref() != LLVM::LLVMDialect::getDataLayoutAttrName())
+  if (attr.getName() != LLVM::LLVMDialect::getDataLayoutAttrName())
     return success();
-  if (auto stringAttr = attr.second.dyn_cast<StringAttr>())
+  if (auto stringAttr = attr.getValue().dyn_cast<StringAttr>())
     return verifyDataLayoutString(
         stringAttr.getValue(),
         [op](const Twine &message) { op->emitOpError() << message.str(); });
@@ -2381,13 +2383,13 @@ LogicalResult LLVMDialect::verifyRegionArgAttribute(Operation *op,
                                                     unsigned argIdx,
                                                     NamedAttribute argAttr) {
   // Check that llvm.noalias is a unit attribute.
-  if (argAttr.first == LLVMDialect::getNoAliasAttrName() &&
-      !argAttr.second.isa<UnitAttr>())
+  if (argAttr.getName() == LLVMDialect::getNoAliasAttrName() &&
+      !argAttr.getValue().isa<UnitAttr>())
     return op->emitError()
            << "expected llvm.noalias argument attribute to be a unit attribute";
   // Check that llvm.align is an integer attribute.
-  if (argAttr.first == LLVMDialect::getAlignAttrName() &&
-      !argAttr.second.isa<IntegerAttr>())
+  if (argAttr.getName() == LLVMDialect::getAlignAttrName() &&
+      !argAttr.getValue().isa<IntegerAttr>())
     return op->emitError()
            << "llvm.align argument attribute of non integer type";
   return success();

diff  --git a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
index ff82f9e1eaa66..8d47a81b917cb 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/NVVMDialect.cpp
@@ -57,7 +57,7 @@ static ParseResult parseNVVMShflSyncBflyOp(OpAsmParser &parser,
     return failure();
 
   for (auto &attr : result.attributes) {
-    if (attr.first != "return_value_and_is_valid")
+    if (attr.getName() != "return_value_and_is_valid")
       continue;
     auto structType = resultType.dyn_cast<LLVM::LLVMStructType>();
     if (structType && !structType.getBody().empty())
@@ -249,7 +249,7 @@ void NVVMDialect::initialize() {
 LogicalResult NVVMDialect::verifyOperationAttribute(Operation *op,
                                                     NamedAttribute attr) {
   // Kernel function attribute should be attached to functions.
-  if (attr.first == NVVMDialect::getKernelFuncAttrName()) {
+  if (attr.getName() == NVVMDialect::getKernelFuncAttrName()) {
     if (!isa<LLVM::LLVMFuncOp>(op)) {
       return op->emitError() << "'" << NVVMDialect::getKernelFuncAttrName()
                              << "' attribute attached to unexpected op";

diff  --git a/mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp b/mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp
index 7f145b373f902..19aeeadab01ee 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/ROCDLDialect.cpp
@@ -96,7 +96,7 @@ void ROCDLDialect::initialize() {
 LogicalResult ROCDLDialect::verifyOperationAttribute(Operation *op,
                                                      NamedAttribute attr) {
   // Kernel function attribute should be attached to functions.
-  if (attr.first == ROCDLDialect::getKernelFuncAttrName()) {
+  if (attr.getName() == ROCDLDialect::getKernelFuncAttrName()) {
     if (!isa<LLVM::LLVMFuncOp>(op)) {
       return op->emitError() << "'" << ROCDLDialect::getKernelFuncAttrName()
                              << "' attribute attached to unexpected op";

diff  --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
index e792e4109aa05..9ef930cb204c1 100644
--- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
@@ -583,7 +583,7 @@ static void print(OpAsmPrinter &p, GenericOp op) {
   genericAttrNamesSet.insert(genericAttrNames.begin(), genericAttrNames.end());
   SmallVector<NamedAttribute, 8> genericAttrs;
   for (auto attr : op->getAttrs())
-    if (genericAttrNamesSet.count(attr.first.strref()) > 0)
+    if (genericAttrNamesSet.count(attr.getName().strref()) > 0)
       genericAttrs.push_back(attr);
   if (!genericAttrs.empty()) {
     auto genericDictAttr = DictionaryAttr::get(op.getContext(), genericAttrs);
@@ -598,7 +598,7 @@ static void print(OpAsmPrinter &p, GenericOp op) {
 
   bool hasExtraAttrs = false;
   for (NamedAttribute n : op->getAttrs()) {
-    if ((hasExtraAttrs = !genericAttrNamesSet.contains(n.first.strref())))
+    if ((hasExtraAttrs = !genericAttrNamesSet.contains(n.getName().strref())))
       break;
   }
   if (hasExtraAttrs) {
@@ -753,8 +753,8 @@ struct DeduplicateGenericOpInputs : public OpRewritePattern<GenericOp> {
     // Copy over unknown attributes. They might be load bearing for some flow.
     ArrayRef<StringRef> odsAttrs = genericOp.getAttributeNames();
     for (NamedAttribute kv : genericOp->getAttrs()) {
-      if (!llvm::is_contained(odsAttrs, kv.first.getValue())) {
-        newOp->setAttr(kv.first, kv.second);
+      if (!llvm::is_contained(odsAttrs, kv.getName().getValue())) {
+        newOp->setAttr(kv.getName(), kv.getValue());
       }
     }
 

diff  --git a/mlir/lib/Dialect/Linalg/IR/LinalgTypes.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgTypes.cpp
index 685ec000e4f39..4ea37ce25c641 100644
--- a/mlir/lib/Dialect/Linalg/IR/LinalgTypes.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/LinalgTypes.cpp
@@ -152,30 +152,30 @@ LogicalResult LinalgDialect::verifyOperationAttribute(Operation *op,
                                                       NamedAttribute attr) {
   using comprehensive_bufferize::BufferizableOpInterface;
 
-  if (attr.first == BufferizableOpInterface::kInplaceableAttrName) {
-    if (!attr.second.isa<BoolAttr>()) {
+  if (attr.getName() == BufferizableOpInterface::kInplaceableAttrName) {
+    if (!attr.getValue().isa<BoolAttr>()) {
       return op->emitError()
              << "'" << BufferizableOpInterface::kInplaceableAttrName
              << "' is expected to be a boolean attribute";
     }
     if (!op->hasTrait<OpTrait::FunctionLike>())
-      return op->emitError() << "expected " << attr.first
+      return op->emitError() << "expected " << attr.getName()
                              << " to be used on function-like operations";
     return success();
   }
-  if (attr.first == BufferizableOpInterface::kBufferLayoutAttrName) {
-    if (!attr.second.isa<AffineMapAttr>()) {
+  if (attr.getName() == BufferizableOpInterface::kBufferLayoutAttrName) {
+    if (!attr.getValue().isa<AffineMapAttr>()) {
       return op->emitError()
              << "'" << BufferizableOpInterface::kBufferLayoutAttrName
              << "' is expected to be a affine map attribute";
     }
     if (!op->hasTrait<OpTrait::FunctionLike>())
-      return op->emitError() << "expected " << attr.first
+      return op->emitError() << "expected " << attr.getName()
                              << " to be used on function-like operations";
     return success();
   }
-  if (attr.first == LinalgDialect::kMemoizedIndexingMapsAttrName)
+  if (attr.getName() == LinalgDialect::kMemoizedIndexingMapsAttrName)
     return success();
-  return op->emitError() << "attribute '" << attr.first
+  return op->emitError() << "attribute '" << attr.getName()
                          << "' not supported by the linalg dialect";
 }

diff  --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp b/mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp
index 6537710b92e09..e48ded448717e 100644
--- a/mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp
@@ -1211,8 +1211,8 @@ Operation *SPIRVDialect::materializeConstant(OpBuilder &builder,
 
 LogicalResult SPIRVDialect::verifyOperationAttribute(Operation *op,
                                                      NamedAttribute attribute) {
-  StringRef symbol = attribute.first.strref();
-  Attribute attr = attribute.second;
+  StringRef symbol = attribute.getName().strref();
+  Attribute attr = attribute.getValue();
 
   // TODO: figure out a way to generate the description from the
   // StructAttr definition.
@@ -1237,8 +1237,8 @@ LogicalResult SPIRVDialect::verifyOperationAttribute(Operation *op,
 /// `valueType` is valid.
 static LogicalResult verifyRegionAttribute(Location loc, Type valueType,
                                            NamedAttribute attribute) {
-  StringRef symbol = attribute.first.strref();
-  Attribute attr = attribute.second;
+  StringRef symbol = attribute.getName().strref();
+  Attribute attr = attribute.getValue();
 
   if (symbol != spirv::getInterfaceVarABIAttrName())
     return emitError(loc, "found unsupported '")

diff  --git a/mlir/lib/Dialect/SPIRV/Linking/ModuleCombiner/ModuleCombiner.cpp b/mlir/lib/Dialect/SPIRV/Linking/ModuleCombiner/ModuleCombiner.cpp
index 69e685973a9a5..80e8f3c185f26 100644
--- a/mlir/lib/Dialect/SPIRV/Linking/ModuleCombiner/ModuleCombiner.cpp
+++ b/mlir/lib/Dialect/SPIRV/Linking/ModuleCombiner/ModuleCombiner.cpp
@@ -76,7 +76,7 @@ static LogicalResult updateSymbolAndAllUses(SymbolOpInterface op,
 static llvm::hash_code computeHash(SymbolOpInterface symbolOp) {
   auto range =
       llvm::make_filter_range(symbolOp->getAttrs(), [](NamedAttribute attr) {
-        return attr.first != SymbolTable::getSymbolAttrName();
+        return attr.getName() != SymbolTable::getSymbolAttrName();
       });
 
   return llvm::hash_combine(

diff  --git a/mlir/lib/Dialect/SPIRV/Transforms/DecorateCompositeTypeLayoutPass.cpp b/mlir/lib/Dialect/SPIRV/Transforms/DecorateCompositeTypeLayoutPass.cpp
index 2a46819f1d168..b1772c2645c7e 100644
--- a/mlir/lib/Dialect/SPIRV/Transforms/DecorateCompositeTypeLayoutPass.cpp
+++ b/mlir/lib/Dialect/SPIRV/Transforms/DecorateCompositeTypeLayoutPass.cpp
@@ -44,9 +44,8 @@ class SPIRVGlobalVariableOpLayoutInfoDecoration
 
     // Save all named attributes except "type" attribute.
     for (const auto &attr : op->getAttrs()) {
-      if (attr.first == "type") {
+      if (attr.getName() == "type")
         continue;
-      }
       globalVarAttrs.push_back(attr);
     }
 

diff  --git a/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp b/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
index fd269851ee8c8..99e7a6684a909 100644
--- a/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
+++ b/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
@@ -580,9 +580,9 @@ FuncOpConversion::matchAndRewrite(FuncOp funcOp, OpAdaptor adaptor,
 
   // Copy over all attributes other than the function name and type.
   for (const auto &namedAttr : funcOp->getAttrs()) {
-    if (namedAttr.first != function_like_impl::getTypeAttrName() &&
-        namedAttr.first != SymbolTable::getSymbolAttrName())
-      newFuncOp->setAttr(namedAttr.first, namedAttr.second);
+    if (namedAttr.getName() != function_like_impl::getTypeAttrName() &&
+        namedAttr.getName() != SymbolTable::getSymbolAttrName())
+      newFuncOp->setAttr(namedAttr.getName(), namedAttr.getValue());
   }
 
   rewriter.inlineRegionBefore(funcOp.getBody(), newFuncOp.getBody(),

diff  --git a/mlir/lib/Dialect/Shape/IR/Shape.cpp b/mlir/lib/Dialect/Shape/IR/Shape.cpp
index f6978935d73a0..0764b0920db67 100644
--- a/mlir/lib/Dialect/Shape/IR/Shape.cpp
+++ b/mlir/lib/Dialect/Shape/IR/Shape.cpp
@@ -188,12 +188,12 @@ void ShapeDialect::printType(Type type, DialectAsmPrinter &os) const {
 LogicalResult ShapeDialect::verifyOperationAttribute(Operation *op,
                                                      NamedAttribute attribute) {
   // Verify shape.lib attribute.
-  if (attribute.first == "shape.lib") {
+  if (attribute.getName() == "shape.lib") {
     if (!op->hasTrait<OpTrait::SymbolTable>())
       return op->emitError(
           "shape.lib attribute may only be on op implementing SymbolTable");
 
-    if (auto symbolRef = attribute.second.dyn_cast<SymbolRefAttr>()) {
+    if (auto symbolRef = attribute.getValue().dyn_cast<SymbolRefAttr>()) {
       auto *symbol = SymbolTable::lookupSymbolIn(op, symbolRef);
       if (!symbol)
         return op->emitError("shape function library ")
@@ -204,7 +204,7 @@ LogicalResult ShapeDialect::verifyOperationAttribute(Operation *op,
                        << symbolRef << " required to be shape function library";
     }
 
-    if (auto arr = attribute.second.dyn_cast<ArrayAttr>()) {
+    if (auto arr = attribute.getValue().dyn_cast<ArrayAttr>()) {
       // Verify all entries are function libraries and mappings in libraries
       // refer to unique ops.
       DenseSet<StringAttr> key;
@@ -219,10 +219,10 @@ LogicalResult ShapeDialect::verifyOperationAttribute(Operation *op,
           return op->emitError()
                  << it << " does not refer to FunctionLibraryOp";
         for (auto mapping : shapeFnLib.getMapping()) {
-          if (!key.insert(mapping.first).second) {
+          if (!key.insert(mapping.getName()).second) {
             return op->emitError("only one op to shape mapping allowed, found "
                                  "multiple for `")
-                   << mapping.first << "`";
+                   << mapping.getName() << "`";
           }
         }
       }

diff  --git a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
index 6cbb7f5dc7b21..9bc1e824760a2 100644
--- a/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
+++ b/mlir/lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp
@@ -54,8 +54,8 @@ Attribute SparseTensorEncodingAttr::parse(AsmParser &parser, Type type) {
   unsigned ptr = 0;
   unsigned ind = 0;
   for (const NamedAttribute &attr : dict) {
-    if (attr.first == "dimLevelType") {
-      auto arrayAttr = attr.second.dyn_cast<ArrayAttr>();
+    if (attr.getName() == "dimLevelType") {
+      auto arrayAttr = attr.getValue().dyn_cast<ArrayAttr>();
       if (!arrayAttr) {
         parser.emitError(parser.getNameLoc(),
                          "expected an array for dimension level types");
@@ -82,24 +82,24 @@ Attribute SparseTensorEncodingAttr::parse(AsmParser &parser, Type type) {
           return {};
         }
       }
-    } else if (attr.first == "dimOrdering") {
-      auto affineAttr = attr.second.dyn_cast<AffineMapAttr>();
+    } else if (attr.getName() == "dimOrdering") {
+      auto affineAttr = attr.getValue().dyn_cast<AffineMapAttr>();
       if (!affineAttr) {
         parser.emitError(parser.getNameLoc(),
                          "expected an affine map for dimension ordering");
         return {};
       }
       map = affineAttr.getValue();
-    } else if (attr.first == "pointerBitWidth") {
-      auto intAttr = attr.second.dyn_cast<IntegerAttr>();
+    } else if (attr.getName() == "pointerBitWidth") {
+      auto intAttr = attr.getValue().dyn_cast<IntegerAttr>();
       if (!intAttr) {
         parser.emitError(parser.getNameLoc(),
                          "expected an integral pointer bitwidth");
         return {};
       }
       ptr = intAttr.getInt();
-    } else if (attr.first == "indexBitWidth") {
-      auto intAttr = attr.second.dyn_cast<IntegerAttr>();
+    } else if (attr.getName() == "indexBitWidth") {
+      auto intAttr = attr.getValue().dyn_cast<IntegerAttr>();
       if (!intAttr) {
         parser.emitError(parser.getNameLoc(),
                          "expected an integral index bitwidth");
@@ -108,7 +108,7 @@ Attribute SparseTensorEncodingAttr::parse(AsmParser &parser, Type type) {
       ind = intAttr.getInt();
     } else {
       parser.emitError(parser.getNameLoc(), "unexpected key: ")
-          << attr.first.str();
+          << attr.getName().strref();
       return {};
     }
   }

diff  --git a/mlir/lib/Dialect/Vector/VectorOps.cpp b/mlir/lib/Dialect/Vector/VectorOps.cpp
index 5b4f1abc570ed..b03c4ecf867ae 100644
--- a/mlir/lib/Dialect/Vector/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/VectorOps.cpp
@@ -486,7 +486,7 @@ static void print(OpAsmPrinter &p, ContractionOp op) {
   traitAttrsSet.insert(attrNames.begin(), attrNames.end());
   SmallVector<NamedAttribute, 8> attrs;
   for (auto attr : op->getAttrs())
-    if (traitAttrsSet.count(attr.first.strref()) > 0)
+    if (traitAttrsSet.count(attr.getName().strref()) > 0)
       attrs.push_back(attr);
 
   auto dictAttr = DictionaryAttr::get(op.getContext(), attrs);

diff  --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp
index 50b10bf1e4e01..454a42e9f40b7 100644
--- a/mlir/lib/IR/AsmPrinter.cpp
+++ b/mlir/lib/IR/AsmPrinter.cpp
@@ -411,7 +411,7 @@ class DummyAliasOperationPrinter : private OpAsmPrinter {
 
     // Consider the attributes of the operation for aliases.
     for (const NamedAttribute &attr : op->getAttrs())
-      printAttribute(attr.second);
+      printAttribute(attr.getValue());
   }
 
   /// Print the given block. If 'printBlockArgs' is false, the arguments of the
@@ -483,14 +483,14 @@ class DummyAliasOperationPrinter : private OpAsmPrinter {
       return;
     if (elidedAttrs.empty()) {
       for (const NamedAttribute &attr : attrs)
-        printAttribute(attr.second);
+        printAttribute(attr.getValue());
       return;
     }
     llvm::SmallDenseSet<StringRef> elidedAttrsSet(elidedAttrs.begin(),
                                                   elidedAttrs.end());
     for (const NamedAttribute &attr : attrs)
-      if (!elidedAttrsSet.contains(attr.first.strref()))
-        printAttribute(attr.second);
+      if (!elidedAttrsSet.contains(attr.getName().strref()))
+        printAttribute(attr.getValue());
   }
   void printOptionalAttrDictWithKeyword(
       ArrayRef<NamedAttribute> attrs,
@@ -2031,24 +2031,22 @@ void AsmPrinter::Impl::printOptionalAttrDict(ArrayRef<NamedAttribute> attrs,
   llvm::SmallDenseSet<StringRef> elidedAttrsSet(elidedAttrs.begin(),
                                                 elidedAttrs.end());
   auto filteredAttrs = llvm::make_filter_range(attrs, [&](NamedAttribute attr) {
-    return !elidedAttrsSet.contains(attr.first.strref());
+    return !elidedAttrsSet.contains(attr.getName().strref());
   });
   if (!filteredAttrs.empty())
     printFilteredAttributesFn(filteredAttrs);
 }
 
 void AsmPrinter::Impl::printNamedAttribute(NamedAttribute attr) {
-  assert(attr.first.size() != 0 && "expected valid named attribute");
-
   // Print the name without quotes if possible.
-  ::printKeywordOrString(attr.first.strref(), os);
+  ::printKeywordOrString(attr.getName().strref(), os);
 
   // Pretty printing elides the attribute value for unit attributes.
-  if (attr.second.isa<UnitAttr>())
+  if (attr.getValue().isa<UnitAttr>())
     return;
 
   os << " = ";
-  printAttribute(attr.second);
+  printAttribute(attr.getValue());
 }
 
 void AsmPrinter::Impl::printDialectAttribute(Attribute attr) {

diff  --git a/mlir/lib/IR/Attributes.cpp b/mlir/lib/IR/Attributes.cpp
index dc6149fc262f0..4e585da7d9090 100644
--- a/mlir/lib/IR/Attributes.cpp
+++ b/mlir/lib/IR/Attributes.cpp
@@ -23,9 +23,27 @@ MLIRContext *Attribute::getContext() const { return getDialect().getContext(); }
 // NamedAttribute
 //===----------------------------------------------------------------------===//
 
-bool mlir::operator<(const NamedAttribute &lhs, const NamedAttribute &rhs) {
-  return lhs.first.compare(rhs.first) < 0;
+NamedAttribute::NamedAttribute(StringAttr name, Attribute value)
+    : name(name), value(value) {
+  assert(name && value && "expected valid attribute name and value");
+  assert(name.size() != 0 && "expected valid attribute name");
 }
-bool mlir::operator<(const NamedAttribute &lhs, StringRef rhs) {
-  return lhs.first.getValue().compare(rhs) < 0;
+
+StringAttr NamedAttribute::getName() const { return name.cast<StringAttr>(); }
+
+Dialect *NamedAttribute::getNameDialect() const {
+  return getName().getReferencedDialect();
+}
+
+void NamedAttribute::setName(StringAttr newName) {
+  assert(name && "expected valid attribute name");
+  name = newName;
+}
+
+bool NamedAttribute::operator<(const NamedAttribute &rhs) const {
+  return getName().compare(rhs.getName()) < 0;
+}
+
+bool NamedAttribute::operator<(StringRef rhs) const {
+  return getName().getValue().compare(rhs) < 0;
 }

diff  --git a/mlir/lib/IR/BuiltinAttributes.cpp b/mlir/lib/IR/BuiltinAttributes.cpp
index d4477fe591350..211687166b501 100644
--- a/mlir/lib/IR/BuiltinAttributes.cpp
+++ b/mlir/lib/IR/BuiltinAttributes.cpp
@@ -119,11 +119,12 @@ findDuplicateElement(ArrayRef<NamedAttribute> value) {
     return none;
 
   if (value.size() == 2)
-    return value[0].first == value[1].first ? value[0] : none;
+    return value[0].getName() == value[1].getName() ? value[0] : none;
 
-  auto it = std::adjacent_find(
-      value.begin(), value.end(),
-      [](NamedAttribute l, NamedAttribute r) { return l.first == r.first; });
+  auto it = std::adjacent_find(value.begin(), value.end(),
+                               [](NamedAttribute l, NamedAttribute r) {
+                                 return l.getName() == r.getName();
+                               });
   return it != value.end() ? *it : none;
 }
 
@@ -154,9 +155,6 @@ DictionaryAttr DictionaryAttr::get(MLIRContext *context,
                                    ArrayRef<NamedAttribute> value) {
   if (value.empty())
     return DictionaryAttr::getEmpty(context);
-  assert(llvm::all_of(value,
-                      [](const NamedAttribute &attr) { return attr.second; }) &&
-         "value cannot have null entries");
 
   // We need to sort the element list to canonicalize it.
   SmallVector<NamedAttribute, 8> storage;
@@ -173,10 +171,8 @@ DictionaryAttr DictionaryAttr::getWithSorted(MLIRContext *context,
   if (value.empty())
     return DictionaryAttr::getEmpty(context);
   // Ensure that the attribute elements are unique and sorted.
-  assert(llvm::is_sorted(value,
-                         [](NamedAttribute l, NamedAttribute r) {
-                           return l.first.strref() < r.first.strref();
-                         }) &&
+  assert(llvm::is_sorted(
+             value, [](NamedAttribute l, NamedAttribute r) { return l < r; }) &&
          "expected attribute values to be sorted");
   assert(!findDuplicateElement(value) &&
          "DictionaryAttr element names must be unique");
@@ -186,11 +182,11 @@ DictionaryAttr DictionaryAttr::getWithSorted(MLIRContext *context,
 /// Return the specified attribute if present, null otherwise.
 Attribute DictionaryAttr::get(StringRef name) const {
   auto it = impl::findAttrSorted(begin(), end(), name);
-  return it.second ? it.first->second : Attribute();
+  return it.second ? it.first->getValue() : Attribute();
 }
 Attribute DictionaryAttr::get(StringAttr name) const {
   auto it = impl::findAttrSorted(begin(), end(), name);
-  return it.second ? it.first->second : Attribute();
+  return it.second ? it.first->getValue() : Attribute();
 }
 
 /// Return the specified named attribute if present, None otherwise.
@@ -226,16 +222,16 @@ DictionaryAttr DictionaryAttr::getEmptyUnchecked(MLIRContext *context) {
 void DictionaryAttr::walkImmediateSubElements(
     function_ref<void(Attribute)> walkAttrsFn,
     function_ref<void(Type)> walkTypesFn) const {
-  for (Attribute attr : llvm::make_second_range(getValue()))
-    walkAttrsFn(attr);
+  for (const NamedAttribute &attr : getValue())
+    walkAttrsFn(attr.getValue());
 }
 
 SubElementAttrInterface DictionaryAttr::replaceImmediateSubAttribute(
     ArrayRef<std::pair<size_t, Attribute>> replacements) const {
   std::vector<NamedAttribute> vec = getValue().vec();
-  for (auto &it : replacements) {
-    vec[it.first].second = it.second;
-  }
+  for (auto &it : replacements)
+    vec[it.first].setValue(it.second);
+
   // The above only modifies the mapped value, but not the key, and therefore
   // not the order of the elements. It remains sorted
   return getWithSorted(getContext(), vec);

diff  --git a/mlir/lib/IR/BuiltinDialect.cpp b/mlir/lib/IR/BuiltinDialect.cpp
index 3dd653ddf3dcd..53d560827db17 100644
--- a/mlir/lib/IR/BuiltinDialect.cpp
+++ b/mlir/lib/IR/BuiltinDialect.cpp
@@ -153,12 +153,17 @@ static LogicalResult verify(FuncOp op) {
 /// from this function to dest.
 void FuncOp::cloneInto(FuncOp dest, BlockAndValueMapping &mapper) {
   // Add the attributes of this function to dest.
-  llvm::MapVector<StringAttr, Attribute> newAttrs;
+  llvm::MapVector<StringAttr, Attribute> newAttrMap;
   for (const auto &attr : dest->getAttrs())
-    newAttrs.insert(attr);
+    newAttrMap.insert({attr.getName(), attr.getValue()});
   for (const auto &attr : (*this)->getAttrs())
-    newAttrs.insert(attr);
-  dest->setAttrs(DictionaryAttr::get(getContext(), newAttrs.takeVector()));
+    newAttrMap.insert({attr.getName(), attr.getValue()});
+
+  auto newAttrs = llvm::to_vector(llvm::map_range(
+      newAttrMap, [](std::pair<StringAttr, Attribute> attrPair) {
+        return NamedAttribute(attrPair.first, attrPair.second);
+      }));
+  dest->setAttrs(DictionaryAttr::get(getContext(), newAttrs));
 
   // Clone the body.
   getBody().cloneInto(&dest.getBody(), mapper);
@@ -235,10 +240,9 @@ DataLayoutSpecInterface ModuleOp::getDataLayoutSpec() {
   // Take the first and only (if present) attribute that implements the
   // interface. This needs a linear search, but is called only once per data
   // layout object construction that is used for repeated queries.
-  for (Attribute attr : llvm::make_second_range(getOperation()->getAttrs())) {
-    if (auto spec = attr.dyn_cast<DataLayoutSpecInterface>())
+  for (NamedAttribute attr : getOperation()->getAttrs())
+    if (auto spec = attr.getValue().dyn_cast<DataLayoutSpecInterface>())
       return spec;
-  }
   return {};
 }
 
@@ -246,30 +250,30 @@ static LogicalResult verify(ModuleOp op) {
   // Check that none of the attributes are non-dialect attributes, except for
   // the symbol related attributes.
   for (auto attr : op->getAttrs()) {
-    if (!attr.first.strref().contains('.') &&
+    if (!attr.getName().strref().contains('.') &&
         !llvm::is_contained(
             ArrayRef<StringRef>{mlir::SymbolTable::getSymbolAttrName(),
                                 mlir::SymbolTable::getVisibilityAttrName()},
-            attr.first.strref()))
+            attr.getName().strref()))
       return op.emitOpError() << "can only contain attributes with "
                                  "dialect-prefixed names, found: '"
-                              << attr.first.getValue() << "'";
+                              << attr.getName().getValue() << "'";
   }
 
   // Check that there is at most one data layout spec attribute.
   StringRef layoutSpecAttrName;
   DataLayoutSpecInterface layoutSpec;
   for (const NamedAttribute &na : op->getAttrs()) {
-    if (auto spec = na.second.dyn_cast<DataLayoutSpecInterface>()) {
+    if (auto spec = na.getValue().dyn_cast<DataLayoutSpecInterface>()) {
       if (layoutSpec) {
         InFlightDiagnostic diag =
             op.emitOpError() << "expects at most one data layout attribute";
         diag.attachNote() << "'" << layoutSpecAttrName
                           << "' is a data layout attribute";
-        diag.attachNote() << "'" << na.first.getValue()
+        diag.attachNote() << "'" << na.getName().getValue()
                           << "' is a data layout attribute";
       }
-      layoutSpecAttrName = na.first.strref();
+      layoutSpecAttrName = na.getName().strref();
       layoutSpec = spec;
     }
   }

diff  --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp
index a0303bd3f0e5d..dd76cf6dd6ae3 100644
--- a/mlir/lib/IR/OperationSupport.cpp
+++ b/mlir/lib/IR/OperationSupport.cpp
@@ -72,11 +72,8 @@ void NamedAttrList::assign(const_iterator in_start, const_iterator in_end) {
 }
 
 void NamedAttrList::push_back(NamedAttribute newAttribute) {
-  assert(newAttribute.second && "unexpected null attribute");
-  if (isSorted()) {
-    dictionarySorted.setInt(attrs.empty() ||
-                            attrs.back().first.compare(newAttribute.first) < 0);
-  }
+  if (isSorted())
+    dictionarySorted.setInt(attrs.empty() || attrs.back() < newAttribute);
   dictionarySorted.setPointer(nullptr);
   attrs.push_back(newAttribute);
 }
@@ -84,11 +81,11 @@ void NamedAttrList::push_back(NamedAttribute newAttribute) {
 /// Return the specified attribute if present, null otherwise.
 Attribute NamedAttrList::get(StringRef name) const {
   auto it = findAttr(*this, name);
-  return it.second ? it.first->second : Attribute();
+  return it.second ? it.first->getValue() : Attribute();
 }
 Attribute NamedAttrList::get(StringAttr name) const {
   auto it = findAttr(*this, name);
-  return it.second ? it.first->second : Attribute();
+  return it.second ? it.first->getValue() : Attribute();
 }
 
 /// Return the specified named attribute if present, None otherwise.
@@ -112,12 +109,14 @@ Attribute NamedAttrList::set(StringAttr name, Attribute value) {
   if (it.second) {
     // Update the existing attribute by swapping out the old value for the new
     // value. Return the old value.
-    if (it.first->second != value) {
-      std::swap(it.first->second, value);
+    Attribute oldValue = it.first->getValue();
+    if (it.first->getValue() != value) {
+      it.first->setValue(value);
+
       // If the attributes have changed, the dictionary is invalidated.
       dictionarySorted.setPointer(nullptr);
     }
-    return value;
+    return oldValue;
   }
   // Perform a string lookup to insert the new attribute into its sorted
   // position.
@@ -137,7 +136,7 @@ Attribute NamedAttrList::set(StringRef name, Attribute value) {
 Attribute
 NamedAttrList::eraseImpl(SmallVectorImpl<NamedAttribute>::iterator it) {
   // Erasing does not affect the sorted property.
-  Attribute attr = it->second;
+  Attribute attr = it->getValue();
   attrs.erase(it);
   dictionarySorted.setPointer(nullptr);
   return attr;
@@ -485,11 +484,12 @@ void MutableOperandRange::updateLength(unsigned newLength) {
 
   // Update any of the provided segment attributes.
   for (OperandSegment &segment : operandSegments) {
-    auto attr = segment.second.second.cast<DenseIntElementsAttr>();
+    auto attr = segment.second.getValue().cast<DenseIntElementsAttr>();
     SmallVector<int32_t, 8> segments(attr.getValues<int32_t>());
     segments[segment.first] += 
diff ;
-    segment.second.second = DenseIntElementsAttr::get(attr.getType(), segments);
-    owner->setAttr(segment.second.first, segment.second.second);
+    segment.second.setValue(
+        DenseIntElementsAttr::get(attr.getType(), segments));
+    owner->setAttr(segment.second.getName(), segment.second.getValue());
   }
 }
 
@@ -500,21 +500,21 @@ MutableOperandRangeRange::MutableOperandRangeRange(
     const MutableOperandRange &operands, NamedAttribute operandSegmentAttr)
     : MutableOperandRangeRange(
           OwnerT(operands, operandSegmentAttr), 0,
-          operandSegmentAttr.second.cast<DenseElementsAttr>().size()) {}
+          operandSegmentAttr.getValue().cast<DenseElementsAttr>().size()) {}
 
 MutableOperandRange MutableOperandRangeRange::join() const {
   return getBase().first;
 }
 
 MutableOperandRangeRange::operator OperandRangeRange() const {
-  return OperandRangeRange(getBase().first,
-                           getBase().second.second.cast<DenseElementsAttr>());
+  return OperandRangeRange(
+      getBase().first, getBase().second.getValue().cast<DenseElementsAttr>());
 }
 
 MutableOperandRange MutableOperandRangeRange::dereference(const OwnerT &object,
                                                           ptr
diff _t index) {
   auto sizeData =
-      object.second.second.cast<DenseElementsAttr>().getValues<uint32_t>();
+      object.second.getValue().cast<DenseElementsAttr>().getValues<uint32_t>();
   uint32_t startIndex =
       std::accumulate(sizeData.begin(), sizeData.begin() + index, 0);
   return object.first.slice(

diff  --git a/mlir/lib/IR/Verifier.cpp b/mlir/lib/IR/Verifier.cpp
index c0e4c7974c6d0..f041f9e35a812 100644
--- a/mlir/lib/IR/Verifier.cpp
+++ b/mlir/lib/IR/Verifier.cpp
@@ -170,7 +170,7 @@ LogicalResult OperationVerifier::verifyOperation(
   /// Verify that all of the attributes are okay.
   for (auto attr : op.getAttrs()) {
     // Check for any optional dialect specific attributes.
-    if (auto *dialect = attr.first.getReferencedDialect())
+    if (auto *dialect = attr.getNameDialect())
       if (failed(dialect->verifyOperationAttribute(&op, attr)))
         return failure();
   }

diff  --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp
index 5f14292ace81f..a1ba6a8010dbe 100644
--- a/mlir/lib/Parser/Parser.cpp
+++ b/mlir/lib/Parser/Parser.cpp
@@ -1123,7 +1123,7 @@ class CustomOpAsmParser : public AsmParserImpl<OpAsmParser> {
     Optional<NamedAttribute> duplicate = opState.attributes.findDuplicate();
     if (duplicate)
       return emitError(getNameLoc(), "attribute '")
-             << duplicate->first.getValue()
+             << duplicate->getName().getValue()
              << "' occurs more than once in the attribute list";
     return success();
   }

diff  --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index abddb790fbc99..90f4f3080ad23 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -812,7 +812,7 @@ CppEmitter::emitOperandsAndAttributes(Operation &op,
   // Insert comma in between operands and non-filtered attributes if needed.
   if (op.getNumOperands() > 0) {
     for (NamedAttribute attr : op.getAttrs()) {
-      if (!llvm::is_contained(exclude, attr.first.strref())) {
+      if (!llvm::is_contained(exclude, attr.getName().strref())) {
         os << ", ";
         break;
       }
@@ -820,10 +820,10 @@ CppEmitter::emitOperandsAndAttributes(Operation &op,
   }
   // Emit attributes.
   auto emitNamedAttribute = [&](NamedAttribute attr) -> LogicalResult {
-    if (llvm::is_contained(exclude, attr.first.strref()))
+    if (llvm::is_contained(exclude, attr.getName().strref()))
       return success();
-    os << "/* " << attr.first.getValue() << " */";
-    if (failed(emitAttribute(op.getLoc(), attr.second)))
+    os << "/* " << attr.getName().getValue() << " */";
+    if (failed(emitAttribute(op.getLoc(), attr.getValue())))
       return failure();
     return success();
   };

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
index 6c10e61dcc857..6abb0a5c0ab8e 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.cpp
@@ -224,9 +224,9 @@ static void setLoopMetadata(Operation &opInst, llvm::Instruction &llvmInst,
         SmallVector<llvm::Metadata *> parallelAccess;
         parallelAccess.push_back(
             llvm::MDString::get(ctx, "llvm.loop.parallel_accesses"));
-        for (SymbolRefAttr accessGroupRef :
-             parallelAccessGroup->second.cast<ArrayAttr>()
-                 .getAsRange<SymbolRefAttr>())
+        for (SymbolRefAttr accessGroupRef : parallelAccessGroup->getValue()
+                                                .cast<ArrayAttr>()
+                                                .getAsRange<SymbolRefAttr>())
           parallelAccess.push_back(
               moduleTranslation.getAccessGroup(opInst, accessGroupRef));
         loopOptions.push_back(llvm::MDNode::get(ctx, parallelAccess));

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
index bdcb451323add..f64d389bf9b20 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/NVVM/NVVMToLLVMIRTranslation.cpp
@@ -57,7 +57,7 @@ class NVVMDialectLLVMIRTranslationInterface
   LogicalResult
   amendOperation(Operation *op, NamedAttribute attribute,
                  LLVM::ModuleTranslation &moduleTranslation) const final {
-    if (attribute.first == NVVM::NVVMDialect::getKernelFuncAttrName()) {
+    if (attribute.getName() == NVVM::NVVMDialect::getKernelFuncAttrName()) {
       auto func = dyn_cast<LLVM::LLVMFuncOp>(op);
       if (!func)
         return failure();

diff  --git a/mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp
index 8a3470ce80aa6..348424ab3722d 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.cpp
@@ -64,7 +64,7 @@ class ROCDLDialectLLVMIRTranslationInterface
   LogicalResult
   amendOperation(Operation *op, NamedAttribute attribute,
                  LLVM::ModuleTranslation &moduleTranslation) const final {
-    if (attribute.first == ROCDL::ROCDLDialect::getKernelFuncAttrName()) {
+    if (attribute.getName() == ROCDL::ROCDLDialect::getKernelFuncAttrName()) {
       auto func = dyn_cast<LLVM::LLVMFuncOp>(op);
       if (!func)
         return failure();

diff  --git a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
index e60d1a9f6789a..646a2df394dec 100644
--- a/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization/Deserializer.cpp
@@ -521,7 +521,7 @@ spirv::Deserializer::createSpecConstant(Location loc, uint32_t resultID,
                                                     defaultValue);
   if (decorations.count(resultID)) {
     for (auto attr : decorations[resultID].getAttrs())
-      op->setAttr(attr.first, attr.second);
+      op->setAttr(attr.getName(), attr.getValue());
   }
   specConstMap[resultID] = op;
   return op;
@@ -591,9 +591,8 @@ spirv::Deserializer::processGlobalVariable(ArrayRef<uint32_t> operands) {
 
   // Decorations.
   if (decorations.count(variableID)) {
-    for (auto attr : decorations[variableID].getAttrs()) {
-      varOp->setAttr(attr.first, attr.second);
-    }
+    for (auto attr : decorations[variableID].getAttrs())
+      varOp->setAttr(attr.getName(), attr.getValue());
   }
   globalVariableMap[variableID] = varOp;
   return success();

diff  --git a/mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp b/mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp
index c1e8d7f382b9a..d877c1b70311e 100644
--- a/mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization/SerializeOps.cpp
@@ -295,8 +295,9 @@ LogicalResult Serializer::processVariableOp(spirv::VariableOp op) {
   (void)encodeInstructionInto(functionHeader, spirv::Opcode::OpVariable,
                               operands);
   for (auto attr : op->getAttrs()) {
-    if (llvm::any_of(elidedAttrs,
-                     [&](StringRef elided) { return attr.first == elided; })) {
+    if (llvm::any_of(elidedAttrs, [&](StringRef elided) {
+          return attr.getName() == elided;
+        })) {
       continue;
     }
     if (failed(processDecoration(op.getLoc(), resultID, attr))) {
@@ -364,8 +365,9 @@ Serializer::processGlobalVariableOp(spirv::GlobalVariableOp varOp) {
 
   // Encode decorations.
   for (auto attr : varOp->getAttrs()) {
-    if (llvm::any_of(elidedAttrs,
-                     [&](StringRef elided) { return attr.first == elided; })) {
+    if (llvm::any_of(elidedAttrs, [&](StringRef elided) {
+          return attr.getName() == elided;
+        })) {
       continue;
     }
     if (failed(processDecoration(varOp.getLoc(), resultID, attr))) {

diff  --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
index 5701b44a2a9f2..6bd5ff1629b25 100644
--- a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
@@ -205,7 +205,7 @@ void Serializer::processMemoryModel() {
 
 LogicalResult Serializer::processDecoration(Location loc, uint32_t resultID,
                                             NamedAttribute attr) {
-  auto attrName = attr.first.strref();
+  auto attrName = attr.getName().strref();
   auto decorationName = llvm::convertToCamelFromSnakeCase(attrName, true);
   auto decoration = spirv::symbolizeDecoration(decorationName);
   if (!decoration) {
@@ -219,13 +219,13 @@ LogicalResult Serializer::processDecoration(Location loc, uint32_t resultID,
   case spirv::Decoration::Binding:
   case spirv::Decoration::DescriptorSet:
   case spirv::Decoration::Location:
-    if (auto intAttr = attr.second.dyn_cast<IntegerAttr>()) {
+    if (auto intAttr = attr.getValue().dyn_cast<IntegerAttr>()) {
       args.push_back(intAttr.getValue().getZExtValue());
       break;
     }
     return emitError(loc, "expected integer attribute for ") << attrName;
   case spirv::Decoration::BuiltIn:
-    if (auto strAttr = attr.second.dyn_cast<StringAttr>()) {
+    if (auto strAttr = attr.getValue().dyn_cast<StringAttr>()) {
       auto enumVal = spirv::symbolizeBuiltIn(strAttr.getValue());
       if (enumVal) {
         args.push_back(static_cast<uint32_t>(enumVal.getValue()));
@@ -243,7 +243,7 @@ LogicalResult Serializer::processDecoration(Location loc, uint32_t resultID,
   case spirv::Decoration::Restrict:
   case spirv::Decoration::RelaxedPrecision:
     // For unit attributes, the args list has no values so we do nothing
-    if (auto unitAttr = attr.second.dyn_cast<UnitAttr>())
+    if (auto unitAttr = attr.getValue().dyn_cast<UnitAttr>())
       break;
     return emitError(loc, "expected unit attribute for ") << attrName;
   default:

diff  --git a/mlir/lib/Transforms/Utils/Utils.cpp b/mlir/lib/Transforms/Utils/Utils.cpp
index 8b40085e380a4..86ade8db70cca 100644
--- a/mlir/lib/Transforms/Utils/Utils.cpp
+++ b/mlir/lib/Transforms/Utils/Utils.cpp
@@ -90,7 +90,7 @@ LogicalResult mlir::replaceAllMemRefUsesWith(Value oldMemRef, Value newMemRef,
   // Perform index rewrites for the dereferencing op and then replace the op
   NamedAttribute oldMapAttrPair =
       affMapAccInterface.getAffineMapAttrForMemRef(oldMemRef);
-  AffineMap oldMap = oldMapAttrPair.second.cast<AffineMapAttr>().getValue();
+  AffineMap oldMap = oldMapAttrPair.getValue().cast<AffineMapAttr>().getValue();
   unsigned oldMapNumInputs = oldMap.getNumInputs();
   SmallVector<Value, 4> oldMapOperands(
       op->operand_begin() + memRefOperandPos + 1,
@@ -194,8 +194,8 @@ LogicalResult mlir::replaceAllMemRefUsesWith(Value oldMemRef, Value newMemRef,
   // Add attribute for 'newMap', other Attributes do not change.
   auto newMapAttr = AffineMapAttr::get(newMap);
   for (auto namedAttr : op->getAttrs()) {
-    if (namedAttr.first == oldMapAttrPair.first)
-      state.attributes.push_back({namedAttr.first, newMapAttr});
+    if (namedAttr.getName() == oldMapAttrPair.getName())
+      state.attributes.push_back({namedAttr.getName(), newMapAttr});
     else
       state.attributes.push_back(namedAttr);
   }

diff  --git a/mlir/lib/Transforms/ViewOpGraph.cpp b/mlir/lib/Transforms/ViewOpGraph.cpp
index 11a276470368c..044136c454bd9 100644
--- a/mlir/lib/Transforms/ViewOpGraph.cpp
+++ b/mlir/lib/Transforms/ViewOpGraph.cpp
@@ -221,8 +221,8 @@ class PrintOpPass : public ViewOpGraphPassBase<PrintOpPass> {
       if (printAttrs) {
         os << "\n";
         for (const NamedAttribute &attr : op->getAttrs()) {
-          os << '\n' << attr.first.getValue() << ": ";
-          emitMlirAttr(os, attr.second);
+          os << '\n' << attr.getName().getValue() << ": ";
+          emitMlirAttr(os, attr.getValue());
         }
       }
     });

diff  --git a/mlir/test/lib/Dialect/Test/TestDialect.cpp b/mlir/test/lib/Dialect/Test/TestDialect.cpp
index e52bdfb5a5f98..e045bb91ab18b 100644
--- a/mlir/test/lib/Dialect/Test/TestDialect.cpp
+++ b/mlir/test/lib/Dialect/Test/TestDialect.cpp
@@ -288,7 +288,7 @@ void *TestDialect::getRegisteredInterfaceForOp(TypeID typeID,
 
 LogicalResult TestDialect::verifyOperationAttribute(Operation *op,
                                                     NamedAttribute namedAttr) {
-  if (namedAttr.first == "test.invalid_attr")
+  if (namedAttr.getName() == "test.invalid_attr")
     return op->emitError() << "invalid to use 'test.invalid_attr'";
   return success();
 }
@@ -297,7 +297,7 @@ LogicalResult TestDialect::verifyRegionArgAttribute(Operation *op,
                                                     unsigned regionIndex,
                                                     unsigned argIndex,
                                                     NamedAttribute namedAttr) {
-  if (namedAttr.first == "test.invalid_attr")
+  if (namedAttr.getName() == "test.invalid_attr")
     return op->emitError() << "invalid to use 'test.invalid_attr'";
   return success();
 }
@@ -306,7 +306,7 @@ LogicalResult
 TestDialect::verifyRegionResultAttribute(Operation *op, unsigned regionIndex,
                                          unsigned resultIndex,
                                          NamedAttribute namedAttr) {
-  if (namedAttr.first == "test.invalid_attr")
+  if (namedAttr.getName() == "test.invalid_attr")
     return op->emitError() << "invalid to use 'test.invalid_attr'";
   return success();
 }
@@ -942,7 +942,7 @@ static ParseResult parseStringAttrPrettyNameOp(OpAsmParser &parser,
   // If the attribute dictionary contains no 'names' attribute, infer it from
   // the SSA name (if specified).
   bool hadNames = llvm::any_of(result.attributes, [](NamedAttribute attr) {
-    return attr.first == "names";
+    return attr.getName() == "names";
   });
 
   // If there was no name specified, check to see if there was a useful name

diff  --git a/mlir/test/lib/Dialect/Test/TestPatterns.cpp b/mlir/test/lib/Dialect/Test/TestPatterns.cpp
index d2b049bfb14cd..8cc89c6ce6444 100644
--- a/mlir/test/lib/Dialect/Test/TestPatterns.cpp
+++ b/mlir/test/lib/Dialect/Test/TestPatterns.cpp
@@ -243,7 +243,7 @@ void TestDerivedAttributeDriver::runOnFunction() {
     if (!dAttr)
       return;
     for (auto d : dAttr)
-      dOp.emitRemark() << d.first.getValue() << " = " << d.second;
+      dOp.emitRemark() << d.getName().getValue() << " = " << d.getValue();
   });
 }
 

diff  --git a/mlir/test/lib/IR/TestBuiltinAttributeInterfaces.cpp b/mlir/test/lib/IR/TestBuiltinAttributeInterfaces.cpp
index 9f334603ca82f..f7371f8733930 100644
--- a/mlir/test/lib/IR/TestBuiltinAttributeInterfaces.cpp
+++ b/mlir/test/lib/IR/TestBuiltinAttributeInterfaces.cpp
@@ -23,7 +23,7 @@ struct TestElementsAttrInterface
   void runOnOperation() override {
     getOperation().walk([&](Operation *op) {
       for (NamedAttribute attr : op->getAttrs()) {
-        auto elementsAttr = attr.second.dyn_cast<ElementsAttr>();
+        auto elementsAttr = attr.getValue().dyn_cast<ElementsAttr>();
         if (!elementsAttr)
           continue;
         testElementsAttrIteration<uint64_t>(op, elementsAttr, "uint64_t");

diff  --git a/mlir/test/lib/IR/TestPrintNesting.cpp b/mlir/test/lib/IR/TestPrintNesting.cpp
index f48a9181f1af5..7149435245c1f 100644
--- a/mlir/test/lib/IR/TestPrintNesting.cpp
+++ b/mlir/test/lib/IR/TestPrintNesting.cpp
@@ -37,8 +37,8 @@ struct TestPrintNestingPass
     if (!op->getAttrs().empty()) {
       printIndent() << op->getAttrs().size() << " attributes:\n";
       for (NamedAttribute attr : op->getAttrs())
-        printIndent() << " - '" << attr.first.getValue() << "' : '"
-                      << attr.second << "'\n";
+        printIndent() << " - '" << attr.getName().getValue() << "' : '"
+                      << attr.getValue() << "'\n";
     }
 
     // Recurse into each of the regions attached to the operation.

diff  --git a/mlir/test/mlir-tblgen/op-result.td b/mlir/test/mlir-tblgen/op-result.td
index 63bc5d0fb417c..29a2b0729f36a 100644
--- a/mlir/test/mlir-tblgen/op-result.td
+++ b/mlir/test/mlir-tblgen/op-result.td
@@ -51,7 +51,7 @@ def OpD : NS_Op<"type_attr_as_result_type", [FirstAttrDerivedResultType]> {
 
 // CHECK-LABEL: OpD definitions
 // CHECK: void OpD::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes)
-// CHECK: odsState.addTypes({attr.second.cast<::mlir::TypeAttr>().getValue()});
+// CHECK: odsState.addTypes({attr.getValue().cast<::mlir::TypeAttr>().getValue()});
 
 def OpE : NS_Op<"value_attr_as_result_type", [FirstAttrDerivedResultType]> {
   let arguments = (ins I32:$x, F32Attr:$attr);
@@ -60,7 +60,7 @@ def OpE : NS_Op<"value_attr_as_result_type", [FirstAttrDerivedResultType]> {
 
 // CHECK-LABEL: OpE definitions
 // CHECK: void OpE::build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes)
-// CHECK: odsState.addTypes({attr.second.getType()});
+// CHECK: odsState.addTypes({attr.getValue().getType()});
 
 def OpF : NS_Op<"one_variadic_result_op", []> {
   let results = (outs Variadic<I32>:$x);

diff  --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index 50708ad3d2b97..e822b7819a532 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -1449,11 +1449,11 @@ void OpEmitter::genUseAttrAsResultTypeBuilder() {
        << "AttrName(" << builderOpState
        << ".name);\n"
           "  for (auto attr : attributes) {\n"
-          "    if (attr.first != attrName) continue;\n";
+          "    if (attr.getName() != attrName) continue;\n";
   if (namedAttr.attr.isTypeAttr()) {
-    resultType = "attr.second.cast<::mlir::TypeAttr>().getValue()";
+    resultType = "attr.getValue().cast<::mlir::TypeAttr>().getValue()";
   } else {
-    resultType = "attr.second.getType()";
+    resultType = "attr.getValue().getType()";
   }
 
   // Operands

diff  --git a/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp b/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
index 4053bc90ccc95..59b472615c005 100644
--- a/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
+++ b/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
@@ -673,7 +673,8 @@ static void emitDecorationSerialization(const Operator &op, StringRef tabs,
     // All non-argument attributes translated into OpDecorate instruction
     os << tabs << formatv("for (auto attr : {0}->getAttrs()) {{\n", opVar);
     os << tabs
-       << formatv("  if (llvm::is_contained({0}, attr.first)) {{", elidedAttrs);
+       << formatv("  if (llvm::is_contained({0}, attr.getName())) {{",
+                  elidedAttrs);
     os << tabs << "    continue;\n";
     os << tabs << "  }\n";
     os << tabs

diff  --git a/mlir/unittests/IR/OperationSupportTest.cpp b/mlir/unittests/IR/OperationSupportTest.cpp
index b0b48b099f2bc..6510116329b51 100644
--- a/mlir/unittests/IR/OperationSupportTest.cpp
+++ b/mlir/unittests/IR/OperationSupportTest.cpp
@@ -237,11 +237,11 @@ TEST(NamedAttrListTest, TestAppendAssign) {
 
   {
     auto it = attrs.begin();
-    EXPECT_EQ(it->first, b.getStringAttr("foo"));
-    EXPECT_EQ(it->second, b.getStringAttr("bar"));
+    EXPECT_EQ(it->getName(), b.getStringAttr("foo"));
+    EXPECT_EQ(it->getValue(), b.getStringAttr("bar"));
     ++it;
-    EXPECT_EQ(it->first, b.getStringAttr("baz"));
-    EXPECT_EQ(it->second, b.getStringAttr("boo"));
+    EXPECT_EQ(it->getName(), b.getStringAttr("baz"));
+    EXPECT_EQ(it->getValue(), b.getStringAttr("boo"));
   }
 
   attrs.append("foo", b.getStringAttr("zoo"));
@@ -261,11 +261,11 @@ TEST(NamedAttrListTest, TestAppendAssign) {
 
   {
     auto it = attrs.begin();
-    EXPECT_EQ(it->first, b.getStringAttr("foo"));
-    EXPECT_EQ(it->second, b.getStringAttr("f"));
+    EXPECT_EQ(it->getName(), b.getStringAttr("foo"));
+    EXPECT_EQ(it->getValue(), b.getStringAttr("f"));
     ++it;
-    EXPECT_EQ(it->first, b.getStringAttr("zoo"));
-    EXPECT_EQ(it->second, b.getStringAttr("z"));
+    EXPECT_EQ(it->getName(), b.getStringAttr("zoo"));
+    EXPECT_EQ(it->getValue(), b.getStringAttr("z"));
   }
 
   attrs.assign({});

diff  --git a/mlir/unittests/TableGen/OpBuildGen.cpp b/mlir/unittests/TableGen/OpBuildGen.cpp
index 5228390f677a3..4e692cacf1843 100644
--- a/mlir/unittests/TableGen/OpBuildGen.cpp
+++ b/mlir/unittests/TableGen/OpBuildGen.cpp
@@ -62,7 +62,8 @@ class OpBuildGenTest : public ::testing::Test {
 
     EXPECT_EQ(op->getAttrs().size(), attrs.size());
     for (unsigned idx : llvm::seq<unsigned>(0U, attrs.size()))
-      EXPECT_EQ(op->getAttr(attrs[idx].first.strref()), attrs[idx].second);
+      EXPECT_EQ(op->getAttr(attrs[idx].getName().strref()),
+                attrs[idx].getValue());
 
     concreteOp.erase();
   }

diff  --git a/mlir/unittests/TableGen/StructsGenTest.cpp b/mlir/unittests/TableGen/StructsGenTest.cpp
index e1ebf1d668bbc..ead1156a9424b 100644
--- a/mlir/unittests/TableGen/StructsGenTest.cpp
+++ b/mlir/unittests/TableGen/StructsGenTest.cpp
@@ -62,7 +62,7 @@ TEST(StructsGenTest, ClassofExtraFalse) {
 
   // Add an extra NamedAttribute.
   auto wrongId = mlir::StringAttr::get(&context, "wrong");
-  auto wrongAttr = mlir::NamedAttribute(wrongId, expectedValues[0].second);
+  auto wrongAttr = mlir::NamedAttribute(wrongId, expectedValues[0].getValue());
   newValues.push_back(wrongAttr);
 
   // Make a new DictionaryAttr and validate.
@@ -84,7 +84,7 @@ TEST(StructsGenTest, ClassofBadNameFalse) {
 
   // Add a copy of the first attribute with the wrong name.
   auto wrongId = mlir::StringAttr::get(&context, "wrong");
-  auto wrongAttr = mlir::NamedAttribute(wrongId, expectedValues[0].second);
+  auto wrongAttr = mlir::NamedAttribute(wrongId, expectedValues[0].getValue());
   newValues.push_back(wrongAttr);
 
   auto badDictionary = mlir::DictionaryAttr::get(&context, newValues);
@@ -108,7 +108,7 @@ TEST(StructsGenTest, ClassofBadTypeFalse) {
   auto elementsType = mlir::RankedTensorType::get({3}, i64Type);
   auto elementsAttr =
       mlir::DenseIntElementsAttr::get(elementsType, ArrayRef<int64_t>{1, 2, 3});
-  mlir::StringAttr id = expectedValues.back().first;
+  mlir::StringAttr id = expectedValues.back().getName();
   auto wrongAttr = mlir::NamedAttribute(id, elementsAttr);
   newValues.push_back(wrongAttr);
 


        


More information about the Mlir-commits mailing list