[Mlir-commits] [mlir] [MLIR][Linalg] Simplify tiling canonical pattern (PR #182909)

Renato Golin llvmlistbot at llvm.org
Tue Feb 24 07:36:21 PST 2026


https://github.com/rengolin updated https://github.com/llvm/llvm-project/pull/182909

>From 47ff35287cfdc3e2656585a9c03090ea15e768af Mon Sep 17 00:00:00 2001
From: Renato Golin <rengolin at systemcall.eu>
Date: Mon, 23 Feb 2026 17:57:15 +0000
Subject: [PATCH 1/2] [MLIR][Linalg] Simplify tiling canonical pattern

Prepare for better composition of canonicalization patterns by splitting
the linalg onw canonicalizers from others for particular purposes (ex.
tiling).

Once dialects have their own registration mechanisms, specific passes
can just add more ops/dialects using a yet-to-be-created helper that
would be similar to the existing
`populateLinalgTilingCanonicalizationPatterns`.

This is a _very_ small start of the larger refactory planned in
https://discourse.llvm.org/t/canonicalization-in-mlir/89841
---
 .../Linalg/TransformOps/LinalgTransformOps.td | 10 +++++
 .../Dialect/Linalg/Transforms/Transforms.h    |  4 +-
 .../TransformOps/LinalgTransformOps.cpp       |  5 +++
 mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp | 41 ++++++++-----------
 .../Linalg/TestLinalgFusionTransforms.cpp     |  4 +-
 5 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index 70d424bae9285..523a5fd28355b 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -80,6 +80,16 @@ def ApplyFoldUnitExtentDimsViaSlicesPatternsOp : Op<Transform_Dialect,
   let assemblyFormat = "attr-dict";
 }
 
+def ApplyLinalgCanonicalizationPatternsOp : Op<Transform_Dialect,
+    "apply_patterns.linalg.canonicalization",
+    [DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
+  let description = [{
+    Collects linalg dialect and operation canonicalization patterns.
+  }];
+
+  let assemblyFormat = "attr-dict";
+}
+
 def ApplyTilingCanonicalizationPatternsOp : Op<Transform_Dialect,
     "apply_patterns.linalg.tiling_canonicalization",
     [DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index 32067358438d3..1829c378eb6da 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -1925,10 +1925,12 @@ struct ExtractSliceOfPadTensorSwapPattern
 // Populate functions.
 //===----------------------------------------------------------------------===//
 
+/// Canonicalization patterns for Linalg operations only.
+void populateLinalgCanonicalizationPatterns(RewritePatternSet &patterns);
+
 /// Canonicalization patterns relevant to apply after tiling patterns. These
 /// are applied automatically by the tiling pass but need to be applied
 /// manually when tiling is called programmatically.
-RewritePatternSet getLinalgTilingCanonicalizationPatterns(MLIRContext *ctx);
 void populateLinalgTilingCanonicalizationPatterns(RewritePatternSet &patterns);
 
 /// Linalg generalization patterns
diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
index 78f1a61149a2b..e381ada9c9e22 100644
--- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
+++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
@@ -246,6 +246,11 @@ void transform::ApplyFoldUnitExtentDimsViaSlicesPatternsOp::populatePatterns(
   linalg::populateFoldUnitExtentDimsPatterns(patterns, options);
 }
 
+void transform::ApplyLinalgCanonicalizationPatternsOp::populatePatterns(
+    RewritePatternSet &patterns) {
+  linalg::populateLinalgCanonicalizationPatterns(patterns);
+}
+
 void transform::ApplyTilingCanonicalizationPatternsOp::populatePatterns(
     RewritePatternSet &patterns) {
   linalg::populateLinalgTilingCanonicalizationPatterns(patterns);
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
index 8e14ef4a2ea12..2e3944819a737 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
@@ -846,33 +846,9 @@ class CanonicalizationPatternList<OpTy, OpTypes...> {
 };
 } // namespace
 
-RewritePatternSet
-mlir::linalg::getLinalgTilingCanonicalizationPatterns(MLIRContext *ctx) {
-  RewritePatternSet patterns(ctx);
-  populateLinalgTilingCanonicalizationPatterns(patterns);
-  return patterns;
-}
-
-void mlir::linalg::populateLinalgTilingCanonicalizationPatterns(
+void mlir::linalg::populateLinalgCanonicalizationPatterns(
     RewritePatternSet &patterns) {
   auto *ctx = patterns.getContext();
-  affine::AffineApplyOp::getCanonicalizationPatterns(patterns, ctx);
-  affine::AffineForOp::getCanonicalizationPatterns(patterns, ctx);
-  affine::AffineMinOp::getCanonicalizationPatterns(patterns, ctx);
-  affine::AffineMaxOp::getCanonicalizationPatterns(patterns, ctx);
-  arith::ConstantIndexOp::getCanonicalizationPatterns(patterns, ctx);
-
-  memref::SubViewOp::getCanonicalizationPatterns(patterns, ctx);
-  memref::ViewOp::getCanonicalizationPatterns(patterns, ctx);
-
-  scf::ForOp::getCanonicalizationPatterns(patterns, ctx);
-  scf::ParallelOp::getCanonicalizationPatterns(patterns, ctx);
-
-  tensor::CastOp::getCanonicalizationPatterns(patterns, ctx);
-  tensor::EmptyOp::getCanonicalizationPatterns(patterns, ctx);
-  tensor::ExtractSliceOp::getCanonicalizationPatterns(patterns, ctx);
-  tensor::InsertSliceOp::getCanonicalizationPatterns(patterns, ctx);
-  tensor::PadOp::getCanonicalizationPatterns(patterns, ctx);
   ctx->getLoadedDialect<LinalgDialect>()->getCanonicalizationPatterns(patterns);
 
   CanonicalizationPatternList<
@@ -880,3 +856,18 @@ void mlir::linalg::populateLinalgTilingCanonicalizationPatterns(
 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
       >::insert(patterns);
 }
+
+void mlir::linalg::populateLinalgTilingCanonicalizationPatterns(
+    RewritePatternSet &patterns) {
+  // Extra patterns from other dialects that we want to register for tiling
+  // Linalg operations.
+  CanonicalizationPatternList<
+      affine::AffineApplyOp, affine::AffineForOp, affine::AffineMinOp,
+      affine::AffineMaxOp, arith::ConstantIndexOp, memref::SubViewOp,
+      memref::ViewOp, scf::ForOp, scf::ParallelOp, tensor::CastOp,
+      tensor::EmptyOp, tensor::ExtractSliceOp, tensor::InsertSliceOp,
+      tensor::PadOp>::insert(patterns);
+
+  // Linalg's own patterns
+  populateLinalgCanonicalizationPatterns(patterns);
+}
diff --git a/mlir/test/lib/Dialect/Linalg/TestLinalgFusionTransforms.cpp b/mlir/test/lib/Dialect/Linalg/TestLinalgFusionTransforms.cpp
index aab7f30127d96..ddb278c9d0052 100644
--- a/mlir/test/lib/Dialect/Linalg/TestLinalgFusionTransforms.cpp
+++ b/mlir/test/lib/Dialect/Linalg/TestLinalgFusionTransforms.cpp
@@ -73,8 +73,8 @@ struct TestLinalgGreedyFusion
   }
   void runOnOperation() override {
     MLIRContext *context = &getContext();
-    RewritePatternSet patterns =
-        linalg::getLinalgTilingCanonicalizationPatterns(context);
+    RewritePatternSet patterns(context);
+    linalg::populateLinalgTilingCanonicalizationPatterns(patterns);
     patterns.add<ExtractSliceOfPadTensorSwapPattern>(context);
     scf::populateSCFForLoopCanonicalizationPatterns(patterns);
     FrozenRewritePatternSet frozenPatterns(std::move(patterns));

>From 68ead283bd43166e223379f1873e286ddf7fb34b Mon Sep 17 00:00:00 2001
From: Renato Golin <rengolin at systemcall.eu>
Date: Tue, 24 Feb 2026 15:28:45 +0000
Subject: [PATCH 2/2] remove new transform

---
 .../Dialect/Linalg/TransformOps/LinalgTransformOps.td  | 10 ----------
 .../mlir/Dialect/Linalg/Transforms/Transforms.h        |  3 ---
 .../Dialect/Linalg/TransformOps/LinalgTransformOps.cpp |  5 -----
 mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp          | 10 ++++++++--
 4 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
index 523a5fd28355b..70d424bae9285 100644
--- a/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/TransformOps/LinalgTransformOps.td
@@ -80,16 +80,6 @@ def ApplyFoldUnitExtentDimsViaSlicesPatternsOp : Op<Transform_Dialect,
   let assemblyFormat = "attr-dict";
 }
 
-def ApplyLinalgCanonicalizationPatternsOp : Op<Transform_Dialect,
-    "apply_patterns.linalg.canonicalization",
-    [DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
-  let description = [{
-    Collects linalg dialect and operation canonicalization patterns.
-  }];
-
-  let assemblyFormat = "attr-dict";
-}
-
 def ApplyTilingCanonicalizationPatternsOp : Op<Transform_Dialect,
     "apply_patterns.linalg.tiling_canonicalization",
     [DeclareOpInterfaceMethods<PatternDescriptorOpInterface>]> {
diff --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index 1829c378eb6da..deb84d556ae0a 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -1925,9 +1925,6 @@ struct ExtractSliceOfPadTensorSwapPattern
 // Populate functions.
 //===----------------------------------------------------------------------===//
 
-/// Canonicalization patterns for Linalg operations only.
-void populateLinalgCanonicalizationPatterns(RewritePatternSet &patterns);
-
 /// Canonicalization patterns relevant to apply after tiling patterns. These
 /// are applied automatically by the tiling pass but need to be applied
 /// manually when tiling is called programmatically.
diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
index e381ada9c9e22..78f1a61149a2b 100644
--- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
+++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
@@ -246,11 +246,6 @@ void transform::ApplyFoldUnitExtentDimsViaSlicesPatternsOp::populatePatterns(
   linalg::populateFoldUnitExtentDimsPatterns(patterns, options);
 }
 
-void transform::ApplyLinalgCanonicalizationPatternsOp::populatePatterns(
-    RewritePatternSet &patterns) {
-  linalg::populateLinalgCanonicalizationPatterns(patterns);
-}
-
 void transform::ApplyTilingCanonicalizationPatternsOp::populatePatterns(
     RewritePatternSet &patterns) {
   linalg::populateLinalgTilingCanonicalizationPatterns(patterns);
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
index 2e3944819a737..d00f76e4b676d 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
@@ -827,6 +827,9 @@ mlir::linalg::tileLinalgOp(RewriterBase &b, LinalgOp op,
 
 namespace {
 /// Helper classes for type list expansion.
+/// TODO: Move this to a common header, so all dialects, passes and
+/// transforms can utilize this method to compose canonicalization
+/// patterns.
 template <typename... OpTypes>
 class CanonicalizationPatternList;
 
@@ -844,9 +847,11 @@ class CanonicalizationPatternList<OpTy, OpTypes...> {
     CanonicalizationPatternList<OpTypes...>::insert(patterns);
   }
 };
-} // namespace
 
-void mlir::linalg::populateLinalgCanonicalizationPatterns(
+/// TODO: Move this into `getCanonicalizationPattern` and do the same for all
+/// dialects, so that we don't need this hack to also get the operations'
+/// canonicalization patterns per dialect.
+static void populateLinalgCanonicalizationPatterns(
     RewritePatternSet &patterns) {
   auto *ctx = patterns.getContext();
   ctx->getLoadedDialect<LinalgDialect>()->getCanonicalizationPatterns(patterns);
@@ -856,6 +861,7 @@ void mlir::linalg::populateLinalgCanonicalizationPatterns(
 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
       >::insert(patterns);
 }
+} // namespace
 
 void mlir::linalg::populateLinalgTilingCanonicalizationPatterns(
     RewritePatternSet &patterns) {



More information about the Mlir-commits mailing list