[Mlir-commits] [mlir] [MLIR] Remove deprecated setting usePropertiesForAttributes (PR #182327)
Mehdi Amini
llvmlistbot at llvm.org
Fri Feb 20 12:08:29 PST 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/182327
>From 42228603ecc8cfce21919898b5b395255f3ee5c3 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 20 Feb 2026 05:39:54 -0800
Subject: [PATCH 1/2] [MLIR] Migrate AffineDma ops to ODS (NFC)
For some historical reasons, seems like we never converted these.
---
.../mlir/Dialect/Affine/IR/AffineOps.h | 333 ------------------
.../mlir/Dialect/Affine/IR/AffineOps.td | 305 ++++++++++++++++
mlir/lib/Dialect/Affine/IR/AffineOps.cpp | 57 +--
3 files changed, 311 insertions(+), 384 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h
index 333de6bbd8a05..20d7f6436a896 100644
--- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h
+++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h
@@ -58,339 +58,6 @@ Region *getAffineAnalysisScope(Operation *op);
OpFoldResult computeProduct(Location loc, OpBuilder &builder,
ArrayRef<OpFoldResult> terms);
-/// AffineDmaStartOp starts a non-blocking DMA operation that transfers data
-/// from a source memref to a destination memref. The source and destination
-/// memref need not be of the same dimensionality, but need to have the same
-/// elemental type. The operands include the source and destination memref's
-/// each followed by its indices, size of the data transfer in terms of the
-/// number of elements (of the elemental type of the memref), a tag memref with
-/// its indices, and optionally at the end, a stride and a
-/// number_of_elements_per_stride arguments. The tag location is used by an
-/// AffineDmaWaitOp to check for completion. The indices of the source memref,
-/// destination memref, and the tag memref have the same restrictions as any
-/// affine.load/store. In particular, index for each memref dimension must be an
-/// affine expression of loop induction variables and symbols.
-/// The optional stride arguments should be of 'index' type, and specify a
-/// stride for the slower memory space (memory space with a lower memory space
-/// id), transferring chunks of number_of_elements_per_stride every stride until
-/// %num_elements are transferred. Either both or no stride arguments should be
-/// specified. The value of 'num_elements' must be a multiple of
-/// 'number_of_elements_per_stride'. If the source and destination locations
-/// overlap the behavior of this operation is not defined.
-//
-// For example, an AffineDmaStartOp operation that transfers 256 elements of a
-// memref '%src' in memory space 0 at indices [%i + 3, %j] to memref '%dst' in
-// memory space 1 at indices [%k + 7, %l], would be specified as follows:
-//
-// %num_elements = arith.constant 256
-// %idx = arith.constant 0 : index
-// %tag = memref.alloc() : memref<1xi32, 4>
-// affine.dma_start %src[%i + 3, %j], %dst[%k + 7, %l], %tag[%idx],
-// %num_elements :
-// memref<40x128xf32, 0>, memref<2x1024xf32, 1>, memref<1xi32, 2>
-//
-// If %stride and %num_elt_per_stride are specified, the DMA is expected to
-// transfer %num_elt_per_stride elements every %stride elements apart from
-// memory space 0 until %num_elements are transferred.
-//
-// affine.dma_start %src[%i, %j], %dst[%k, %l], %tag[%idx], %num_elements,
-// %stride, %num_elt_per_stride : ...
-//
-// TODO: add additional operands to allow source and destination striding, and
-// multiple stride levels (possibly using AffineMaps to specify multiple levels
-// of striding).
-class AffineDmaStartOp
- : public Op<AffineDmaStartOp, OpTrait::MemRefsNormalizable,
- OpTrait::VariadicOperands, OpTrait::ZeroResults,
- OpTrait::OpInvariants, AffineMapAccessInterface::Trait,
- MemoryEffectOpInterface::Trait> {
-public:
- using Op::Op;
- static ArrayRef<StringRef> getAttributeNames() { return {}; }
-
- static void build(OpBuilder &builder, OperationState &result, Value srcMemRef,
- AffineMap srcMap, ValueRange srcIndices, Value destMemRef,
- AffineMap dstMap, ValueRange destIndices, Value tagMemRef,
- AffineMap tagMap, ValueRange tagIndices, Value numElements,
- Value stride = nullptr, Value elementsPerStride = nullptr);
-
- static AffineDmaStartOp
- create(OpBuilder &builder, Location location, Value srcMemRef,
- AffineMap srcMap, ValueRange srcIndices, Value destMemRef,
- AffineMap dstMap, ValueRange destIndices, Value tagMemRef,
- AffineMap tagMap, ValueRange tagIndices, Value numElements,
- Value stride = nullptr, Value elementsPerStride = nullptr);
-
- static AffineDmaStartOp create(ImplicitLocOpBuilder &builder, Value srcMemRef,
- AffineMap srcMap, ValueRange srcIndices,
- Value destMemRef, AffineMap dstMap,
- ValueRange destIndices, Value tagMemRef,
- AffineMap tagMap, ValueRange tagIndices,
- Value numElements, Value stride = nullptr,
- Value elementsPerStride = nullptr);
-
- /// Returns the operand index of the source memref.
- unsigned getSrcMemRefOperandIndex() { return 0; }
-
- /// Returns the source MemRefType for this DMA operation.
- Value getSrcMemRef() { return getOperand(getSrcMemRefOperandIndex()); }
- OpOperand &getSrcMemRefMutable() {
- return getOperation()->getOpOperand(getSrcMemRefOperandIndex());
- }
- MemRefType getSrcMemRefType() {
- return cast<MemRefType>(getSrcMemRef().getType());
- }
-
- /// Returns the rank (number of indices) of the source MemRefType.
- unsigned getSrcMemRefRank() { return getSrcMemRefType().getRank(); }
-
- /// Returns the affine map used to access the source memref.
- AffineMap getSrcMap() { return getSrcMapAttr().getValue(); }
- AffineMapAttr getSrcMapAttr() {
- return cast<AffineMapAttr>(
- *(*this)->getInherentAttr(getSrcMapAttrStrName()));
- }
-
- /// Returns the source memref affine map indices for this DMA operation.
- operand_range getSrcIndices() {
- return {operand_begin() + getSrcMemRefOperandIndex() + 1,
- operand_begin() + getSrcMemRefOperandIndex() + 1 +
- getSrcMap().getNumInputs()};
- }
-
- /// Returns the memory space of the source memref.
- unsigned getSrcMemorySpace() {
- return cast<MemRefType>(getSrcMemRef().getType()).getMemorySpaceAsInt();
- }
-
- /// Returns the operand index of the destination memref.
- unsigned getDstMemRefOperandIndex() {
- return getSrcMemRefOperandIndex() + 1 + getSrcMap().getNumInputs();
- }
-
- /// Returns the destination MemRefType for this DMA operation.
- Value getDstMemRef() { return getOperand(getDstMemRefOperandIndex()); }
- OpOperand &getDstMemRefMutable() {
- return getOperation()->getOpOperand(getDstMemRefOperandIndex());
- }
- MemRefType getDstMemRefType() {
- return cast<MemRefType>(getDstMemRef().getType());
- }
-
- /// Returns the rank (number of indices) of the destination MemRefType.
- unsigned getDstMemRefRank() {
- return cast<MemRefType>(getDstMemRef().getType()).getRank();
- }
-
- /// Returns the memory space of the source memref.
- unsigned getDstMemorySpace() {
- return cast<MemRefType>(getDstMemRef().getType()).getMemorySpaceAsInt();
- }
-
- /// Returns the affine map used to access the destination memref.
- AffineMap getDstMap() { return getDstMapAttr().getValue(); }
- AffineMapAttr getDstMapAttr() {
- return cast<AffineMapAttr>(
- *(*this)->getInherentAttr(getDstMapAttrStrName()));
- }
-
- /// Returns the destination memref indices for this DMA operation.
- operand_range getDstIndices() {
- return {operand_begin() + getDstMemRefOperandIndex() + 1,
- operand_begin() + getDstMemRefOperandIndex() + 1 +
- getDstMap().getNumInputs()};
- }
-
- /// Returns the operand index of the tag memref.
- unsigned getTagMemRefOperandIndex() {
- return getDstMemRefOperandIndex() + 1 + getDstMap().getNumInputs();
- }
-
- /// Returns the Tag MemRef for this DMA operation.
- Value getTagMemRef() { return getOperand(getTagMemRefOperandIndex()); }
- OpOperand &getTagMemRefMutable() {
- return getOperation()->getOpOperand(getTagMemRefOperandIndex());
- }
- MemRefType getTagMemRefType() {
- return cast<MemRefType>(getTagMemRef().getType());
- }
-
- /// Returns the rank (number of indices) of the tag MemRefType.
- unsigned getTagMemRefRank() {
- return cast<MemRefType>(getTagMemRef().getType()).getRank();
- }
-
- /// Returns the affine map used to access the tag memref.
- AffineMap getTagMap() { return getTagMapAttr().getValue(); }
- AffineMapAttr getTagMapAttr() {
- return cast<AffineMapAttr>(
- *(*this)->getInherentAttr(getTagMapAttrStrName()));
- }
-
- /// Returns the tag memref indices for this DMA operation.
- operand_range getTagIndices() {
- return {operand_begin() + getTagMemRefOperandIndex() + 1,
- operand_begin() + getTagMemRefOperandIndex() + 1 +
- getTagMap().getNumInputs()};
- }
-
- /// Returns the number of elements being transferred by this DMA operation.
- Value getNumElements() {
- return getOperand(getTagMemRefOperandIndex() + 1 +
- getTagMap().getNumInputs());
- }
-
- /// Impelements the AffineMapAccessInterface.
- /// Returns the AffineMapAttr associated with 'memref'.
- NamedAttribute getAffineMapAttrForMemRef(Value memref) {
- if (memref == getSrcMemRef())
- return {StringAttr::get(getContext(), getSrcMapAttrStrName()),
- getSrcMapAttr()};
- if (memref == getDstMemRef())
- return {StringAttr::get(getContext(), getDstMapAttrStrName()),
- getDstMapAttr()};
- assert(memref == getTagMemRef() &&
- "DmaStartOp expected source, destination or tag memref");
- return {StringAttr::get(getContext(), getTagMapAttrStrName()),
- getTagMapAttr()};
- }
-
- /// Returns true if this is a DMA from a faster memory space to a slower one.
- bool isDestMemorySpaceFaster() {
- return (getSrcMemorySpace() < getDstMemorySpace());
- }
-
- /// Returns true if this is a DMA from a slower memory space to a faster one.
- bool isSrcMemorySpaceFaster() {
- // Assumes that a lower number is for a slower memory space.
- return (getDstMemorySpace() < getSrcMemorySpace());
- }
-
- /// Given a DMA start operation, returns the operand position of either the
- /// source or destination memref depending on the one that is at the higher
- /// level of the memory hierarchy. Asserts failure if neither is true.
- unsigned getFasterMemPos() {
- assert(isSrcMemorySpaceFaster() || isDestMemorySpaceFaster());
- return isSrcMemorySpaceFaster() ? 0 : getDstMemRefOperandIndex();
- }
-
- void
- getEffects(SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
- &effects);
-
- static StringRef getSrcMapAttrStrName() { return "src_map"; }
- static StringRef getDstMapAttrStrName() { return "dst_map"; }
- static StringRef getTagMapAttrStrName() { return "tag_map"; }
-
- static StringRef getOperationName() { return "affine.dma_start"; }
- static ParseResult parse(OpAsmParser &parser, OperationState &result);
- void print(OpAsmPrinter &p);
- LogicalResult verifyInvariantsImpl();
- LogicalResult verifyInvariants() { return verifyInvariantsImpl(); }
- LogicalResult fold(ArrayRef<Attribute> cstOperands,
- SmallVectorImpl<OpFoldResult> &results);
-
- /// Returns true if this DMA operation is strided, returns false otherwise.
- bool isStrided() {
- return getNumOperands() !=
- getTagMemRefOperandIndex() + 1 + getTagMap().getNumInputs() + 1;
- }
-
- /// Returns the stride value for this DMA operation.
- Value getStride() {
- if (!isStrided())
- return nullptr;
- return getOperand(getNumOperands() - 1 - 1);
- }
-
- /// Returns the number of elements to transfer per stride for this DMA op.
- Value getNumElementsPerStride() {
- if (!isStrided())
- return nullptr;
- return getOperand(getNumOperands() - 1);
- }
-};
-
-/// AffineDmaWaitOp blocks until the completion of a DMA operation associated
-/// with the tag element '%tag[%index]'. %tag is a memref, and %index has to be
-/// an index with the same restrictions as any load/store index. In particular,
-/// index for each memref dimension must be an affine expression of loop
-/// induction variables and symbols. %num_elements is the number of elements
-/// associated with the DMA operation. For example:
-//
-// affine.dma_start %src[%i, %j], %dst[%k, %l], %tag[%index], %num_elements :
-// memref<2048xf32, 0>, memref<256xf32, 1>, memref<1xi32, 2>
-// ...
-// ...
-// affine.dma_wait %tag[%index], %num_elements : memref<1xi32, 2>
-//
-class AffineDmaWaitOp
- : public Op<AffineDmaWaitOp, OpTrait::MemRefsNormalizable,
- OpTrait::VariadicOperands, OpTrait::ZeroResults,
- OpTrait::OpInvariants, AffineMapAccessInterface::Trait> {
-public:
- using Op::Op;
- static ArrayRef<StringRef> getAttributeNames() { return {}; }
-
- static void build(OpBuilder &builder, OperationState &result, Value tagMemRef,
- AffineMap tagMap, ValueRange tagIndices, Value numElements);
- static AffineDmaWaitOp create(OpBuilder &builder, Location location,
- Value tagMemRef, AffineMap tagMap,
- ValueRange tagIndices, Value numElements);
- static AffineDmaWaitOp create(ImplicitLocOpBuilder &builder, Value tagMemRef,
- AffineMap tagMap, ValueRange tagIndices,
- Value numElements);
-
- static StringRef getOperationName() { return "affine.dma_wait"; }
-
- /// Returns the Tag MemRef associated with the DMA operation being waited on.
- Value getTagMemRef() { return getOperand(0); }
- OpOperand &getTagMemRefMutable() { return getOperation()->getOpOperand(0); }
- MemRefType getTagMemRefType() {
- return cast<MemRefType>(getTagMemRef().getType());
- }
-
- /// Returns the affine map used to access the tag memref.
- AffineMap getTagMap() { return getTagMapAttr().getValue(); }
- AffineMapAttr getTagMapAttr() {
- return cast<AffineMapAttr>(
- *(*this)->getInherentAttr(getTagMapAttrStrName()));
- }
-
- /// Returns the tag memref index for this DMA operation.
- operand_range getTagIndices() {
- return {operand_begin() + 1,
- operand_begin() + 1 + getTagMap().getNumInputs()};
- }
-
- /// Returns the rank (number of indices) of the tag memref.
- unsigned getTagMemRefRank() {
- return cast<MemRefType>(getTagMemRef().getType()).getRank();
- }
-
- /// Impelements the AffineMapAccessInterface. Returns the AffineMapAttr
- /// associated with 'memref'.
- NamedAttribute getAffineMapAttrForMemRef(Value memref) {
- assert(memref == getTagMemRef());
- return {StringAttr::get(getContext(), getTagMapAttrStrName()),
- getTagMapAttr()};
- }
-
- /// Returns the number of elements transferred by the associated DMA op.
- Value getNumElements() { return getOperand(1 + getTagMap().getNumInputs()); }
-
- static StringRef getTagMapAttrStrName() { return "tag_map"; }
- static ParseResult parse(OpAsmParser &parser, OperationState &result);
- void print(OpAsmPrinter &p);
- LogicalResult verifyInvariantsImpl();
- LogicalResult verifyInvariants() { return verifyInvariantsImpl(); }
- LogicalResult fold(ArrayRef<Attribute> cstOperands,
- SmallVectorImpl<OpFoldResult> &results);
- void
- getEffects(SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
- &effects);
-};
-
/// Returns true if the given Value can be used as a dimension id in the region
/// of the closest surrounding op that has the trait `AffineScope`.
bool isValidDim(Value value);
diff --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
index 482987ebab27d..9cb0f3242db17 100644
--- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
+++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
@@ -1267,4 +1267,309 @@ def AffineLinearizeIndexOp : Affine_Op<"linearize_index",
let hasCanonicalizer = 1;
}
+//===----------------------------------------------------------------------===//
+// AffineDmaStartOp
+//===----------------------------------------------------------------------===//
+
+def AffineDmaStartOp : Affine_Op<"dma_start", [
+ MemRefsNormalizable,
+ DeclareOpInterfaceMethods<AffineMapAccessInterface>,
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ let summary = "affine dma start operation";
+ let description = [{
+ The `affine.dma_start` op starts a non-blocking DMA operation that
+ transfers data from a source memref to a destination memref. The source and
+ destination memref need not be of the same dimensionality, but need to have
+ the same elemental type. The operands include the source and destination
+ memref's each followed by its indices, size of the data transfer in terms of
+ the number of elements (of the elemental type of the memref), a tag memref
+ with its indices, and optionally at the end, a stride and a
+ number_of_elements_per_stride arguments. The tag location is used by an
+ `affine.dma_wait` to check for completion. The indices of the source memref,
+ destination memref, and the tag memref have the same restrictions as any
+ affine.load/store. In particular, index for each memref dimension must be an
+ affine expression of loop induction variables and symbols.
+
+ The optional stride arguments should be of 'index' type, and specify a
+ stride for the slower memory space (memory space with a lower memory space
+ id), transferring chunks of number_of_elements_per_stride every stride until
+ %num_elements are transferred. Either both or no stride arguments should be
+ specified. The value of 'num_elements' must be a multiple of
+ 'number_of_elements_per_stride'. If the source and destination locations
+ overlap the behavior of this operation is not defined.
+
+ Example:
+
+ ```mlir
+ %num_elements = arith.constant 256
+ %idx = arith.constant 0 : index
+ %tag = memref.alloc() : memref<1xi32, 4>
+ affine.dma_start %src[%i + 3, %j], %dst[%k + 7, %l], %tag[%idx],
+ %num_elements :
+ memref<40x128xf32, 0>, memref<2x1024xf32, 1>, memref<1xi32, 2>
+
+ // If %stride and %num_elt_per_stride are specified, the DMA is expected to
+ // transfer %num_elt_per_stride elements every %stride elements apart from
+ // memory space 0 until %num_elements are transferred.
+ affine.dma_start %src[%i, %j], %dst[%k, %l], %tag[%idx], %num_elements,
+ %stride, %num_elt_per_stride : ...
+ ```
+ }];
+
+ let arguments = (ins
+ Variadic<AnyType>,
+ AffineMapAttr:$src_map,
+ AffineMapAttr:$dst_map,
+ AffineMapAttr:$tag_map);
+
+ let results = (outs);
+
+ let skipDefaultBuilders = 1;
+ let builders = [
+ OpBuilder<(ins "Value":$srcMemRef, "AffineMap":$srcMap,
+ "ValueRange":$srcIndices, "Value":$destMemRef, "AffineMap":$dstMap,
+ "ValueRange":$destIndices, "Value":$tagMemRef, "AffineMap":$tagMap,
+ "ValueRange":$tagIndices, "Value":$numElements,
+ CArg<"Value", "nullptr">:$stride,
+ CArg<"Value", "nullptr">:$elementsPerStride)>
+ ];
+
+ let extraClassDeclaration = [{
+ /// Returns the operand index of the source memref.
+ unsigned getSrcMemRefOperandIndex() { return 0; }
+
+ /// Returns the source MemRefType for this DMA operation.
+ Value getSrcMemRef() { return getOperand(getSrcMemRefOperandIndex()); }
+ OpOperand &getSrcMemRefMutable() {
+ return getOperation()->getOpOperand(getSrcMemRefOperandIndex());
+ }
+ MemRefType getSrcMemRefType() {
+ return ::llvm::cast<MemRefType>(getSrcMemRef().getType());
+ }
+
+ /// Returns the rank (number of indices) of the source MemRefType.
+ unsigned getSrcMemRefRank() { return getSrcMemRefType().getRank(); }
+
+ /// Returns the source memref affine map indices for this DMA operation.
+ operand_range getSrcIndices() {
+ return {operand_begin() + getSrcMemRefOperandIndex() + 1,
+ operand_begin() + getSrcMemRefOperandIndex() + 1 +
+ getSrcMap().getNumInputs()};
+ }
+
+ /// Returns the memory space of the source memref.
+ unsigned getSrcMemorySpace() {
+ return ::llvm::cast<MemRefType>(getSrcMemRef().getType())
+ .getMemorySpaceAsInt();
+ }
+
+ /// Returns the operand index of the destination memref.
+ unsigned getDstMemRefOperandIndex() {
+ return getSrcMemRefOperandIndex() + 1 + getSrcMap().getNumInputs();
+ }
+
+ /// Returns the destination MemRefType for this DMA operation.
+ Value getDstMemRef() { return getOperand(getDstMemRefOperandIndex()); }
+ OpOperand &getDstMemRefMutable() {
+ return getOperation()->getOpOperand(getDstMemRefOperandIndex());
+ }
+ MemRefType getDstMemRefType() {
+ return ::llvm::cast<MemRefType>(getDstMemRef().getType());
+ }
+
+ /// Returns the rank (number of indices) of the destination MemRefType.
+ unsigned getDstMemRefRank() {
+ return ::llvm::cast<MemRefType>(getDstMemRef().getType()).getRank();
+ }
+
+ /// Returns the memory space of the destination memref.
+ unsigned getDstMemorySpace() {
+ return ::llvm::cast<MemRefType>(getDstMemRef().getType())
+ .getMemorySpaceAsInt();
+ }
+
+ /// Returns the destination memref indices for this DMA operation.
+ operand_range getDstIndices() {
+ return {operand_begin() + getDstMemRefOperandIndex() + 1,
+ operand_begin() + getDstMemRefOperandIndex() + 1 +
+ getDstMap().getNumInputs()};
+ }
+
+ /// Returns the operand index of the tag memref.
+ unsigned getTagMemRefOperandIndex() {
+ return getDstMemRefOperandIndex() + 1 + getDstMap().getNumInputs();
+ }
+
+ /// Returns the tag MemRef for this DMA operation.
+ Value getTagMemRef() { return getOperand(getTagMemRefOperandIndex()); }
+ OpOperand &getTagMemRefMutable() {
+ return getOperation()->getOpOperand(getTagMemRefOperandIndex());
+ }
+ MemRefType getTagMemRefType() {
+ return ::llvm::cast<MemRefType>(getTagMemRef().getType());
+ }
+
+ /// Returns the rank (number of indices) of the tag MemRefType.
+ unsigned getTagMemRefRank() {
+ return ::llvm::cast<MemRefType>(getTagMemRef().getType()).getRank();
+ }
+
+ /// Returns the tag memref indices for this DMA operation.
+ operand_range getTagIndices() {
+ return {operand_begin() + getTagMemRefOperandIndex() + 1,
+ operand_begin() + getTagMemRefOperandIndex() + 1 +
+ getTagMap().getNumInputs()};
+ }
+
+ /// Returns the number of elements being transferred by this DMA operation.
+ Value getNumElements() {
+ return getOperand(getTagMemRefOperandIndex() + 1 +
+ getTagMap().getNumInputs());
+ }
+
+ /// Implements the AffineMapAccessInterface.
+ /// Returns the AffineMapAttr associated with 'memref'.
+ NamedAttribute getAffineMapAttrForMemRef(Value memref) {
+ if (memref == getSrcMemRef())
+ return {StringAttr::get(getContext(), getSrcMapAttrStrName()),
+ getSrcMapAttr()};
+ if (memref == getDstMemRef())
+ return {StringAttr::get(getContext(), getDstMapAttrStrName()),
+ getDstMapAttr()};
+ assert(memref == getTagMemRef() &&
+ "DmaStartOp expected source, destination or tag memref");
+ return {StringAttr::get(getContext(), getTagMapAttrStrName()),
+ getTagMapAttr()};
+ }
+
+ /// Returns true if this is a DMA from a faster memory space to a slower one.
+ bool isDestMemorySpaceFaster() {
+ return (getSrcMemorySpace() < getDstMemorySpace());
+ }
+
+ /// Returns true if this is a DMA from a slower memory space to a faster one.
+ bool isSrcMemorySpaceFaster() {
+ return (getDstMemorySpace() < getSrcMemorySpace());
+ }
+
+ /// Returns the operand position of either the source or destination memref
+ /// depending on which is at the higher level of the memory hierarchy.
+ unsigned getFasterMemPos() {
+ assert(isSrcMemorySpaceFaster() || isDestMemorySpaceFaster());
+ return isSrcMemorySpaceFaster() ? 0 : getDstMemRefOperandIndex();
+ }
+
+ static StringRef getSrcMapAttrStrName() { return "src_map"; }
+ static StringRef getDstMapAttrStrName() { return "dst_map"; }
+ static StringRef getTagMapAttrStrName() { return "tag_map"; }
+
+ /// Returns true if this DMA operation is strided, returns false otherwise.
+ bool isStrided() {
+ return getNumOperands() !=
+ getTagMemRefOperandIndex() + 1 + getTagMap().getNumInputs() + 1;
+ }
+
+ /// Returns the stride value for this DMA operation.
+ Value getStride() {
+ if (!isStrided())
+ return nullptr;
+ return getOperand(getNumOperands() - 1 - 1);
+ }
+
+ /// Returns the number of elements to transfer per stride for this DMA op.
+ Value getNumElementsPerStride() {
+ if (!isStrided())
+ return nullptr;
+ return getOperand(getNumOperands() - 1);
+ }
+
+ }];
+
+ let hasCustomAssemblyFormat = 1;
+ let hasVerifier = 1;
+ let hasFolder = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// AffineDmaWaitOp
+//===----------------------------------------------------------------------===//
+
+def AffineDmaWaitOp : Affine_Op<"dma_wait", [
+ MemRefsNormalizable,
+ DeclareOpInterfaceMethods<AffineMapAccessInterface>,
+ DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+ let summary = "affine dma wait operation";
+ let description = [{
+ The `affine.dma_wait` op blocks until the completion of a DMA operation
+ associated with the tag element `%tag[%index]`. `%tag` is a memref, and
+ `%index` has to be an index with the same restrictions as any load/store
+ index. In particular, index for each memref dimension must be an affine
+ expression of loop induction variables and symbols. `%num_elements` is the
+ number of elements associated with the DMA operation.
+
+ Example:
+
+ ```mlir
+ affine.dma_start %src[%i, %j], %dst[%k, %l], %tag[%index], %num_elements :
+ memref<2048xf32, 0>, memref<256xf32, 1>, memref<1xi32, 2>
+ ...
+ affine.dma_wait %tag[%index], %num_elements : memref<1xi32, 2>
+ ```
+ }];
+
+ let arguments = (ins
+ Variadic<AnyType>,
+ AffineMapAttr:$tag_map);
+
+ let results = (outs);
+
+ let skipDefaultBuilders = 1;
+ let builders = [
+ OpBuilder<(ins "Value":$tagMemRef, "AffineMap":$tagMap,
+ "ValueRange":$tagIndices, "Value":$numElements)>
+ ];
+
+ let extraClassDeclaration = [{
+ /// Returns the tag MemRef associated with the DMA operation being waited on.
+ Value getTagMemRef() { return getOperand(0); }
+ OpOperand &getTagMemRefMutable() {
+ return getOperation()->getOpOperand(0);
+ }
+ MemRefType getTagMemRefType() {
+ return ::llvm::cast<MemRefType>(getTagMemRef().getType());
+ }
+
+ /// Returns the tag memref index for this DMA operation.
+ operand_range getTagIndices() {
+ return {operand_begin() + 1,
+ operand_begin() + 1 + getTagMap().getNumInputs()};
+ }
+
+ /// Returns the rank (number of indices) of the tag memref.
+ unsigned getTagMemRefRank() {
+ return ::llvm::cast<MemRefType>(getTagMemRef().getType()).getRank();
+ }
+
+ /// Implements the AffineMapAccessInterface. Returns the AffineMapAttr
+ /// associated with 'memref'.
+ NamedAttribute getAffineMapAttrForMemRef(Value memref) {
+ assert(memref == getTagMemRef());
+ return {StringAttr::get(getContext(), getTagMapAttrStrName()),
+ getTagMapAttr()};
+ }
+
+ /// Returns the number of elements transferred by the associated DMA op.
+ Value getNumElements() {
+ return getOperand(1 + getTagMap().getNumInputs());
+ }
+
+ static StringRef getTagMapAttrStrName() { return "tag_map"; }
+
+ }];
+
+ let hasCustomAssemblyFormat = 1;
+ let hasVerifier = 1;
+ let hasFolder = 1;
+}
+
#endif // AFFINE_OPS
diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
index 871c7df2f71e5..a5e4b1c4d0a6f 100644
--- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
@@ -224,10 +224,10 @@ struct AffineInlinerInterface : public DialectInlinerInterface {
//===----------------------------------------------------------------------===//
void AffineDialect::initialize() {
- addOperations<AffineDmaStartOp, AffineDmaWaitOp,
+ addOperations<
#define GET_OP_LIST
#include "mlir/Dialect/Affine/IR/AffineOps.cpp.inc"
- >();
+ >();
addInterfaces<AffineInlinerInterface>();
declarePromisedInterfaces<ValueBoundsOpInterface, AffineApplyOp, AffineMaxOp,
AffineMinOp>();
@@ -1885,32 +1885,6 @@ void AffineDmaStartOp::build(OpBuilder &builder, OperationState &result,
}
}
-AffineDmaStartOp AffineDmaStartOp::create(
- OpBuilder &builder, Location location, Value srcMemRef, AffineMap srcMap,
- ValueRange srcIndices, Value destMemRef, AffineMap dstMap,
- ValueRange destIndices, Value tagMemRef, AffineMap tagMap,
- ValueRange tagIndices, Value numElements, Value stride,
- Value elementsPerStride) {
- mlir::OperationState state(location, getOperationName());
- build(builder, state, srcMemRef, srcMap, srcIndices, destMemRef, dstMap,
- destIndices, tagMemRef, tagMap, tagIndices, numElements, stride,
- elementsPerStride);
- auto result = dyn_cast<AffineDmaStartOp>(builder.create(state));
- assert(result && "builder didn't return the right type");
- return result;
-}
-
-AffineDmaStartOp AffineDmaStartOp::create(
- ImplicitLocOpBuilder &builder, Value srcMemRef, AffineMap srcMap,
- ValueRange srcIndices, Value destMemRef, AffineMap dstMap,
- ValueRange destIndices, Value tagMemRef, AffineMap tagMap,
- ValueRange tagIndices, Value numElements, Value stride,
- Value elementsPerStride) {
- return create(builder, builder.getLoc(), srcMemRef, srcMap, srcIndices,
- destMemRef, dstMap, destIndices, tagMemRef, tagMap, tagIndices,
- numElements, stride, elementsPerStride);
-}
-
void AffineDmaStartOp::print(OpAsmPrinter &p) {
p << " " << getSrcMemRef() << '[';
p.printAffineMapOfSSAIds(getSrcMapAttr(), getSrcIndices());
@@ -2009,7 +1983,7 @@ ParseResult AffineDmaStartOp::parse(OpAsmParser &parser,
return success();
}
-LogicalResult AffineDmaStartOp::verifyInvariantsImpl() {
+LogicalResult AffineDmaStartOp::verify() {
if (!llvm::isa<MemRefType>(getOperand(getSrcMemRefOperandIndex()).getType()))
return emitOpError("expected DMA source to be of memref type");
if (!llvm::isa<MemRefType>(getOperand(getDstMemRefOperandIndex()).getType()))
@@ -2050,7 +2024,7 @@ LogicalResult AffineDmaStartOp::verifyInvariantsImpl() {
return success();
}
-LogicalResult AffineDmaStartOp::fold(ArrayRef<Attribute> cstOperands,
+LogicalResult AffineDmaStartOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
/// dma_start(memrefcast) -> dma_start
return memref::foldMemRefCast(*this);
@@ -2081,25 +2055,6 @@ void AffineDmaWaitOp::build(OpBuilder &builder, OperationState &result,
result.addOperands(numElements);
}
-AffineDmaWaitOp AffineDmaWaitOp::create(OpBuilder &builder, Location location,
- Value tagMemRef, AffineMap tagMap,
- ValueRange tagIndices,
- Value numElements) {
- mlir::OperationState state(location, getOperationName());
- build(builder, state, tagMemRef, tagMap, tagIndices, numElements);
- auto result = dyn_cast<AffineDmaWaitOp>(builder.create(state));
- assert(result && "builder didn't return the right type");
- return result;
-}
-
-AffineDmaWaitOp AffineDmaWaitOp::create(ImplicitLocOpBuilder &builder,
- Value tagMemRef, AffineMap tagMap,
- ValueRange tagIndices,
- Value numElements) {
- return create(builder, builder.getLoc(), tagMemRef, tagMap, tagIndices,
- numElements);
-}
-
void AffineDmaWaitOp::print(OpAsmPrinter &p) {
p << " " << getTagMemRef() << '[';
SmallVector<Value, 2> operands(getTagIndices());
@@ -2145,7 +2100,7 @@ ParseResult AffineDmaWaitOp::parse(OpAsmParser &parser,
return success();
}
-LogicalResult AffineDmaWaitOp::verifyInvariantsImpl() {
+LogicalResult AffineDmaWaitOp::verify() {
if (!llvm::isa<MemRefType>(getOperand(0).getType()))
return emitOpError("expected DMA tag to be of memref type");
Region *scope = getAffineScope(*this);
@@ -2159,7 +2114,7 @@ LogicalResult AffineDmaWaitOp::verifyInvariantsImpl() {
return success();
}
-LogicalResult AffineDmaWaitOp::fold(ArrayRef<Attribute> cstOperands,
+LogicalResult AffineDmaWaitOp::fold(FoldAdaptor adaptor,
SmallVectorImpl<OpFoldResult> &results) {
/// dma_wait(memrefcast) -> dma_wait
return memref::foldMemRefCast(*this);
>From 75731560686b83c30780f0d119d519ceb3bbc241 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Thu, 19 Feb 2026 09:25:10 -0800
Subject: [PATCH 2/2] [MLIR] Remove deprecated setting
usePropertiesForAttributes
This was slotted for removal in LLVM 19 in the release notes of LLVM 17, we're
way past it now.
---
mlir/include/mlir/IR/DialectBase.td | 3 -
mlir/include/mlir/IR/OperationSupport.h | 17 +-
mlir/include/mlir/TableGen/Dialect.h | 4 -
mlir/lib/TableGen/Dialect.cpp | 4 -
mlir/test/mlir-tblgen/op-attribute.td | 47 ----
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 259 ++++----------------
mlir/tools/mlir-tblgen/OpFormatGen.cpp | 59 ++---
mlir/tools/mlir-tblgen/RewriterGen.cpp | 51 +---
mlir/unittests/Bytecode/BytecodeTest.cpp | 5 +-
mlir/unittests/IR/OpPropertiesTest.cpp | 5 +-
10 files changed, 95 insertions(+), 359 deletions(-)
diff --git a/mlir/include/mlir/IR/DialectBase.td b/mlir/include/mlir/IR/DialectBase.td
index 115a01f92706a..efa09a43ec581 100644
--- a/mlir/include/mlir/IR/DialectBase.td
+++ b/mlir/include/mlir/IR/DialectBase.td
@@ -92,9 +92,6 @@ class Dialect {
// If this dialect can be extended at runtime with new operations or types.
bit isExtensible = 0;
-
- // Whether inherent Attributes defined in ODS will be stored as Properties.
- bit usePropertiesForAttributes = 1;
}
#endif // DIALECTBASE_TD
diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h
index 1ff7c56ddca38..389261c72b2a3 100644
--- a/mlir/include/mlir/IR/OperationSupport.h
+++ b/mlir/include/mlir/IR/OperationSupport.h
@@ -570,9 +570,7 @@ class RegisteredOperationName : public OperationName {
return ConcreteOp::getInherentAttr(concreteOp->getContext(),
concreteOp.getProperties(), name);
}
- // If the op does not have support for properties, we dispatch back to the
- // dictionnary of discardable attributes for now.
- return cast<ConcreteOp>(op)->getDiscardableAttr(name);
+ return std::nullopt;
}
void setInherentAttr(Operation *op, StringAttr name,
Attribute value) final {
@@ -581,9 +579,8 @@ class RegisteredOperationName : public OperationName {
return ConcreteOp::setInherentAttr(concreteOp.getProperties(), name,
value);
}
- // If the op does not have support for properties, we dispatch back to the
- // dictionnary of discardable attributes for now.
- return cast<ConcreteOp>(op)->setDiscardableAttr(name, value);
+ llvm_unreachable(
+ "Can't call setInherentAttr on operation with empty properties");
}
void populateInherentAttrs(Operation *op, NamedAttrList &attrs) final {
if constexpr (hasProperties) {
@@ -639,7 +636,7 @@ class RegisteredOperationName : public OperationName {
auto p = properties.as<Properties *>();
return ConcreteOp::setPropertiesFromAttr(*p, attr, emitError);
}
- emitError() << "this operation does not support properties";
+ emitError() << "this operation has empty properties";
return failure();
}
Attribute getPropertiesAsAttr(Operation *op) final {
@@ -651,11 +648,9 @@ class RegisteredOperationName : public OperationName {
return {};
}
bool compareProperties(OpaqueProperties lhs, OpaqueProperties rhs) final {
- if constexpr (hasProperties) {
+ if constexpr (hasProperties)
return *lhs.as<Properties *>() == *rhs.as<Properties *>();
- } else {
- return true;
- }
+ return true;
}
void copyProperties(OpaqueProperties lhs, OpaqueProperties rhs) final {
*lhs.as<Properties *>() = *rhs.as<Properties *>();
diff --git a/mlir/include/mlir/TableGen/Dialect.h b/mlir/include/mlir/TableGen/Dialect.h
index 37c6427a9282a..30f9d690b678d 100644
--- a/mlir/include/mlir/TableGen/Dialect.h
+++ b/mlir/include/mlir/TableGen/Dialect.h
@@ -88,10 +88,6 @@ class Dialect {
/// operations or types.
bool isExtensible() const;
- /// Default to use properties for storing Attributes for operations in this
- /// dialect.
- bool usePropertiesForAttributes() const;
-
const llvm::DagInit *getDiscardableAttributes() const;
const llvm::Record *getDef() const { return def; }
diff --git a/mlir/lib/TableGen/Dialect.cpp b/mlir/lib/TableGen/Dialect.cpp
index ef39818e439b3..7aaf4dd57c50e 100644
--- a/mlir/lib/TableGen/Dialect.cpp
+++ b/mlir/lib/TableGen/Dialect.cpp
@@ -102,10 +102,6 @@ bool Dialect::isExtensible() const {
return def->getValueAsBit("isExtensible");
}
-bool Dialect::usePropertiesForAttributes() const {
- return def->getValueAsBit("usePropertiesForAttributes");
-}
-
const llvm::DagInit *Dialect::getDiscardableAttributes() const {
return def->getValueAsDag("discardableAttrs");
}
diff --git a/mlir/test/mlir-tblgen/op-attribute.td b/mlir/test/mlir-tblgen/op-attribute.td
index 4107c1fcc26ce..cfdaaebb9e91e 100644
--- a/mlir/test/mlir-tblgen/op-attribute.td
+++ b/mlir/test/mlir-tblgen/op-attribute.td
@@ -469,53 +469,6 @@ def EOp : NS_Op<"e_op", []> {
// DECL-LABEL: EOp declarations
// DECL: static void build({{.*}}, uint32_t i32_attr, uint32_t dv_i32_attr, ::llvm::APFloat f64_attr, ::llvm::APFloat dv_f64_attr, ::llvm::StringRef str_attr, ::llvm::StringRef dv_str_attr, bool bool_attr, bool dv_bool_attr, ::SomeI32Enum enum_attr, ::SomeI32Enum dv_enum_attr = ::SomeI32Enum::case5)
-// Test verifyInvariantsImpl for op in dialect with `usePropertiesForAttributes = 0` set.
-// ---
-
-def Test3_Dialect : Dialect {
- let name = "test3";
- let cppNamespace = "foobar3";
- let usePropertiesForAttributes = 0;
-}
-def FOp : Op<Test3_Dialect, "f_op", []> {
- let arguments = (ins
- SomeAttr:$aAttr,
- DefaultValuedOptionalAttr<SomeAttr, "4.2">:$bAttr,
- OptionalAttr<SomeAttr>:$cAttr
- );
-}
-
-// DEF-LABEL: FOp definitions
-// DEF: ::llvm::LogicalResult FOp::verifyInvariantsImpl() {
-// DEF: auto namedAttrRange = (*this)->getAttrs();
-// DEF: auto namedAttrIt = namedAttrRange.begin();
-// DEF: ::mlir::Attribute tblgen_aAttr;
-
-// DEF: while (true) {
-// DEF: if (namedAttrIt == namedAttrRange.end())
-// DEF: return emitOpError("requires attribute 'aAttr'");
-// DEF: if (namedAttrIt->getName() == getAAttrAttrName()) {
-// DEF: tblgen_aAttr = namedAttrIt->getValue();
-// DEF: break;
-// DEF: }
-// DEF: ++namedAttrIt;
-// DEF: }
-
-// DEF: ::mlir::Attribute tblgen_bAttr;
-// DEF: ::mlir::Attribute tblgen_cAttr;
-// DEF: while (true) {
-// DEF: if (namedAttrIt == namedAttrRange.end()) {
-// DEF: break;
-// DEF: }
-// DEF: else if (namedAttrIt->getName() == getBAttrAttrName()) {
-// DEF: tblgen_bAttr = namedAttrIt->getValue();
-// DEF: }
-// DEF: else if (namedAttrIt->getName() == getCAttrAttrName()) {
-// DEF: tblgen_cAttr = namedAttrIt->getValue();
-// DEF: }
-// DEF: ++namedAttrIt;
-// DEF: }
-
// Test proper namespacing for AttrDef
// ---
diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index d1f1e85371133..5fb8dc4deac82 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -123,21 +123,10 @@ static const char *const attrSizedSegmentValueRangeCalcCode = R"(
/// The code snippet to initialize the sizes for the value range calculation.
///
/// {0}: The code to get the attribute.
-static const char *const adapterSegmentSizeAttrInitCode = R"(
- assert({0} && "missing segment size attribute for op");
- auto sizeAttr = ::llvm::cast<::mlir::DenseI32ArrayAttr>({0});
-)";
static const char *const adapterSegmentSizeAttrInitCodeProperties = R"(
::llvm::ArrayRef<int32_t> sizeAttr = {0};
)";
-/// The code snippet to initialize the sizes for the value range calculation.
-///
-/// {0}: The code to get the attribute.
-static const char *const opSegmentSizeAttrInitCode = R"(
- auto sizeAttr = ::llvm::cast<::mlir::DenseI32ArrayAttr>({0});
-)";
-
/// The logic to calculate the actual value range for a declared operand
/// of an op with variadic of variadic operands within the OpAdaptor.
///
@@ -431,8 +420,6 @@ class OpOrAdaptorHelper {
bool hasProperties() const {
if (!op.getProperties().empty())
return true;
- if (!op.getDialect().usePropertiesForAttributes())
- return false;
return true;
}
@@ -537,36 +524,22 @@ void OpOrAdaptorHelper::computeAttrMetadata() {
};
// Include key attributes from several traits as implicitly registered.
if (op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments")) {
- if (op.getDialect().usePropertiesForAttributes()) {
- operandSegmentsSizeStorage =
- llvm::formatv("std::array<int32_t, {0}>", op.getNumOperands());
- operandSegmentsSizeParser =
- llvm::formatv(parseTextualSegmentSizeFormat, op.getNumOperands());
- operandSegmentsSize = {
- "operandSegmentSizes",
- makeProperty(operandSegmentsSizeStorage, operandSegmentsSizeParser)};
- } else {
- attrMetadata.insert(
- {operandSegmentAttrName, AttributeMetadata{operandSegmentAttrName,
- /*isRequired=*/true,
- /*attr=*/std::nullopt}});
- }
+ operandSegmentsSizeStorage =
+ llvm::formatv("std::array<int32_t, {0}>", op.getNumOperands());
+ operandSegmentsSizeParser =
+ llvm::formatv(parseTextualSegmentSizeFormat, op.getNumOperands());
+ operandSegmentsSize = {
+ "operandSegmentSizes",
+ makeProperty(operandSegmentsSizeStorage, operandSegmentsSizeParser)};
}
if (op.getTrait("::mlir::OpTrait::AttrSizedResultSegments")) {
- if (op.getDialect().usePropertiesForAttributes()) {
- resultSegmentsSizeStorage =
- llvm::formatv("std::array<int32_t, {0}>", op.getNumResults());
- resultSegmentsSizeParser =
- llvm::formatv(parseTextualSegmentSizeFormat, op.getNumResults());
- resultSegmentsSize = {
- "resultSegmentSizes",
- makeProperty(resultSegmentsSizeStorage, resultSegmentsSizeParser)};
- } else {
- attrMetadata.insert(
- {resultSegmentAttrName,
- AttributeMetadata{resultSegmentAttrName, /*isRequired=*/true,
- /*attr=*/std::nullopt}});
- }
+ resultSegmentsSizeStorage =
+ llvm::formatv("std::array<int32_t, {0}>", op.getNumResults());
+ resultSegmentsSizeParser =
+ llvm::formatv(parseTextualSegmentSizeFormat, op.getNumResults());
+ resultSegmentsSize = {
+ "resultSegmentSizes",
+ makeProperty(resultSegmentsSizeStorage, resultSegmentsSizeParser)};
}
// Store the metadata in sorted order.
@@ -865,43 +838,6 @@ static void populateSubstitutions(const OpOrAdaptorHelper &emitHelper,
}
}
-/// Generate verification on native traits requiring attributes.
-static void genNativeTraitAttrVerifier(MethodBody &body,
- const OpOrAdaptorHelper &emitHelper) {
- // Check that the variadic segment sizes attribute exists and contains the
- // expected number of elements.
- //
- // {0}: Attribute name.
- // {1}: Expected number of elements.
- // {2}: "operand" or "result".
- // {3}: Emit error prefix.
- const char *const checkAttrSizedValueSegmentsCode = R"(
- {
- auto sizeAttr = ::llvm::cast<::mlir::DenseI32ArrayAttr>(tblgen_{0});
- auto numElements = sizeAttr.asArrayRef().size();
- if (numElements != {1})
- return {3}"'{0}' attribute for specifying {2} segments must have {1} "
- "elements, but got ") << numElements;
- }
- )";
-
- // Verify a few traits first so that we can use getODSOperands() and
- // getODSResults() in the rest of the verifier.
- auto &op = emitHelper.getOp();
- if (!op.getDialect().usePropertiesForAttributes()) {
- if (op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments")) {
- body << formatv(checkAttrSizedValueSegmentsCode, operandSegmentAttrName,
- op.getNumOperands(), "operand",
- emitHelper.emitErrorPrefix());
- }
- if (op.getTrait("::mlir::OpTrait::AttrSizedResultSegments")) {
- body << formatv(checkAttrSizedValueSegmentsCode, resultSegmentAttrName,
- op.getNumResults(), "result",
- emitHelper.emitErrorPrefix());
- }
- }
-}
-
// Return true if a verifier can be emitted for the attribute: it is not a
// derived attribute, it has a predicate, its condition is not empty, and, for
// adaptors, the condition does not reference the op.
@@ -1077,10 +1013,6 @@ while (true) {{
}
body.unindent();
- // Emit the checks for segment attributes first so that the other
- // constraints can call operand and result getters.
- genNativeTraitAttrVerifier(body, emitHelper);
-
bool isEmittingForOp = emitHelper.isEmittingForOp();
for (const auto &namedAttr : emitHelper.getOp().getAttributes())
if (canEmitAttrVerifier(namedAttr.attr, isEmittingForOp))
@@ -1275,7 +1207,6 @@ void OpEmitter::genAttrNameGetters() {
const llvm::MapVector<StringRef, AttributeMetadata> &attributes =
emitHelper.getAttrMetadata();
bool hasOperandSegmentsSize =
- op.getDialect().usePropertiesForAttributes() &&
op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments");
// Emit the getAttributeNames method.
{
@@ -2039,18 +1970,11 @@ void OpEmitter::genAttrGetters() {
}
void OpEmitter::genAttrSetters() {
- bool useProperties = op.getDialect().usePropertiesForAttributes();
-
// Generate the code to set an attribute.
auto emitSetAttr = [&](Method *method, StringRef getterName,
StringRef attrName, StringRef attrVar) {
- if (useProperties) {
- method->body() << formatv(" getProperties().{0} = {1};", attrName,
- attrVar);
- } else {
- method->body() << formatv(" (*this)->setAttr({0}AttrName(), {1});",
- getterName, attrVar);
- }
+ method->body() << formatv(" getProperties().{0} = {1};", attrName,
+ attrVar);
};
// Generate raw named setter type. This is a wrapper class that allows setting
@@ -2110,25 +2034,15 @@ void OpEmitter::genAttrSetters() {
// optional but not in the same way as the others (i.e. it uses bool over
// std::optional<>).
StringRef paramStr = isUnitAttr ? "attrValue" : "*attrValue";
- if (!useProperties) {
- const char *optionalCodeBody = R"(
- if (attrValue)
- return (*this)->setAttr({0}AttrName(), {1});
- (*this)->removeAttr({0}AttrName());)";
- method->body() << formatv(
- optionalCodeBody, getterName,
- constBuildAttrFromParam(baseAttr, fctx, paramStr));
- } else {
- const char *optionalCodeBody = R"(
+ const char *optionalCodeBody = R"(
auto &odsProp = getProperties().{0};
if (attrValue)
odsProp = {1};
else
odsProp = nullptr;)";
- method->body() << formatv(
- optionalCodeBody, attrName,
- constBuildAttrFromParam(baseAttr, fctx, paramStr));
- }
+ method->body() << formatv(
+ optionalCodeBody, attrName,
+ constBuildAttrFromParam(baseAttr, fctx, paramStr));
};
for (const NamedAttribute &namedAttr : op.getAttributes()) {
@@ -2146,28 +2060,22 @@ void OpEmitter::genAttrSetters() {
void OpEmitter::genOptionalAttrRemovers() {
// Generate methods for removing optional attributes, instead of having to
// use the string interface. Enables better compile time verification.
- auto emitRemoveAttr = [&](StringRef name, bool useProperties) {
+ auto emitRemoveAttr = [&](StringRef name) {
auto *method = opClass.addInlineMethod("::mlir::Attribute",
op.getRemoverName(name) + "Attr");
if (!method)
return;
- if (useProperties) {
- method->body() << formatv(R"(
+ method->body() << formatv(R"(
auto attr = getProperties().{0};
getProperties().{0} = {{};
return attr;
)",
- name);
- return;
- }
- method->body() << formatv("return (*this)->removeAttr({0}AttrName());",
- op.getGetterName(name));
+ name);
};
for (const NamedAttribute &namedAttr : op.getAttributes())
if (namedAttr.attr.isOptional())
- emitRemoveAttr(namedAttr.name,
- op.getDialect().usePropertiesForAttributes());
+ emitRemoveAttr(namedAttr.name);
}
// Generates the code to compute the start and end index of an operand or result
@@ -2366,13 +2274,8 @@ void OpEmitter::genNamedOperandGetters() {
// array.
std::string attrSizeInitCode;
if (op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments")) {
- if (op.getDialect().usePropertiesForAttributes())
- attrSizeInitCode = formatv(adapterSegmentSizeAttrInitCodeProperties,
- "getProperties().operandSegmentSizes");
-
- else
- attrSizeInitCode = formatv(opSegmentSizeAttrInitCode,
- emitHelper.getAttr(operandSegmentAttrName));
+ attrSizeInitCode = formatv(adapterSegmentSizeAttrInitCodeProperties,
+ "getProperties().operandSegmentSizes");
}
generateNamedOperandGetters(
@@ -2483,13 +2386,8 @@ void OpEmitter::genNamedResultGetters() {
// Build the initializer string for the result segment size attribute.
std::string attrSizeInitCode;
if (attrSizedResults) {
- if (op.getDialect().usePropertiesForAttributes())
- attrSizeInitCode = formatv(adapterSegmentSizeAttrInitCodeProperties,
- "getProperties().resultSegmentSizes");
-
- else
- attrSizeInitCode = formatv(opSegmentSizeAttrInitCode,
- emitHelper.getAttr(resultSegmentAttrName));
+ attrSizeInitCode = formatv(adapterSegmentSizeAttrInitCodeProperties,
+ "getProperties().resultSegmentSizes");
}
generateValueRangeStartAndEnd(
@@ -2722,14 +2620,7 @@ void OpEmitter::genSeparateArgParamBuilder() {
// Automatically create the 'resultSegmentSizes' attribute using
// the length of the type ranges.
if (op.getTrait("::mlir::OpTrait::AttrSizedResultSegments")) {
- if (op.getDialect().usePropertiesForAttributes()) {
- body << " ::llvm::copy(::llvm::ArrayRef<int32_t>({";
- } else {
- std::string getterName = op.getGetterName(resultSegmentAttrName);
- body << " " << builderOpState << ".addAttribute(" << getterName
- << "AttrName(" << builderOpState << ".name), "
- << "odsBuilder.getDenseI32ArrayAttr({";
- }
+ body << " ::llvm::copy(::llvm::ArrayRef<int32_t>({";
interleaveComma(
llvm::seq<int>(0, op.getNumResults()), body, [&](int i) {
const NamedTypeConstraint &result = op.getResult(i);
@@ -2746,13 +2637,9 @@ void OpEmitter::genSeparateArgParamBuilder() {
body << "static_cast<int32_t>(" << resultNames[i] << ".size())";
}
});
- if (op.getDialect().usePropertiesForAttributes()) {
- body << "}), " << builderOpState
- << ".getOrAddProperties<Properties>()."
- "resultSegmentSizes.begin());\n";
- } else {
- body << "}));\n";
- }
+ body << "}), " << builderOpState
+ << ".getOrAddProperties<Properties>()."
+ "resultSegmentSizes.begin());\n";
}
return;
@@ -3501,16 +3388,9 @@ void OpEmitter::genCodeForAddingArgAndRegionForBuilder(
<< " rangeSegments.push_back(range.size());\n"
<< " auto rangeAttr = " << odsBuilder
<< ".getDenseI32ArrayAttr(rangeSegments);\n";
- if (op.getDialect().usePropertiesForAttributes()) {
- body << " " << builderOpState << ".getOrAddProperties<Properties>()."
- << operand.constraint.getVariadicOfVariadicSegmentSizeAttr()
- << " = rangeAttr;";
- } else {
- body << " " << builderOpState << ".addAttribute("
- << op.getGetterName(
- operand.constraint.getVariadicOfVariadicSegmentSizeAttr())
- << "AttrName(" << builderOpState << ".name), rangeAttr);";
- }
+ body << " " << builderOpState << ".getOrAddProperties<Properties>()."
+ << operand.constraint.getVariadicOfVariadicSegmentSizeAttr()
+ << " = rangeAttr;";
body << " }\n";
continue;
}
@@ -3545,19 +3425,11 @@ void OpEmitter::genCodeForAddingArgAndRegionForBuilder(
};
if (op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments")) {
std::string sizes = op.getGetterName(operandSegmentAttrName);
- if (op.getDialect().usePropertiesForAttributes()) {
- body << " ::llvm::copy(::llvm::ArrayRef<int32_t>({";
- emitSegment();
- body << "}), " << builderOpState
- << ".getOrAddProperties<Properties>()."
- "operandSegmentSizes.begin());\n";
- } else {
- body << " " << builderOpState << ".addAttribute(" << sizes << "AttrName("
- << builderOpState << ".name), "
- << "odsBuilder.getDenseI32ArrayAttr({";
- emitSegment();
- body << "}));\n";
- }
+ body << " ::llvm::copy(::llvm::ArrayRef<int32_t>({";
+ emitSegment();
+ body << "}), " << builderOpState
+ << ".getOrAddProperties<Properties>()."
+ "operandSegmentSizes.begin());\n";
}
// Push all properties to the result.
@@ -3591,24 +3463,12 @@ void OpEmitter::genCodeForAddingArgAndRegionForBuilder(
// instance.
FmtContext fctx;
fctx.withBuilder("odsBuilder");
- if (op.getDialect().usePropertiesForAttributes()) {
- body << formatv(" {0}.getOrAddProperties<Properties>().{1} = {2};\n",
- builderOpState, namedAttr.name,
- constBuildAttrFromParam(attr, fctx, namedAttr.name));
- } else {
- body << formatv(" {0}.addAttribute({1}AttrName({0}.name), {2});\n",
- builderOpState, op.getGetterName(namedAttr.name),
- constBuildAttrFromParam(attr, fctx, namedAttr.name));
- }
+ body << formatv(" {0}.getOrAddProperties<Properties>().{1} = {2};\n",
+ builderOpState, namedAttr.name,
+ constBuildAttrFromParam(attr, fctx, namedAttr.name));
} else {
- if (op.getDialect().usePropertiesForAttributes()) {
- body << formatv(" {0}.getOrAddProperties<Properties>().{1} = {1};\n",
- builderOpState, namedAttr.name);
- } else {
- body << formatv(" {0}.addAttribute({1}AttrName({0}.name), {2});\n",
- builderOpState, op.getGetterName(namedAttr.name),
- namedAttr.name);
- }
+ body << formatv(" {0}.getOrAddProperties<Properties>().{1} = {1};\n",
+ builderOpState, namedAttr.name);
}
if (emitNotNullCheck)
body.unindent() << " }\n";
@@ -3935,20 +3795,12 @@ void OpEmitter::genTypeInterfaceMethods() {
} else if (auto *attr = dyn_cast<NamedAttribute *>(
op.getArg(arg.operandOrAttributeIndex()))) {
body << " ::mlir::TypedAttr odsInferredTypeAttr" << inferredTypeIdx
- << " = ";
- if (op.getDialect().usePropertiesForAttributes()) {
- body << "(properties ? properties.as<Properties *>()->"
- << attr->name
- << " : "
- "::llvm::dyn_cast_or_null<::mlir::TypedAttr>(attributes."
- "get(\"" +
- attr->name + "\")));\n";
- } else {
- body << "::llvm::dyn_cast_or_null<::mlir::TypedAttr>(attributes."
- "get(\"" +
- attr->name + "\"));\n";
- }
- body << " if (!odsInferredTypeAttr" << inferredTypeIdx
+ << " = (properties ? properties.as<Properties *>()->"
+ << attr->name
+ << " : ::llvm::dyn_cast_or_null<::mlir::TypedAttr>(attributes."
+ "get(\""
+ << attr->name << "\")));\n"
+ << " if (!odsInferredTypeAttr" << inferredTypeIdx
<< ") return ::mlir::failure();\n";
typeStr =
("odsInferredTypeAttr" + Twine(inferredTypeIdx) + ".getType()")
@@ -4672,13 +4524,8 @@ OpOperandAdaptorEmitter::OpOperandAdaptorEmitter(
std::string sizeAttrInit;
if (op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments")) {
- if (op.getDialect().usePropertiesForAttributes())
- sizeAttrInit =
- formatv(adapterSegmentSizeAttrInitCodeProperties,
- llvm::formatv("getProperties().operandSegmentSizes"));
- else
- sizeAttrInit = formatv(adapterSegmentSizeAttrInitCode,
- emitHelper.getAttr(operandSegmentAttrName));
+ sizeAttrInit = formatv(adapterSegmentSizeAttrInitCodeProperties,
+ "getProperties().operandSegmentSizes");
}
generateNamedOperandGetters(op, genericAdaptor,
/*genericAdaptorBase=*/&genericAdaptorBase,
diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
index b834c6f8d3aaf..2031376ec8cfc 100644
--- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
@@ -1915,38 +1915,22 @@ void OperationFormat::genParserVariadicSegmentResolution(Operator &op,
else
body << "1";
};
- if (op.getDialect().usePropertiesForAttributes()) {
- body << "::llvm::copy(::llvm::ArrayRef<int32_t>({";
- llvm::interleaveComma(op.getOperands(), body, interleaveFn);
- body << formatv("}), "
- "result.getOrAddProperties<{0}::Properties>()."
- "operandSegmentSizes.begin());\n",
- op.getCppClassName());
- } else {
- body << " result.addAttribute(\"operandSegmentSizes\", "
- << "parser.getBuilder().getDenseI32ArrayAttr({";
- llvm::interleaveComma(op.getOperands(), body, interleaveFn);
- body << "}));\n";
- }
+ body << "::llvm::copy(::llvm::ArrayRef<int32_t>({";
+ llvm::interleaveComma(op.getOperands(), body, interleaveFn);
+ body << formatv("}), "
+ "result.getOrAddProperties<{0}::Properties>()."
+ "operandSegmentSizes.begin());\n",
+ op.getCppClassName());
}
for (const NamedTypeConstraint &operand : op.getOperands()) {
if (!operand.isVariadicOfVariadic())
continue;
- if (op.getDialect().usePropertiesForAttributes()) {
- body << formatv(
- " result.getOrAddProperties<{0}::Properties>().{1} = "
- "parser.getBuilder().getDenseI32ArrayAttr({2}OperandGroupSizes);\n",
- op.getCppClassName(),
- operand.constraint.getVariadicOfVariadicSegmentSizeAttr(),
- operand.name);
- } else {
- body << formatv(
- " result.addAttribute(\"{0}\", "
- "parser.getBuilder().getDenseI32ArrayAttr({1}OperandGroupSizes));"
- "\n",
- operand.constraint.getVariadicOfVariadicSegmentSizeAttr(),
- operand.name);
- }
+ body << formatv(
+ " result.getOrAddProperties<{0}::Properties>().{1} = "
+ "parser.getBuilder().getDenseI32ArrayAttr({2}OperandGroupSizes);\n",
+ op.getCppClassName(),
+ operand.constraint.getVariadicOfVariadicSegmentSizeAttr(),
+ operand.name);
}
}
@@ -1959,19 +1943,12 @@ void OperationFormat::genParserVariadicSegmentResolution(Operator &op,
else
body << "1";
};
- if (op.getDialect().usePropertiesForAttributes()) {
- body << "::llvm::copy(::llvm::ArrayRef<int32_t>({";
- llvm::interleaveComma(op.getResults(), body, interleaveFn);
- body << formatv("}), "
- "result.getOrAddProperties<{0}::Properties>()."
- "resultSegmentSizes.begin());\n",
- op.getCppClassName());
- } else {
- body << " result.addAttribute(\"resultSegmentSizes\", "
- << "parser.getBuilder().getDenseI32ArrayAttr({";
- llvm::interleaveComma(op.getResults(), body, interleaveFn);
- body << "}));\n";
- }
+ body << "::llvm::copy(::llvm::ArrayRef<int32_t>({";
+ llvm::interleaveComma(op.getResults(), body, interleaveFn);
+ body << formatv("}), "
+ "result.getOrAddProperties<{0}::Properties>()."
+ "resultSegmentSizes.begin());\n",
+ op.getCppClassName());
}
}
diff --git a/mlir/tools/mlir-tblgen/RewriterGen.cpp b/mlir/tools/mlir-tblgen/RewriterGen.cpp
index 08d6483e1f1b3..e3043708a46d1 100644
--- a/mlir/tools/mlir-tblgen/RewriterGen.cpp
+++ b/mlir/tools/mlir-tblgen/RewriterGen.cpp
@@ -892,15 +892,9 @@ void PatternEmitter::emitAttributeMatch(DagNode tree, StringRef castedName,
const auto &attr = namedAttr->attr;
os << "{\n";
- if (op.getDialect().usePropertiesForAttributes()) {
- os.indent() << formatv(
- "[[maybe_unused]] auto tblgen_attr = {0}.getProperties().{1}();\n",
- castedName, op.getGetterName(namedAttr->name));
- } else {
- os.indent() << formatv("[[maybe_unused]] auto tblgen_attr = "
- "{0}->getAttrOfType<{1}>(\"{2}\");\n",
- castedName, attr.getStorageType(), namedAttr->name);
- }
+ os.indent() << formatv(
+ "[[maybe_unused]] auto tblgen_attr = {0}.getProperties().{1}();\n",
+ castedName, op.getGetterName(namedAttr->name));
// TODO: This should use getter method to avoid duplication.
if (attr.hasDefaultValue()) {
@@ -1606,7 +1600,6 @@ std::string PatternEmitter::handleOpCreation(DagNode tree, int resultIndex,
LLVM_DEBUG(llvm::dbgs() << '\n');
Operator &resultOp = tree.getDialectOp(opMap);
- bool useProperties = resultOp.getDialect().usePropertiesForAttributes();
auto numOpArgs = resultOp.getNumArgs();
auto numPatArgs = tree.getNumArgs();
@@ -1698,10 +1691,9 @@ std::string PatternEmitter::handleOpCreation(DagNode tree, int resultIndex,
createAggregateLocalVarsForOpArgs(tree, childNodeNames, depth);
// Then create the op.
- os.scope("", "\n}\n").os
- << formatv("{0} = {1}::create(rewriter, {2}, tblgen_values, {3});",
- valuePackName, resultOp.getQualCppClassName(), locToUse,
- useProperties ? "tblgen_props" : "tblgen_attrs");
+ os.scope("", "\n}\n").os << formatv(
+ "{0} = {1}::create(rewriter, {2}, tblgen_values, {3});", valuePackName,
+ resultOp.getQualCppClassName(), locToUse, "tblgen_props");
return resultValue;
}
@@ -1760,7 +1752,7 @@ std::string PatternEmitter::handleOpCreation(DagNode tree, int resultIndex,
os << formatv("{0} = {1}::create(rewriter, {2}, tblgen_types, "
"tblgen_values, {3});\n",
valuePackName, resultOp.getQualCppClassName(), locToUse,
- useProperties ? "tblgen_props" : "tblgen_attrs");
+ "tblgen_props");
os.unindent() << "}\n";
return resultValue;
}
@@ -1874,26 +1866,15 @@ void PatternEmitter::createAggregateLocalVarsForOpArgs(
DagNode node, const ChildNodeIndexNameMap &childNodeNames, int depth) {
Operator &resultOp = node.getDialectOp(opMap);
- bool useProperties = resultOp.getDialect().usePropertiesForAttributes();
auto scope = os.scope();
os << formatv("::llvm::SmallVector<::mlir::Value, 4> "
"tblgen_values; (void)tblgen_values;\n");
- if (useProperties) {
- os << formatv("{0}::Properties tblgen_props; (void)tblgen_props;\n",
- resultOp.getQualCppClassName());
- } else {
- os << formatv("::llvm::SmallVector<::mlir::NamedAttribute, 4> "
- "tblgen_attrs; (void)tblgen_attrs;\n");
- }
+ os << formatv("{0}::Properties tblgen_props; (void)tblgen_props;\n",
+ resultOp.getQualCppClassName());
- const char *setPropCmd =
+ const char *setterCmd =
"tblgen_props.{0} = "
"::llvm::dyn_cast_if_present<decltype(tblgen_props.{0})>({1});\n";
- const char *addAttrCmd =
- "if (auto tmpAttr = {1}) {\n"
- " tblgen_attrs.emplace_back(rewriter.getStringAttr(\"{0}\"), "
- "tmpAttr);\n}\n";
- const char *setterCmd = (useProperties) ? setPropCmd : addAttrCmd;
const char *propSetterCmd = "tblgen_props.{0}({1});\n";
int numVariadic = 0;
@@ -1992,18 +1973,10 @@ void PatternEmitter::createAggregateLocalVarsForOpArgs(
const auto *sameVariadicSize =
resultOp.getTrait("::mlir::OpTrait::SameVariadicOperandSize");
if (!sameVariadicSize) {
- if (useProperties) {
- const char *setSizes = R"(
+ const char *setSizes = R"(
tblgen_props.operandSegmentSizes = {{ {0} };
)";
- os.printReindented(formatv(setSizes, llvm::join(sizes, ", ")).str());
- } else {
- const char *setSizes = R"(
- tblgen_attrs.emplace_back(rewriter.getStringAttr("operandSegmentSizes"),
- rewriter.getDenseI32ArrayAttr({{ {0} }));
- )";
- os.printReindented(formatv(setSizes, llvm::join(sizes, ", ")).str());
- }
+ os.printReindented(formatv(setSizes, llvm::join(sizes, ", ")).str());
}
}
}
diff --git a/mlir/unittests/Bytecode/BytecodeTest.cpp b/mlir/unittests/Bytecode/BytecodeTest.cpp
index 30e7ed9b6cb7e..148868801da33 100644
--- a/mlir/unittests/Bytecode/BytecodeTest.cpp
+++ b/mlir/unittests/Bytecode/BytecodeTest.cpp
@@ -223,8 +223,9 @@ TEST(Bytecode, OpWithoutProperties) {
llvm::MemoryBufferRef(bytecode, "string-buffer"), block.get(), config)));
Operation *roundtripped = &block->front();
EXPECT_EQ(roundtripped->getAttrs().size(), 2u);
- EXPECT_TRUE(roundtripped->getInherentAttr("inherent_attr") != std::nullopt);
- EXPECT_TRUE(roundtripped->getDiscardableAttr("other_attr") != Attribute());
+ EXPECT_EQ(roundtripped->getInherentAttr("inherent_attr"), std::nullopt);
+ EXPECT_NE(roundtripped->getDiscardableAttr("inherent_attr"), Attribute());
+ EXPECT_NE(roundtripped->getDiscardableAttr("other_attr"), Attribute());
EXPECT_TRUE(OperationEquivalence::computeHash(op.get()) ==
OperationEquivalence::computeHash(roundtripped));
diff --git a/mlir/unittests/IR/OpPropertiesTest.cpp b/mlir/unittests/IR/OpPropertiesTest.cpp
index 4759735d99605..bea69e9e8f107 100644
--- a/mlir/unittests/IR/OpPropertiesTest.cpp
+++ b/mlir/unittests/IR/OpPropertiesTest.cpp
@@ -399,8 +399,9 @@ TEST(OpPropertiesTest, withoutPropertiesDiscardableAttrs) {
"other_attr");
EXPECT_EQ(op->getAttrs().size(), 2u);
- EXPECT_TRUE(op->getInherentAttr("inherent_attr") != std::nullopt);
- EXPECT_TRUE(op->getDiscardableAttr("other_attr") != Attribute());
+ EXPECT_EQ(op->getInherentAttr("inherent_attr"), std::nullopt);
+ EXPECT_NE(op->getDiscardableAttr("inherent_attr"), Attribute());
+ EXPECT_NE(op->getDiscardableAttr("other_attr"), Attribute());
std::string output;
llvm::raw_string_ostream os(output);
More information about the Mlir-commits
mailing list