[Mlir-commits] [mlir] [mlir][PDL] PDLToPDLInterp: Use the pdl pattern name in the generated rewriter. (PR #149481)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Sep 2 00:50:18 PDT 2025


https://github.com/jumerckx updated https://github.com/llvm/llvm-project/pull/149481

>From 2462896361bab852fe8ebda0ebc6d78708c0a0c1 Mon Sep 17 00:00:00 2001
From: jumerckx <31353884+jumerckx at users.noreply.github.com>
Date: Fri, 18 Jul 2025 10:54:52 +0200
Subject: [PATCH 1/4] PDLToPDLInterp: Use the pdl pattern name in the generated
 rewriter.

---
 mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp b/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
index 7d20109b3db59..3a1c1fd2d57af 100644
--- a/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
+++ b/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
@@ -632,8 +632,14 @@ void PatternLowering::generate(SuccessNode *successNode, Block *&currentBlock) {
 SymbolRefAttr PatternLowering::generateRewriter(
     pdl::PatternOp pattern, SmallVectorImpl<Position *> &usedMatchValues) {
   builder.setInsertionPointToEnd(rewriterModule.getBody());
+  // Get the pattern name if available, otherwise use default
+  StringRef rewriterName = "pdl_generated_rewriter";
+  if (auto symName = pattern.getSymName()) {
+    rewriterName = symName.value();
+  }
+  
   auto rewriterFunc = builder.create<pdl_interp::FuncOp>(
-      pattern.getLoc(), "pdl_generated_rewriter",
+      pattern.getLoc(), rewriterName,
       builder.getFunctionType({}, {}));
   rewriterSymbolTable.insert(rewriterFunc);
 

>From 776dd7be43f32c60783ef54215a8c6c9f8150817 Mon Sep 17 00:00:00 2001
From: jumerckx <31353884+jumerckx at users.noreply.github.com>
Date: Tue, 2 Sep 2025 09:47:04 +0200
Subject: [PATCH 2/4] review

Co-authored-by: Mehdi Amini <joker-eph at gmail.com>
---
 mlir/build_information.md                     | 142 ++++++++++++++++++
 .../PDLToPDLInterp/PDLToPDLInterp.cpp         |   3 +-
 2 files changed, 143 insertions(+), 2 deletions(-)
 create mode 100644 mlir/build_information.md

diff --git a/mlir/build_information.md b/mlir/build_information.md
new file mode 100644
index 0000000000000..e5481957d8691
--- /dev/null
+++ b/mlir/build_information.md
@@ -0,0 +1,142 @@
+# MLIR Project Build Structure Overview
+
+This document provides an overview of the MLIR project's build structure, focusing on how different components are compiled and linked together, independent of CMake implementation details. The goal is to provide enough information for a developer to understand the dependencies and build process without relying on the CMake build scripts.
+
+MLIR (Multi-Level Intermediate Representation) is a flexible and extensible infrastructure for building reusable and composable compiler technologies. Its architecture is modular, allowing for independent development and compilation of various components.
+
+## Core Components
+
+The MLIR project is primarily composed of several core libraries that provide the fundamental infrastructure, and a set of tools that utilize these libraries.
+
+### 1. Core MLIR Libraries
+
+These libraries form the foundation of MLIR, providing the core IR, pass management, and utility functions. They are typically compiled into static or shared libraries that other components link against.
+
+*   **`lib/IR` (Intermediate Representation):**
+    *   **Purpose:** Defines the core MLIR IR, including operations, types, attributes, locations, and the module structure. This is the most fundamental part of MLIR.
+    *   **Compilation:** Source files (e.g., `lib/IR/*.cpp`) are compiled into object files.
+    *   **Linking:** These object files are then linked together to form a core MLIR IR library (e.g., `libMLIRIR.a` or `libMLIRIR.so`). Almost all other MLIR components depend on this library.
+    *   **Headers:** Public headers are located in `include/mlir/IR/`.
+
+*   **`lib/Dialect` (Dialect Definitions):**
+    *   **Purpose:** Contains the definitions for various built-in and standard dialects (e.g., `lib/Dialect/Standard`, `lib/Dialect/Affine`). Each dialect defines its own operations, types, and attributes.
+    *   **Compilation:** Source files for each dialect (e.g., `lib/Dialect/Standard/*.cpp`, `lib/Dialect/Affine/*.cpp`) are compiled into object files.
+    *   **Linking:** These object files are typically grouped into separate libraries per dialect (e.g., `libMLIRStandardDialect.a`, `libMLIRAffineDialect.a`). Tools and other components link against the specific dialects they need.
+    *   **Headers:** Public headers are in `include/mlir/Dialect/`.
+
+*   **`lib/Pass` (Pass Management):**
+    *   **Purpose:** Provides the infrastructure for defining, registering, and running optimization and transformation passes on the MLIR IR.
+    *   **Compilation:** Source files (e.g., `lib/Pass/*.cpp`) are compiled into object files.
+    *   **Linking:** These object files are linked to form a pass management library (e.g., `libMLIRPass.a`). Components that define or run passes depend on this.
+    *   **Headers:** Public headers are in `include/mlir/Pass/`.
+
+*   **`lib/Transforms` (Common Transformations):**
+    *   **Purpose:** Contains common, reusable transformation passes that operate on the MLIR IR, often across different dialects.
+    *   **Compilation:** Source files (e.g., `lib/Transforms/*.cpp`) are compiled into object files.
+    *   **Linking:** These object files are linked into a transformations library (e.g., `libMLIRTransforms.a`). Tools and other passes might link against this.
+    *   **Headers:** Public headers are in `include/mlir/Transforms/`.
+
+*   **`lib/Support` (Utility and Support Functions):**
+    *   **Purpose:** Provides various utility functions, data structures, and common infrastructure used throughout MLIR (e.g., command-line parsing, error handling).
+    *   **Compilation:** Source files (e.g., `lib/Support/*.cpp`) are compiled into object files.
+    *   **Linking:** These object files are linked into a support library (e.g., `libMLIRSupport.a`). Many other MLIR libraries depend on this.
+    *   **Headers:** Public headers are in `include/mlir/Support/`.
+
+### 2. Tools
+
+MLIR provides several command-line tools built on top of the core libraries. These tools demonstrate MLIR's capabilities and are useful for development, testing, and analysis.
+
+*   **`mlir-opt` (MLIR Optimizer):**
+    *   **Purpose:** A multi-purpose tool for parsing, optimizing, and transforming MLIR code. It can apply various passes and print the IR in different forms.
+    *   **Source Location:** `tools/mlir/mlir-opt/`
+    *   **Compilation:** The `mlir-opt.cpp` source file is compiled into an object file.
+    *   **Linking:** This object file is linked against:
+        *   Core MLIR libraries (`libMLIRIR`, `libMLIRPass`, `libMLIRSupport`, etc.).
+        *   Libraries for all dialects it supports (e.g., `libMLIRStandardDialect`, `libMLIRAffineDialect`, etc.).
+        *   Libraries for common transformations (`libMLIRTransforms`).
+        *   Potentially other utility libraries from LLVM.
+    *   **Executable:** The final linked executable is `bin/mlir-opt`.
+
+*   **`mlir-translate` (MLIR Translator):**
+    *   **Purpose:** A tool for converting MLIR code to and from other formats (e.g., LLVM IR, SPIR-V).
+    *   **Source Location:** `tools/mlir/mlir-translate/`
+    *   **Compilation:** The `mlir-translate.cpp` source file is compiled into an object file.
+    *   **Linking:** This object file is linked against:
+        *   Core MLIR libraries.
+        *   Specific dialect libraries relevant to the translations it performs.
+        *   Libraries for the target formats (e.g., LLVM libraries for LLVM IR translation).
+    *   **Executable:** The final linked executable is `bin/mlir-translate`.
+
+*   **Other Tools:**
+    *   Many other tools exist in `tools/mlir/` (e.g., `mlir-tblgen`, `mlir-lsp-server`). Each of these follows a similar pattern: a main source file is compiled and linked against the necessary core MLIR libraries, specific dialect libraries, and any other specialized libraries they require.
+
+### 3. Dependencies and Linking
+
+The build process generally follows a hierarchical dependency model:
+
+1.  **LLVM Core:** MLIR builds on top of LLVM's infrastructure. Many MLIR components depend on core LLVM libraries (e.g., `libLLVMSupport`, `libLLVMCore`). These are typically built first.
+2.  **MLIR Support and IR:** `lib/Support` and `lib/IR` are foundational MLIR libraries. `lib/IR` often depends on `lib/Support`.
+3.  **Pass Management and Transforms:** `lib/Pass` and `lib/Transforms` depend on `lib/IR` and `lib/Support`.
+4.  **Dialects:** Individual dialects in `lib/Dialect` depend on `lib/IR` and `lib/Support`. They are often independent of each other, allowing for modular compilation.
+5.  **Tools:** Tools like `mlir-opt` and `mlir-translate` are the top-level executables. They link against all the MLIR core libraries, the specific dialect libraries they need to support, and relevant LLVM libraries.
+
+### General Build Steps (Conceptual)
+
+To build MLIR components without CMake, one would conceptually follow these steps:
+
+1.  **Compile LLVM Libraries:** Compile the necessary LLVM core libraries (e.g., `libLLVMSupport.a`, `libLLVMCore.a`) from their respective source files.
+2.  **Compile MLIR Core Libraries:**
+    *   Compile all `.cpp` files in `lib/Support` into object files, then link them into `libMLIRSupport.a`.
+    *   Compile all `.cpp` files in `lib/IR` into object files. Link these with `libMLIRSupport.a` to create `libMLIRIR.a`.
+    *   Repeat for `lib/Pass`, `lib/Transforms`, etc., linking against previously built MLIR and LLVM libraries as needed.
+3.  **Compile Dialect Libraries:** For each dialect (e.g., Standard, Affine):
+    *   Compile its `.cpp` files (e.g., `lib/Dialect/Standard/*.cpp`) into object files.
+    *   Link these object files with `libMLIRIR.a`, `libMLIRSupport.a`, and any other required core MLIR/LLVM libraries to create `libMLIR<DialectName>Dialect.a`.
+4.  **Compile Tools:** For each tool (e.g., `mlir-opt`):
+    *   Compile its main `.cpp` file (e.g., `tools/mlir/mlir-opt/mlir-opt.cpp`) into an object file.
+    *   Link this object file with all the necessary MLIR core libraries (e.g., `libMLIRIR.a`, `libMLIRPass.a`, `libMLIRSupport.a`), all the dialect libraries it needs to support (e.g., `libMLIRStandardDialect.a`, `libMLIRAffineDialect.a`), and any required LLVM libraries. This will produce the final executable (e.g., `bin/mlir-opt`).
+
+This modular structure allows for efficient development and compilation, as changes in one dialect or pass often only require recompilation of that specific component and relinking of tools that depend on it.
+
+## Building MLIR Core (without specific dialects)
+
+To build the absolute core of MLIR, which provides the fundamental IR infrastructure without any particular dialects (beyond the intrinsic `BuiltinDialect` that is part of the core IR definition), the following components are required:
+
+1.  **LLVM Core Libraries:**
+    *   **Purpose:** MLIR leverages LLVM's foundational utilities (e.g., `llvm::StringRef`, `llvm::ArrayRef`, `llvm::DenseMap`).
+    *   **Key Libraries:** At a minimum, `libLLVMSupport.a` (or `.so`) and potentially `libLLVMCore.a` depending on the specific LLVM features used by MLIR's core.
+    *   **Build:** These would need to be compiled from their respective LLVM source files.
+
+2.  **MLIR Support Library (`libMLIRSupport.a`):**
+    *   **Purpose:** Provides MLIR-specific utility functions, data structures, and common infrastructure (e.g., command-line parsing utilities, error handling).
+    *   **Source Files:** All `.cpp` files within `lib/Support/`.
+    *   **Include Paths:** Requires access to `include/mlir/Support/` and LLVM's public include directories.
+    *   **Dependencies:** Links against `libLLVMSupport.a` and other necessary LLVM core libraries.
+
+3.  **MLIR IR Library (`libMLIRIR.a`):**
+    *   **Purpose:** Defines the fundamental MLIR Intermediate Representation, including `MLIRContext`, `Operation`, `Type`, `Attribute`, `Location`, `Dialect` (the base class), `ModuleOp`, and the core mechanisms for pattern matching and verification. The `BuiltinDialect` is an intrinsic part of the core IR and is included here.
+    *   **Source Files:** All `.cpp` files within `lib/IR/`.
+    *   **Include Paths:** Requires access to `include/mlir/IR/`, `include/mlir/Support/`, and LLVM's public include directories.
+    *   **Dependencies:** Links against `libMLIRSupport.a`, `libLLVMSupport.a`, and `libLLVMCore.a` (if needed).
+
+**Conceptual Build Steps for MLIR Core:**
+
+Assuming a C++ compiler (like Clang or GCC) and a linker:
+
+1.  **Compile LLVM Support and Core Libraries:**
+    *   Compile all relevant `.cpp` files from the LLVM project (e.g., `llvm/lib/Support/*.cpp`, `llvm/lib/Core/*.cpp`) into object files (`.o`).
+    *   Link these object files to create `libLLVMSupport.a` and `libLLVMCore.a` (or their shared library equivalents).
+
+2.  **Compile MLIR Support Library:**
+    *   Compile all `.cpp` files in `mlir/lib/Support/` into object files.
+    *   **Include Paths:** Use compiler flags like `-I<path_to_mlir_include>` (e.g., `/Users/jumerckx/llvm-project/mlir/include`) and `-I<path_to_llvm_include>`.
+    *   Link these object files to create `libMLIRSupport.a`.
+    *   **Dependencies:** Link against `libLLVMSupport.a`.
+
+3.  **Compile MLIR IR Library:**
+    *   Compile all `.cpp` files in `mlir/lib/IR/` into object files.
+    *   **Include Paths:** Use compiler flags like `-I<path_to_mlir_include>` and `-I<path_to_llvm_include>`.
+    *   Link these object files to create `libMLIRIR.a`.
+    *   **Dependencies:** Link against `libMLIRSupport.a`, `libLLVMSupport.a`, and `libLLVMCore.a` (if needed).
+
+This sequence ensures that dependencies are met: LLVM libraries are built first, then MLIR's `Support` library (which depends on LLVM), and finally MLIR's `IR` library (which depends on MLIR `Support` and LLVM).
diff --git a/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp b/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
index fd2c02f022b9d..4e4313900769b 100644
--- a/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
+++ b/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
@@ -641,9 +641,8 @@ SymbolRefAttr PatternLowering::generateRewriter(
   builder.setInsertionPointToEnd(rewriterModule.getBody());
   // Get the pattern name if available, otherwise use default
   StringRef rewriterName = "pdl_generated_rewriter";
-  if (auto symName = pattern.getSymName()) {
+  if (auto symName = pattern.getSymName())
     rewriterName = symName.value();
-  }
   auto rewriterFunc = pdl_interp::FuncOp::create(
       builder, pattern.getLoc(), rewriterName,
       builder.getFunctionType({}, {}));

>From 5205cc1a63ec587526da9dc049ebd3fd9a8da13a Mon Sep 17 00:00:00 2001
From: jumerckx <31353884+jumerckx at users.noreply.github.com>
Date: Tue, 2 Sep 2025 09:47:13 +0200
Subject: [PATCH 3/4] lit test

---
 .../pdl-to-pdl-interp-rewriter.mlir           | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/mlir/test/Conversion/PDLToPDLInterp/pdl-to-pdl-interp-rewriter.mlir b/mlir/test/Conversion/PDLToPDLInterp/pdl-to-pdl-interp-rewriter.mlir
index e5a84d69dcad9..cf0cefd3280a8 100644
--- a/mlir/test/Conversion/PDLToPDLInterp/pdl-to-pdl-interp-rewriter.mlir
+++ b/mlir/test/Conversion/PDLToPDLInterp/pdl-to-pdl-interp-rewriter.mlir
@@ -260,3 +260,30 @@ module @range_op {
     }
   }
 }
+
+// -----
+
+// CHECK-LABEL: module @named_pattern
+module @named_pattern {
+  // CHECK: pdl_interp.func @matcher(%[[ARG0:.*]]: !pdl.operation) {
+  // CHECK:   pdl_interp.check_operation_name of %[[ARG0]] is "foo.op" -> ^bb2, ^bb1
+  // CHECK: ^bb1:
+  // CHECK:   pdl_interp.finalize
+  // CHECK: ^bb2:
+  // CHECK:   pdl_interp.check_operand_count of %[[ARG0]] is 0 -> ^bb3, ^bb1
+  // CHECK: ^bb3:
+  // CHECK:   pdl_interp.check_result_count of %[[ARG0]] is 0 -> ^bb4, ^bb1
+  // CHECK: ^bb4:
+  // CHECK:   pdl_interp.record_match @rewriters::@my_pattern(%[[ARG0]] : !pdl.operation) : benefit(1), loc([%[[ARG0]]]), root("foo.op") -> ^bb1
+  // CHECK: }
+  // CHECK: module @rewriters {
+  // CHECK:   pdl_interp.func @my_pattern(%[[ARG0:.*]]: !pdl.operation) {
+  // CHECK:     pdl_interp.apply_rewrite "rewriter"(%[[ARG0]] : !pdl.operation)
+  // CHECK:     pdl_interp.finalize
+  // CHECK:   }
+  // CHECK: }
+  pdl.pattern @my_pattern : benefit(1) {
+    %root = operation "foo.op"
+    rewrite %root with "rewriter"
+  }
+}

>From 7f222aa9140970b4b42cb73b8e57c461e7eb0f52 Mon Sep 17 00:00:00 2001
From: jumerckx <31353884+jumerckx at users.noreply.github.com>
Date: Tue, 2 Sep 2025 09:50:05 +0200
Subject: [PATCH 4/4] clang-format

---
 mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp b/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
index 4e4313900769b..c06824ce837dd 100644
--- a/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
+++ b/mlir/lib/Conversion/PDLToPDLInterp/PDLToPDLInterp.cpp
@@ -644,8 +644,7 @@ SymbolRefAttr PatternLowering::generateRewriter(
   if (auto symName = pattern.getSymName())
     rewriterName = symName.value();
   auto rewriterFunc = pdl_interp::FuncOp::create(
-      builder, pattern.getLoc(), rewriterName,
-      builder.getFunctionType({}, {}));
+      builder, pattern.getLoc(), rewriterName, builder.getFunctionType({}, {}));
   rewriterSymbolTable.insert(rewriterFunc);
 
   // Generate the rewriter function body.



More information about the Mlir-commits mailing list