[mlir] Reintroduce API for creating operations with a DictionaryAttr
authorJeff Niu <jeff@modular.com>
Thu, 16 Feb 2023 18:27:10 +0000 (10:27 -0800)
committerJeff Niu <jeff@modular.com>
Fri, 17 Feb 2023 18:07:53 +0000 (10:07 -0800)
This patch reintroduces an API to create operations with a pre-existing
DictionaryAttr. This API does not populate the attributes with any
default attributes the operation may have, like the API that takes a
NamedAttrList does. NamedAttrList is effective at not re-hashing the
attributes if no default attributes were added, but this new API speeds
up clone-heavy workloads slightly (~5%).

Reviewed By: rriddle

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

mlir/include/mlir/IR/Operation.h
mlir/lib/IR/Operation.cpp

index 59d450e..e7ef01e 100644 (file)
@@ -74,12 +74,21 @@ class alignas(8) Operation final
       private llvm::TrailingObjects<Operation, detail::OperandStorage,
                                     BlockOperand, Region, OpOperand> {
 public:
-  /// Create a new Operation with the specific fields.
+  /// Create a new Operation with the specific fields. This constructor
+  /// populates the provided attribute list with default attributes if
+  /// necessary.
   static Operation *create(Location location, OperationName name,
                            TypeRange resultTypes, ValueRange operands,
                            NamedAttrList &&attributes, BlockRange successors,
                            unsigned numRegions);
 
+  /// Create a new Operation with the specific fields. This constructor uses an
+  /// existing attribute dictionary to avoid uniquing a list of attributes.
+  static Operation *create(Location location, OperationName name,
+                           TypeRange resultTypes, ValueRange operands,
+                           DictionaryAttr attributes, BlockRange successors,
+                           unsigned numRegions);
+
   /// Create a new Operation from the fields stored in `state`.
   static Operation *create(const OperationState &state);
 
@@ -506,9 +515,9 @@ public:
 
   /// Sets default attributes on unset attributes.
   void populateDefaultAttrs() {
-      NamedAttrList attrs(getAttrDictionary());
-      name.populateDefaultAttrs(attrs);
-      setAttrs(attrs.getDictionary(getContext()));
+    NamedAttrList attrs(getAttrDictionary());
+    name.populateDefaultAttrs(attrs);
+    setAttrs(attrs.getDictionary(getContext()));
   }
 
   //===--------------------------------------------------------------------===//
index 50815b3..5a7594e 100644 (file)
@@ -44,11 +44,24 @@ Operation *Operation::create(Location location, OperationName name,
   return op;
 }
 
+/// Create a new Operation with the specific fields.
+Operation *Operation::create(Location location, OperationName name,
+                             TypeRange resultTypes, ValueRange operands,
+                             NamedAttrList &&attributes, BlockRange successors,
+                             unsigned numRegions) {
+  // Populate default attributes.
+  name.populateDefaultAttrs(attributes);
+
+  return create(location, name, resultTypes, operands,
+                attributes.getDictionary(location.getContext()), successors,
+                numRegions);
+}
+
 /// Overload of create that takes an existing DictionaryAttr to avoid
 /// unnecessarily uniquing a list of attributes.
 Operation *Operation::create(Location location, OperationName name,
                              TypeRange resultTypes, ValueRange operands,
-                             NamedAttrList &&attributes, BlockRange successors,
+                             DictionaryAttr attributes, BlockRange successors,
                              unsigned numRegions) {
   assert(llvm::all_of(resultTypes, [](Type t) { return t; }) &&
          "unexpected null result type");
@@ -77,13 +90,10 @@ Operation *Operation::create(Location location, OperationName name,
   char *mallocMem = reinterpret_cast<char *>(malloc(byteSize + prefixByteSize));
   void *rawMem = mallocMem + prefixByteSize;
 
-  // Populate default attributes.
-  name.populateDefaultAttrs(attributes);
-
   // Create the new Operation.
-  Operation *op = ::new (rawMem) Operation(
-      location, name, numResults, numSuccessors, numRegions,
-      attributes.getDictionary(location.getContext()), needsOperandStorage);
+  Operation *op =
+      ::new (rawMem) Operation(location, name, numResults, numSuccessors,
+                               numRegions, attributes, needsOperandStorage);
 
   assert((numSuccessors == 0 || op->mightHaveTrait<OpTrait::IsTerminator>()) &&
          "unexpected successors in a non-terminator operation");