[Mlir-commits] [mlir] 39427a4 - [mlir][Linalg] Fold/erase self-copy linalg.copy on buffers
Nicolas Vasilache
llvmlistbot at llvm.org
Thu Jul 13 07:42:35 PDT 2023
Author: Nicolas Vasilache
Date: 2023-07-13T16:38:02+02:00
New Revision: 39427a4fbb6e6714b773909a08ab37f655850891
URL: https://github.com/llvm/llvm-project/commit/39427a4fbb6e6714b773909a08ab37f655850891
DIFF: https://github.com/llvm/llvm-project/commit/39427a4fbb6e6714b773909a08ab37f655850891.diff
LOG: [mlir][Linalg] Fold/erase self-copy linalg.copy on buffers
Differential Revision: https://reviews.llvm.org/D155203
Added:
Modified:
mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml
mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py
mlir/test/Dialect/Linalg/canonicalize.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml b/mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml
index d021376ff4cdcd..10de4e2811eb44 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml
@@ -9,6 +9,8 @@ metadata: !LinalgOpMetadata
Numeric casting is performed on the input operand, promoting it to the same
data type as the accumulator/output.
+ defines:
+ - hasCanonicalizer
structured_op: !LinalgStructuredOpConfig
args:
- !LinalgOperandDefConfig
diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
index a5c549a59eba83..a40618fd4ca6d7 100644
--- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
@@ -224,11 +224,11 @@ parseCommonStructuredOpParts(OpAsmParser &parser, OperationState &result,
if (addOperandSegmentSizes) {
// This is a bit complex because we're trying to be backward compatible with
- // operation syntax that mix the inherent attributes and the discardable ones
- // in the same dictionary.
- // If the properties are used, we append the operand_segment_sizes there directly.
- // Otherwise we append it to the discardable attributes dictionary where it is
- // handled by the generic Operation::create(...) method.
+ // operation syntax that mix the inherent attributes and the discardable
+ // ones in the same dictionary. If the properties are used, we append the
+ // operand_segment_sizes there directly. Otherwise we append it to the
+ // discardable attributes dictionary where it is handled by the generic
+ // Operation::create(...) method.
if (result.propertiesAttr) {
NamedAttrList attrs = llvm::cast<DictionaryAttr>(result.propertiesAttr);
attrs.append("operand_segment_sizes",
@@ -539,6 +539,33 @@ class RegionBuilderHelper {
} // namespace
+//===----------------------------------------------------------------------===//
+// CopyOp
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+struct EraseSelfCopyOnBuffers : OpRewritePattern<CopyOp> {
+ using OpRewritePattern<CopyOp>::OpRewritePattern;
+ LogicalResult matchAndRewrite(CopyOp copyOp,
+ PatternRewriter &rewriter) const override {
+ if (!copyOp.hasBufferSemantics())
+ return rewriter.notifyMatchFailure(copyOp,
+ "does not have buffer semantics");
+ if (copyOp.getInputs().front() != copyOp.getOutputs().front())
+ return rewriter.notifyMatchFailure(copyOp, "not a self copy");
+ rewriter.eraseOp(copyOp);
+ return success();
+ }
+};
+
+} // namespace
+
+void CopyOp::getCanonicalizationPatterns(RewritePatternSet &results,
+ MLIRContext *context) {
+ results.add<EraseSelfCopyOnBuffers>(context);
+}
+
//===----------------------------------------------------------------------===//
// FillOp
//===----------------------------------------------------------------------===//
@@ -2114,8 +2141,7 @@ static void createNewOperandWithStaticSizes(
for (unsigned i = 0; i < sourceShape.size(); i++) {
int64_t dimShape = sourceShape[i];
AffineExpr dimExpr = sourceMap.getResult(i);
- if (!affineExprToSize.contains(dimExpr) ||
- !sourceType.isDynamicDim(i)) {
+ if (!affineExprToSize.contains(dimExpr) || !sourceType.isDynamicDim(i)) {
newShape.push_back(dimShape);
continue;
}
diff --git a/mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py b/mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py
index e4512cd1e0573c..08818b2120bf04 100644
--- a/mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py
+++ b/mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py
@@ -17,6 +17,7 @@ def copy(
Numeric casting is performed on the input operand, promoting it to the same
data type as the accumulator/output.
"""
+ defines(Canonicalizer)
O[None] = cast(U, I[None])
diff --git a/mlir/test/Dialect/Linalg/canonicalize.mlir b/mlir/test/Dialect/Linalg/canonicalize.mlir
index 9e4d886c5b0adc..5f45ab40875af2 100644
--- a/mlir/test/Dialect/Linalg/canonicalize.mlir
+++ b/mlir/test/Dialect/Linalg/canonicalize.mlir
@@ -47,6 +47,16 @@ func.func @dce_zero_memref(%arg0 : memref<0xf32>, %arg1: tensor<0xf32>) -> tenso
// -----
+func.func @dce_self_linalg_copy(%arg0 : memref<?xf32>) {
+ linalg.copy ins(%arg0: memref<?xf32>) outs(%arg0: memref<?xf32>)
+ return
+}
+
+// CHECK-LABEL: @dce_self_linalg_copy
+// CHECK-NOT: copy
+
+// -----
+
// CHECK-LABEL: func @tensor.cast(
func.func @tensor.cast(%a : tensor<3x4xf32>, %b : tensor<4x?xf32>, %c : tensor<3x?xf32>)
-> tensor<3x?xf32>
More information about the Mlir-commits
mailing list