From e0f3b63a761b82d21c3dd09f6804f2644966a5da Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Sun, 27 Apr 2025 23:13:41 -0700 Subject: [PATCH 01/11] Add an MLIR "pattern catalog" generator. This PR adds a new cmake build option MLIR_ENABLE_CATALOG_GENERATOR. When enabled, it attaches a listener to all RewritePatterns that emits the name of the operation being modified to a special file. When the MLIR test suite is run, these files can be combined into an index linking operations to the patterns that insert, modify, or replace them. This index is intended to be used to create a website that allows one to look up patterns from an operation name. --- mlir/CMakeLists.txt | 19 +++++ mlir/cmake/modules/MLIRConfig.cmake.in | 1 + mlir/include/mlir/IR/PatternMatch.h | 74 +++++++++++++++++++ mlir/lib/Rewrite/PatternApplicator.cpp | 49 +++++++++++- .../mlir/test/BUILD.bazel | 1 + 5 files changed, 142 insertions(+), 2 deletions(-) diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt index 44493b75b8a8c..bd30d94e1ccb4 100644 --- a/mlir/CMakeLists.txt +++ b/mlir/CMakeLists.txt @@ -202,6 +202,24 @@ if(MLIR_ENABLE_BINDINGS_PYTHON) mlir_configure_python_dev_packages() endif() +#------------------------------------------------------------------------------- +# MLIR Pattern Catalog Generator Configuration +# Requires: +# RTTI to be enabled (set with -DLLVM_ENABLE_RTTI=ON) +# When enabled, causes all rewriter patterns to dump their type names and the +# names of affected operations, which can be used to build a search index +# mapping operations to patterns. +#------------------------------------------------------------------------------- + +set(MLIR_ENABLE_CATALOG_GENERATOR 0 CACHE BOOL + "Enables construction of a catalog of rewrite patterns.") + +if (MLIR_ENABLE_CATALOG_GENERATOR) + message(STATUS "Enabling MLIR pattern catalog generator") + add_definitions(-DMLIR_ENABLE_CATALOG_GENERATOR) + add_definitions(-DLLVM_ENABLE_RTTI) +endif() + set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(BEFORE @@ -322,3 +340,4 @@ endif() if(MLIR_STANDALONE_BUILD) llvm_distribution_add_targets() endif() + diff --git a/mlir/cmake/modules/MLIRConfig.cmake.in b/mlir/cmake/modules/MLIRConfig.cmake.in index 71f3e028b1e88..f4ae70a22b3d2 100644 --- a/mlir/cmake/modules/MLIRConfig.cmake.in +++ b/mlir/cmake/modules/MLIRConfig.cmake.in @@ -16,6 +16,7 @@ set(MLIR_IRDL_TO_CPP_EXE "@MLIR_CONFIG_IRDL_TO_CPP_EXE@") set(MLIR_INSTALL_AGGREGATE_OBJECTS "@MLIR_INSTALL_AGGREGATE_OBJECTS@") set(MLIR_ENABLE_BINDINGS_PYTHON "@MLIR_ENABLE_BINDINGS_PYTHON@") set(MLIR_ENABLE_EXECUTION_ENGINE "@MLIR_ENABLE_EXECUTION_ENGINE@") +set(MLIR_ENABLE_CATALOG_GENERATOR "@MLIR_ENABLE_CATALOG_GENERATOR@") set_property(GLOBAL PROPERTY MLIR_ALL_LIBS "@MLIR_ALL_LIBS@") set_property(GLOBAL PROPERTY MLIR_DIALECT_LIBS "@MLIR_DIALECT_LIBS@") diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index 10cfe851765dc..141b3c6806ed8 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -475,6 +475,80 @@ class RewriterBase : public OpBuilder { RewriterBase::Listener *rewriteListener; }; + struct CatalogingListener : public RewriterBase::ForwardingListener { + CatalogingListener(OpBuilder::Listener *listener, + const std::string &patternName, raw_ostream &os, + std::mutex &writeMutex) + : RewriterBase::ForwardingListener(listener), patternName(patternName), + os(os), writeMutex(writeMutex) {} + + void notifyOperationInserted(Operation *op, InsertPoint previous) override { + { + std::lock_guard lock(writeMutex); + os << patternName << " | notifyOperationInserted" + << " | " << op->getName() << "\n"; + os.flush(); + } + ForwardingListener::notifyOperationInserted(op, previous); + } + + void notifyOperationModified(Operation *op) override { + { + std::lock_guard lock(writeMutex); + os << patternName << " | notifyOperationModified" + << " | " << op->getName() << "\n"; + os.flush(); + } + ForwardingListener::notifyOperationModified(op); + } + + void notifyOperationReplaced(Operation *op, Operation *newOp) override { + { + std::lock_guard lock(writeMutex); + os << patternName << " | notifyOperationReplaced (with op)" + << " | " << op->getName() << " | " << newOp->getName() << "\n"; + os.flush(); + } + ForwardingListener::notifyOperationReplaced(op, newOp); + } + + void notifyOperationReplaced(Operation *op, + ValueRange replacement) override { + { + std::lock_guard lock(writeMutex); + os << patternName << " | notifyOperationReplaced (with values)" + << " | " << op->getName() << "\n"; + os.flush(); + } + ForwardingListener::notifyOperationReplaced(op, replacement); + } + + void notifyOperationErased(Operation *op) override { + { + std::lock_guard lock(writeMutex); + os << patternName << " | notifyOperationErased" + << " | " << op->getName() << "\n"; + os.flush(); + } + ForwardingListener::notifyOperationErased(op); + } + + void notifyPatternBegin(const Pattern &pattern, Operation *op) override { + { + std::lock_guard lock(writeMutex); + os << patternName << " | notifyPatternBegin" + << " | " << op->getName() << "\n"; + os.flush(); + } + ForwardingListener::notifyPatternBegin(pattern, op); + } + + private: + const std::string &patternName; + raw_ostream &os; + std::mutex &writeMutex; + }; + /// Move the blocks that belong to "region" before the given position in /// another region "parent". The two regions must be different. The caller /// is responsible for creating or updating the operation transferring flow diff --git a/mlir/lib/Rewrite/PatternApplicator.cpp b/mlir/lib/Rewrite/PatternApplicator.cpp index 4a12183492fd4..c66aaf267881f 100644 --- a/mlir/lib/Rewrite/PatternApplicator.cpp +++ b/mlir/lib/Rewrite/PatternApplicator.cpp @@ -15,8 +15,19 @@ #include "ByteCode.h" #include "llvm/Support/Debug.h" +#ifdef MLIR_ENABLE_CATALOG_GENERATOR +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +#endif + #define DEBUG_TYPE "pattern-application" +#ifdef MLIR_ENABLE_CATALOG_GENERATOR +static std::mutex catalogWriteMutex; +#endif + using namespace mlir; using namespace mlir::detail; @@ -152,6 +163,16 @@ LogicalResult PatternApplicator::matchAndRewrite( unsigned anyIt = 0, anyE = anyOpPatterns.size(); unsigned pdlIt = 0, pdlE = pdlMatches.size(); LogicalResult result = failure(); +#ifdef MLIR_ENABLE_CATALOG_GENERATOR + std::error_code ec; + llvm::raw_fd_ostream catalogOs("pattern_catalog.txt", ec, + llvm::sys::fs::OF_Append); + if (ec) { + op->emitError("Failed to open pattern catalog file: " + ec.message()); + return failure(); + } +#endif + do { // Find the next pattern with the highest benefit. const Pattern *bestPattern = nullptr; @@ -206,14 +227,38 @@ LogicalResult PatternApplicator::matchAndRewrite( } else { LLVM_DEBUG(llvm::dbgs() << "Trying to match \"" << bestPattern->getDebugName() << "\"\n"); - const auto *pattern = static_cast(bestPattern); - result = pattern->matchAndRewrite(op, rewriter); +#ifdef MLIR_ENABLE_CATALOG_GENERATOR + OpBuilder::Listener *oldListener = rewriter.getListener(); + int status; + const char *mangledPatternName = typeid(*pattern).name(); + char *demangled = abi::__cxa_demangle(mangledPatternName, nullptr, + nullptr, &status); + std::string demangledPatternName; + if (status == 0 && demangled) { + demangledPatternName = demangled; + free(demangled); + } else { + // Fallback in case demangling fails. + demangledPatternName = mangledPatternName; + } + + RewriterBase::CatalogingListener *catalogingListener = + new RewriterBase::CatalogingListener( + oldListener, demangledPatternName, catalogOs, + catalogWriteMutex); + rewriter.setListener(catalogingListener); +#endif + result = pattern->matchAndRewrite(op, rewriter); LLVM_DEBUG(llvm::dbgs() << "\"" << bestPattern->getDebugName() << "\" result " << succeeded(result) << "\n"); +#ifdef MLIR_ENABLE_CATALOG_GENERATOR + rewriter.setListener(oldListener); + delete catalogingListener; +#endif } // Process the result of the pattern application. diff --git a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel index 23d89f41a3a45..281b2566304b0 100644 --- a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel @@ -44,6 +44,7 @@ expand_template( "@MLIR_ENABLE_SPIRV_CPU_RUNNER@": "0", "@MLIR_ENABLE_VULKAN_RUNNER@": "0", "@MLIR_ENABLE_BINDINGS_PYTHON@": "0", + "@MLIR_ENABLE_CATALOG_GENERATOR@": "0", "@MLIR_RUN_AMX_TESTS@": "0", "@MLIR_RUN_ARM_SVE_TESTS@": "0", "@MLIR_RUN_ARM_SME_TESTS@": "0", From a431eb5283dc62d20b44bd3114c489ac1405126e Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Sat, 28 Jun 2025 19:11:30 -0700 Subject: [PATCH 02/11] remove use of RTTI --- mlir/CMakeLists.txt | 4 +--- mlir/include/mlir/IR/PatternMatch.h | 7 +++---- mlir/lib/Rewrite/PatternApplicator.cpp | 16 +--------------- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt index bd30d94e1ccb4..62e94777b3d1f 100644 --- a/mlir/CMakeLists.txt +++ b/mlir/CMakeLists.txt @@ -204,8 +204,7 @@ endif() #------------------------------------------------------------------------------- # MLIR Pattern Catalog Generator Configuration -# Requires: -# RTTI to be enabled (set with -DLLVM_ENABLE_RTTI=ON) +# # When enabled, causes all rewriter patterns to dump their type names and the # names of affected operations, which can be used to build a search index # mapping operations to patterns. @@ -217,7 +216,6 @@ set(MLIR_ENABLE_CATALOG_GENERATOR 0 CACHE BOOL if (MLIR_ENABLE_CATALOG_GENERATOR) message(STATUS "Enabling MLIR pattern catalog generator") add_definitions(-DMLIR_ENABLE_CATALOG_GENERATOR) - add_definitions(-DLLVM_ENABLE_RTTI) endif() set(CMAKE_INCLUDE_CURRENT_DIR ON) diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index 141b3c6806ed8..d4ead9bbb9a38 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -476,9 +476,8 @@ class RewriterBase : public OpBuilder { }; struct CatalogingListener : public RewriterBase::ForwardingListener { - CatalogingListener(OpBuilder::Listener *listener, - const std::string &patternName, raw_ostream &os, - std::mutex &writeMutex) + CatalogingListener(OpBuilder::Listener *listener, StringRef patternName, + raw_ostream &os, std::mutex &writeMutex) : RewriterBase::ForwardingListener(listener), patternName(patternName), os(os), writeMutex(writeMutex) {} @@ -544,7 +543,7 @@ class RewriterBase : public OpBuilder { } private: - const std::string &patternName; + StringRef patternName; raw_ostream &os; std::mutex &writeMutex; }; diff --git a/mlir/lib/Rewrite/PatternApplicator.cpp b/mlir/lib/Rewrite/PatternApplicator.cpp index c66aaf267881f..86263d12b6545 100644 --- a/mlir/lib/Rewrite/PatternApplicator.cpp +++ b/mlir/lib/Rewrite/PatternApplicator.cpp @@ -18,7 +18,6 @@ #ifdef MLIR_ENABLE_CATALOG_GENERATOR #include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" -#include #include #endif @@ -232,22 +231,9 @@ LogicalResult PatternApplicator::matchAndRewrite( #ifdef MLIR_ENABLE_CATALOG_GENERATOR OpBuilder::Listener *oldListener = rewriter.getListener(); - int status; - const char *mangledPatternName = typeid(*pattern).name(); - char *demangled = abi::__cxa_demangle(mangledPatternName, nullptr, - nullptr, &status); - std::string demangledPatternName; - if (status == 0 && demangled) { - demangledPatternName = demangled; - free(demangled); - } else { - // Fallback in case demangling fails. - demangledPatternName = mangledPatternName; - } - RewriterBase::CatalogingListener *catalogingListener = new RewriterBase::CatalogingListener( - oldListener, demangledPatternName, catalogOs, + oldListener, pattern->getDebugName(), catalogOs, catalogWriteMutex); rewriter.setListener(catalogingListener); #endif From 18adc2410bc51c650cc71d08ebbca8cdd2686ef8 Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Sun, 29 Jun 2025 20:31:34 -0700 Subject: [PATCH 03/11] remove mutex/file writes in favor of toolsubst+llvm::dbgs --- mlir/CMakeLists.txt | 17 ----- mlir/cmake/modules/MLIRConfig.cmake.in | 1 - mlir/include/mlir/IR/PatternMatch.h | 72 +++---------------- mlir/lib/IR/CMakeLists.txt | 1 + mlir/lib/IR/CatalogingListener.cpp | 49 +++++++++++++ mlir/lib/Rewrite/PatternApplicator.cpp | 29 ++------ mlir/test/lit.cfg.py | 13 ++++ .../mlir/test/BUILD.bazel | 1 - 8 files changed, 75 insertions(+), 108 deletions(-) create mode 100644 mlir/lib/IR/CatalogingListener.cpp diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt index 62e94777b3d1f..44493b75b8a8c 100644 --- a/mlir/CMakeLists.txt +++ b/mlir/CMakeLists.txt @@ -202,22 +202,6 @@ if(MLIR_ENABLE_BINDINGS_PYTHON) mlir_configure_python_dev_packages() endif() -#------------------------------------------------------------------------------- -# MLIR Pattern Catalog Generator Configuration -# -# When enabled, causes all rewriter patterns to dump their type names and the -# names of affected operations, which can be used to build a search index -# mapping operations to patterns. -#------------------------------------------------------------------------------- - -set(MLIR_ENABLE_CATALOG_GENERATOR 0 CACHE BOOL - "Enables construction of a catalog of rewrite patterns.") - -if (MLIR_ENABLE_CATALOG_GENERATOR) - message(STATUS "Enabling MLIR pattern catalog generator") - add_definitions(-DMLIR_ENABLE_CATALOG_GENERATOR) -endif() - set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(BEFORE @@ -338,4 +322,3 @@ endif() if(MLIR_STANDALONE_BUILD) llvm_distribution_add_targets() endif() - diff --git a/mlir/cmake/modules/MLIRConfig.cmake.in b/mlir/cmake/modules/MLIRConfig.cmake.in index f4ae70a22b3d2..71f3e028b1e88 100644 --- a/mlir/cmake/modules/MLIRConfig.cmake.in +++ b/mlir/cmake/modules/MLIRConfig.cmake.in @@ -16,7 +16,6 @@ set(MLIR_IRDL_TO_CPP_EXE "@MLIR_CONFIG_IRDL_TO_CPP_EXE@") set(MLIR_INSTALL_AGGREGATE_OBJECTS "@MLIR_INSTALL_AGGREGATE_OBJECTS@") set(MLIR_ENABLE_BINDINGS_PYTHON "@MLIR_ENABLE_BINDINGS_PYTHON@") set(MLIR_ENABLE_EXECUTION_ENGINE "@MLIR_ENABLE_EXECUTION_ENGINE@") -set(MLIR_ENABLE_CATALOG_GENERATOR "@MLIR_ENABLE_CATALOG_GENERATOR@") set_property(GLOBAL PROPERTY MLIR_ALL_LIBS "@MLIR_ALL_LIBS@") set_property(GLOBAL PROPERTY MLIR_DIALECT_LIBS "@MLIR_DIALECT_LIBS@") diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index d4ead9bbb9a38..63563fb53cd81 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -476,76 +476,20 @@ class RewriterBase : public OpBuilder { }; struct CatalogingListener : public RewriterBase::ForwardingListener { - CatalogingListener(OpBuilder::Listener *listener, StringRef patternName, - raw_ostream &os, std::mutex &writeMutex) - : RewriterBase::ForwardingListener(listener), patternName(patternName), - os(os), writeMutex(writeMutex) {} - - void notifyOperationInserted(Operation *op, InsertPoint previous) override { - { - std::lock_guard lock(writeMutex); - os << patternName << " | notifyOperationInserted" - << " | " << op->getName() << "\n"; - os.flush(); - } - ForwardingListener::notifyOperationInserted(op, previous); - } - - void notifyOperationModified(Operation *op) override { - { - std::lock_guard lock(writeMutex); - os << patternName << " | notifyOperationModified" - << " | " << op->getName() << "\n"; - os.flush(); - } - ForwardingListener::notifyOperationModified(op); - } - - void notifyOperationReplaced(Operation *op, Operation *newOp) override { - { - std::lock_guard lock(writeMutex); - os << patternName << " | notifyOperationReplaced (with op)" - << " | " << op->getName() << " | " << newOp->getName() << "\n"; - os.flush(); - } - ForwardingListener::notifyOperationReplaced(op, newOp); + CatalogingListener(OpBuilder::Listener *listener, StringRef patternName) + : RewriterBase::ForwardingListener(listener), patternName(patternName) { } + void notifyOperationInserted(Operation *op, InsertPoint previous) override; + void notifyOperationModified(Operation *op) override; + void notifyOperationReplaced(Operation *op, Operation *newOp) override; void notifyOperationReplaced(Operation *op, - ValueRange replacement) override { - { - std::lock_guard lock(writeMutex); - os << patternName << " | notifyOperationReplaced (with values)" - << " | " << op->getName() << "\n"; - os.flush(); - } - ForwardingListener::notifyOperationReplaced(op, replacement); - } - - void notifyOperationErased(Operation *op) override { - { - std::lock_guard lock(writeMutex); - os << patternName << " | notifyOperationErased" - << " | " << op->getName() << "\n"; - os.flush(); - } - ForwardingListener::notifyOperationErased(op); - } - - void notifyPatternBegin(const Pattern &pattern, Operation *op) override { - { - std::lock_guard lock(writeMutex); - os << patternName << " | notifyPatternBegin" - << " | " << op->getName() << "\n"; - os.flush(); - } - ForwardingListener::notifyPatternBegin(pattern, op); - } + ValueRange replacement) override; + void notifyOperationErased(Operation *op) override; + void notifyPatternBegin(const Pattern &pattern, Operation *op) override; private: StringRef patternName; - raw_ostream &os; - std::mutex &writeMutex; }; /// Move the blocks that belong to "region" before the given position in diff --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt index 4cabac185171c..c6900d4fcae3a 100644 --- a/mlir/lib/IR/CMakeLists.txt +++ b/mlir/lib/IR/CMakeLists.txt @@ -18,6 +18,7 @@ add_mlir_library(MLIRIR BuiltinDialectBytecode.cpp BuiltinTypes.cpp BuiltinTypeInterfaces.cpp + CatalogingListener.cpp Diagnostics.cpp Dialect.cpp DialectResourceBlobManager.cpp diff --git a/mlir/lib/IR/CatalogingListener.cpp b/mlir/lib/IR/CatalogingListener.cpp new file mode 100644 index 0000000000000..156530d19431b --- /dev/null +++ b/mlir/lib/IR/CatalogingListener.cpp @@ -0,0 +1,49 @@ +#include "mlir/IR/PatternMatch.h" +#include "llvm/Support/Debug.h" + +#define DEBUG_TYPE "generate-pattern-catalog" + +using namespace mlir; + +void RewriterBase::CatalogingListener::notifyOperationInserted( + Operation *op, InsertPoint previous) { + LLVM_DEBUG(llvm::dbgs() << patternName << " | notifyOperationInserted" + << " | " << op->getName() << "\n"); + ForwardingListener::notifyOperationInserted(op, previous); +} + +void RewriterBase::CatalogingListener::notifyOperationModified(Operation *op) { + LLVM_DEBUG(llvm::dbgs() << patternName << " | notifyOperationModified" + << " | " << op->getName() << "\n"); + ForwardingListener::notifyOperationModified(op); +} + +void RewriterBase::CatalogingListener::notifyOperationReplaced( + Operation *op, Operation *newOp) { + LLVM_DEBUG(llvm::dbgs() << patternName + << " | notifyOperationReplaced (with op)" + << " | " << op->getName() << " | " << newOp->getName() + << "\n"); + ForwardingListener::notifyOperationReplaced(op, newOp); +} + +void RewriterBase::CatalogingListener::notifyOperationReplaced( + Operation *op, ValueRange replacement) { + LLVM_DEBUG(llvm::dbgs() << patternName + << " | notifyOperationReplaced (with values)" + << " | " << op->getName() << "\n"); + ForwardingListener::notifyOperationReplaced(op, replacement); +} + +void RewriterBase::CatalogingListener::notifyOperationErased(Operation *op) { + LLVM_DEBUG(llvm::dbgs() << patternName << " | notifyOperationErased" + << " | " << op->getName() << "\n"); + ForwardingListener::notifyOperationErased(op); +} + +void RewriterBase::CatalogingListener::notifyPatternBegin( + const Pattern &pattern, Operation *op) { + LLVM_DEBUG(llvm::dbgs() << patternName << " | notifyPatternBegin" + << " | " << op->getName() << "\n"); + ForwardingListener::notifyPatternBegin(pattern, op); +} diff --git a/mlir/lib/Rewrite/PatternApplicator.cpp b/mlir/lib/Rewrite/PatternApplicator.cpp index 86263d12b6545..47a5006767b35 100644 --- a/mlir/lib/Rewrite/PatternApplicator.cpp +++ b/mlir/lib/Rewrite/PatternApplicator.cpp @@ -15,18 +15,8 @@ #include "ByteCode.h" #include "llvm/Support/Debug.h" -#ifdef MLIR_ENABLE_CATALOG_GENERATOR -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/raw_ostream.h" -#include -#endif - #define DEBUG_TYPE "pattern-application" -#ifdef MLIR_ENABLE_CATALOG_GENERATOR -static std::mutex catalogWriteMutex; -#endif - using namespace mlir; using namespace mlir::detail; @@ -162,16 +152,6 @@ LogicalResult PatternApplicator::matchAndRewrite( unsigned anyIt = 0, anyE = anyOpPatterns.size(); unsigned pdlIt = 0, pdlE = pdlMatches.size(); LogicalResult result = failure(); -#ifdef MLIR_ENABLE_CATALOG_GENERATOR - std::error_code ec; - llvm::raw_fd_ostream catalogOs("pattern_catalog.txt", ec, - llvm::sys::fs::OF_Append); - if (ec) { - op->emitError("Failed to open pattern catalog file: " + ec.message()); - return failure(); - } -#endif - do { // Find the next pattern with the highest benefit. const Pattern *bestPattern = nullptr; @@ -229,19 +209,18 @@ LogicalResult PatternApplicator::matchAndRewrite( const auto *pattern = static_cast(bestPattern); -#ifdef MLIR_ENABLE_CATALOG_GENERATOR +#ifndef NDEBUG OpBuilder::Listener *oldListener = rewriter.getListener(); RewriterBase::CatalogingListener *catalogingListener = - new RewriterBase::CatalogingListener( - oldListener, pattern->getDebugName(), catalogOs, - catalogWriteMutex); + new RewriterBase::CatalogingListener(oldListener, + pattern->getDebugName()); rewriter.setListener(catalogingListener); #endif result = pattern->matchAndRewrite(op, rewriter); LLVM_DEBUG(llvm::dbgs() << "\"" << bestPattern->getDebugName() << "\" result " << succeeded(result) << "\n"); -#ifdef MLIR_ENABLE_CATALOG_GENERATOR +#ifndef NDEBUG rewriter.setListener(oldListener); delete catalogingListener; #endif diff --git a/mlir/test/lit.cfg.py b/mlir/test/lit.cfg.py index 9b5cadd62befc..4cc204d96e9de 100644 --- a/mlir/test/lit.cfg.py +++ b/mlir/test/lit.cfg.py @@ -301,6 +301,19 @@ def find_real_python_interpreter(): ToolSubst("mlir-opt", "mlir-opt --verify-roundtrip", unresolved="fatal"), ] ) +elif "MLIR_GENERATE_PATTERN_CATALOG" in os.environ: + tools.extend([ + ToolSubst( + "mlir-opt", + "mlir-opt --debug-only=generate-pattern-catalog --mlir-disable-threading", + unresolved="fatal" + ), + ToolSubst( + "FileCheck", + "FileCheck --dump-input=always", + unresolved="fatal" + ), + ]) else: tools.extend(["mlir-opt"]) diff --git a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel index 281b2566304b0..23d89f41a3a45 100644 --- a/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/mlir/test/BUILD.bazel @@ -44,7 +44,6 @@ expand_template( "@MLIR_ENABLE_SPIRV_CPU_RUNNER@": "0", "@MLIR_ENABLE_VULKAN_RUNNER@": "0", "@MLIR_ENABLE_BINDINGS_PYTHON@": "0", - "@MLIR_ENABLE_CATALOG_GENERATOR@": "0", "@MLIR_RUN_AMX_TESTS@": "0", "@MLIR_RUN_ARM_SVE_TESTS@": "0", "@MLIR_RUN_ARM_SME_TESTS@": "0", From 037ff61cc898e46fdd3b066bbc4d1a499694eeb0 Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Sun, 29 Jun 2025 21:48:32 -0700 Subject: [PATCH 04/11] add debug log marker for ease of filtering --- mlir/lib/IR/CatalogingListener.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/mlir/lib/IR/CatalogingListener.cpp b/mlir/lib/IR/CatalogingListener.cpp index 156530d19431b..cd19a118798f0 100644 --- a/mlir/lib/IR/CatalogingListener.cpp +++ b/mlir/lib/IR/CatalogingListener.cpp @@ -5,22 +5,26 @@ using namespace mlir; +static constexpr StringLiteral catalogPrefix = "CatalogingListener: "; + void RewriterBase::CatalogingListener::notifyOperationInserted( Operation *op, InsertPoint previous) { - LLVM_DEBUG(llvm::dbgs() << patternName << " | notifyOperationInserted" + LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName + << " | notifyOperationInserted" << " | " << op->getName() << "\n"); ForwardingListener::notifyOperationInserted(op, previous); } void RewriterBase::CatalogingListener::notifyOperationModified(Operation *op) { - LLVM_DEBUG(llvm::dbgs() << patternName << " | notifyOperationModified" + LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName + << " | notifyOperationModified" << " | " << op->getName() << "\n"); ForwardingListener::notifyOperationModified(op); } void RewriterBase::CatalogingListener::notifyOperationReplaced( Operation *op, Operation *newOp) { - LLVM_DEBUG(llvm::dbgs() << patternName + LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName << " | notifyOperationReplaced (with op)" << " | " << op->getName() << " | " << newOp->getName() << "\n"); @@ -29,21 +33,23 @@ void RewriterBase::CatalogingListener::notifyOperationReplaced( void RewriterBase::CatalogingListener::notifyOperationReplaced( Operation *op, ValueRange replacement) { - LLVM_DEBUG(llvm::dbgs() << patternName + LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName << " | notifyOperationReplaced (with values)" << " | " << op->getName() << "\n"); ForwardingListener::notifyOperationReplaced(op, replacement); } void RewriterBase::CatalogingListener::notifyOperationErased(Operation *op) { - LLVM_DEBUG(llvm::dbgs() << patternName << " | notifyOperationErased" + LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName + << " | notifyOperationErased" << " | " << op->getName() << "\n"); ForwardingListener::notifyOperationErased(op); } void RewriterBase::CatalogingListener::notifyPatternBegin( const Pattern &pattern, Operation *op) { - LLVM_DEBUG(llvm::dbgs() << patternName << " | notifyPatternBegin" + LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName + << " | notifyPatternBegin" << " | " << op->getName() << "\n"); ForwardingListener::notifyPatternBegin(pattern, op); } From 179370ea68d05e1eec64cf2f43f4f19fc3ffe468 Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Sun, 29 Jun 2025 21:57:25 -0700 Subject: [PATCH 05/11] formatting --- mlir/test/lit.cfg.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/mlir/test/lit.cfg.py b/mlir/test/lit.cfg.py index 4cc204d96e9de..55b8e7e99f2bb 100644 --- a/mlir/test/lit.cfg.py +++ b/mlir/test/lit.cfg.py @@ -302,18 +302,16 @@ def find_real_python_interpreter(): ] ) elif "MLIR_GENERATE_PATTERN_CATALOG" in os.environ: - tools.extend([ - ToolSubst( - "mlir-opt", - "mlir-opt --debug-only=generate-pattern-catalog --mlir-disable-threading", - unresolved="fatal" - ), - ToolSubst( - "FileCheck", - "FileCheck --dump-input=always", - unresolved="fatal" - ), - ]) + tools.extend( + [ + ToolSubst( + "mlir-opt", + "mlir-opt --debug-only=generate-pattern-catalog --mlir-disable-threading", + unresolved="fatal", + ), + ToolSubst("FileCheck", "FileCheck --dump-input=always", unresolved="fatal"), + ] + ) else: tools.extend(["mlir-opt"]) From c91206b2e55c0153813195003da52ee4529b7081 Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Mon, 30 Jun 2025 10:29:25 -0700 Subject: [PATCH 06/11] Apply RAII Co-authored-by: Mehdi Amini --- mlir/lib/Rewrite/PatternApplicator.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mlir/lib/Rewrite/PatternApplicator.cpp b/mlir/lib/Rewrite/PatternApplicator.cpp index 47a5006767b35..c34ecdf5c99a0 100644 --- a/mlir/lib/Rewrite/PatternApplicator.cpp +++ b/mlir/lib/Rewrite/PatternApplicator.cpp @@ -211,10 +211,11 @@ LogicalResult PatternApplicator::matchAndRewrite( #ifndef NDEBUG OpBuilder::Listener *oldListener = rewriter.getListener(); - RewriterBase::CatalogingListener *catalogingListener = - new RewriterBase::CatalogingListener(oldListener, + auto catalogingListener = + std::make_unique(oldListener, pattern->getDebugName()); - rewriter.setListener(catalogingListener); + rewriter.setListener(catalogingListener.get()); + llvm::make_scope_exit([&] { rewriter.setListener(oldListener); }; #endif result = pattern->matchAndRewrite(op, rewriter); LLVM_DEBUG(llvm::dbgs() From 966c7da4c73cb993e5a097cae5538becc2ed230e Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Mon, 30 Jun 2025 10:29:45 -0700 Subject: [PATCH 07/11] Remove need for post set-listener with RAII Co-authored-by: Mehdi Amini --- mlir/lib/Rewrite/PatternApplicator.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mlir/lib/Rewrite/PatternApplicator.cpp b/mlir/lib/Rewrite/PatternApplicator.cpp index c34ecdf5c99a0..210336afbb9a7 100644 --- a/mlir/lib/Rewrite/PatternApplicator.cpp +++ b/mlir/lib/Rewrite/PatternApplicator.cpp @@ -221,10 +221,6 @@ LogicalResult PatternApplicator::matchAndRewrite( LLVM_DEBUG(llvm::dbgs() << "\"" << bestPattern->getDebugName() << "\" result " << succeeded(result) << "\n"); -#ifndef NDEBUG - rewriter.setListener(oldListener); - delete catalogingListener; -#endif } // Process the result of the pattern application. From 7b19f44e282706c529024b9d72d27a49e15fc794 Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Mon, 30 Jun 2025 10:35:32 -0700 Subject: [PATCH 08/11] formatting --- mlir/lib/Rewrite/PatternApplicator.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mlir/lib/Rewrite/PatternApplicator.cpp b/mlir/lib/Rewrite/PatternApplicator.cpp index 210336afbb9a7..2771c90c2ee57 100644 --- a/mlir/lib/Rewrite/PatternApplicator.cpp +++ b/mlir/lib/Rewrite/PatternApplicator.cpp @@ -212,10 +212,11 @@ LogicalResult PatternApplicator::matchAndRewrite( #ifndef NDEBUG OpBuilder::Listener *oldListener = rewriter.getListener(); auto catalogingListener = - std::make_unique(oldListener, - pattern->getDebugName()); + std::make_unique( + oldListener, pattern->getDebugName()); rewriter.setListener(catalogingListener.get()); - llvm::make_scope_exit([&] { rewriter.setListener(oldListener); }; + llvm::make_scope_exit([&] { + rewriter.setListener(oldListener); }; #endif result = pattern->matchAndRewrite(op, rewriter); LLVM_DEBUG(llvm::dbgs() From 6443f06e141fd1022b9c528ed0f0bc47f7785f74 Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Mon, 30 Jun 2025 13:12:42 -0700 Subject: [PATCH 09/11] rename to PatternLoggingListener --- mlir/include/mlir/IR/PatternMatch.h | 6 ++++-- mlir/lib/IR/CMakeLists.txt | 2 +- ...ngListener.cpp => PatternLoggingListener.cpp} | 16 ++++++++-------- mlir/lib/Rewrite/PatternApplicator.cpp | 10 +++++++--- mlir/test/lit.cfg.py | 2 +- 5 files changed, 21 insertions(+), 15 deletions(-) rename mlir/lib/IR/{CatalogingListener.cpp => PatternLoggingListener.cpp} (76%) diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index 63563fb53cd81..d6045ab46d21d 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -475,8 +475,10 @@ class RewriterBase : public OpBuilder { RewriterBase::Listener *rewriteListener; }; - struct CatalogingListener : public RewriterBase::ForwardingListener { - CatalogingListener(OpBuilder::Listener *listener, StringRef patternName) + /// A listener that logs notification events to llvm::dbgs() before + /// forwarding to the base listener. + struct PatternLoggingListener : public RewriterBase::ForwardingListener { + PatternLoggingListener(OpBuilder::Listener *listener, StringRef patternName) : RewriterBase::ForwardingListener(listener), patternName(patternName) { } diff --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt index c6900d4fcae3a..3ef69cea18f0a 100644 --- a/mlir/lib/IR/CMakeLists.txt +++ b/mlir/lib/IR/CMakeLists.txt @@ -18,7 +18,6 @@ add_mlir_library(MLIRIR BuiltinDialectBytecode.cpp BuiltinTypes.cpp BuiltinTypeInterfaces.cpp - CatalogingListener.cpp Diagnostics.cpp Dialect.cpp DialectResourceBlobManager.cpp @@ -30,6 +29,7 @@ add_mlir_library(MLIRIR ODSSupport.cpp Operation.cpp OperationSupport.cpp + PatternLoggingListener.cpp PatternMatch.cpp Region.cpp RegionKindInterface.cpp diff --git a/mlir/lib/IR/CatalogingListener.cpp b/mlir/lib/IR/PatternLoggingListener.cpp similarity index 76% rename from mlir/lib/IR/CatalogingListener.cpp rename to mlir/lib/IR/PatternLoggingListener.cpp index cd19a118798f0..735997bbd5937 100644 --- a/mlir/lib/IR/CatalogingListener.cpp +++ b/mlir/lib/IR/PatternLoggingListener.cpp @@ -1,13 +1,13 @@ #include "mlir/IR/PatternMatch.h" #include "llvm/Support/Debug.h" -#define DEBUG_TYPE "generate-pattern-catalog" +#define DEBUG_TYPE "pattern-logging-listener" using namespace mlir; -static constexpr StringLiteral catalogPrefix = "CatalogingListener: "; +static constexpr StringLiteral catalogPrefix = "PatternLoggingListener: "; -void RewriterBase::CatalogingListener::notifyOperationInserted( +void RewriterBase::PatternLoggingListener::notifyOperationInserted( Operation *op, InsertPoint previous) { LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName << " | notifyOperationInserted" @@ -15,14 +15,14 @@ void RewriterBase::CatalogingListener::notifyOperationInserted( ForwardingListener::notifyOperationInserted(op, previous); } -void RewriterBase::CatalogingListener::notifyOperationModified(Operation *op) { +void RewriterBase::PatternLoggingListener::notifyOperationModified(Operation *op) { LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName << " | notifyOperationModified" << " | " << op->getName() << "\n"); ForwardingListener::notifyOperationModified(op); } -void RewriterBase::CatalogingListener::notifyOperationReplaced( +void RewriterBase::PatternLoggingListener::notifyOperationReplaced( Operation *op, Operation *newOp) { LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName << " | notifyOperationReplaced (with op)" @@ -31,7 +31,7 @@ void RewriterBase::CatalogingListener::notifyOperationReplaced( ForwardingListener::notifyOperationReplaced(op, newOp); } -void RewriterBase::CatalogingListener::notifyOperationReplaced( +void RewriterBase::PatternLoggingListener::notifyOperationReplaced( Operation *op, ValueRange replacement) { LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName << " | notifyOperationReplaced (with values)" @@ -39,14 +39,14 @@ void RewriterBase::CatalogingListener::notifyOperationReplaced( ForwardingListener::notifyOperationReplaced(op, replacement); } -void RewriterBase::CatalogingListener::notifyOperationErased(Operation *op) { +void RewriterBase::PatternLoggingListener::notifyOperationErased(Operation *op) { LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName << " | notifyOperationErased" << " | " << op->getName() << "\n"); ForwardingListener::notifyOperationErased(op); } -void RewriterBase::CatalogingListener::notifyPatternBegin( +void RewriterBase::PatternLoggingListener::notifyPatternBegin( const Pattern &pattern, Operation *op) { LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName << " | notifyPatternBegin" diff --git a/mlir/lib/Rewrite/PatternApplicator.cpp b/mlir/lib/Rewrite/PatternApplicator.cpp index 2771c90c2ee57..62ccb7e55659a 100644 --- a/mlir/lib/Rewrite/PatternApplicator.cpp +++ b/mlir/lib/Rewrite/PatternApplicator.cpp @@ -15,6 +15,10 @@ #include "ByteCode.h" #include "llvm/Support/Debug.h" +#ifndef NDEBUG +#include "llvm/ADT/ScopeExit.h" +#endif + #define DEBUG_TYPE "pattern-application" using namespace mlir; @@ -212,11 +216,11 @@ LogicalResult PatternApplicator::matchAndRewrite( #ifndef NDEBUG OpBuilder::Listener *oldListener = rewriter.getListener(); auto catalogingListener = - std::make_unique( + std::make_unique( oldListener, pattern->getDebugName()); rewriter.setListener(catalogingListener.get()); - llvm::make_scope_exit([&] { - rewriter.setListener(oldListener); }; + auto resetListenerCallback = llvm::make_scope_exit( + [&] { rewriter.setListener(oldListener); }); #endif result = pattern->matchAndRewrite(op, rewriter); LLVM_DEBUG(llvm::dbgs() diff --git a/mlir/test/lit.cfg.py b/mlir/test/lit.cfg.py index 55b8e7e99f2bb..233fef8ec4296 100644 --- a/mlir/test/lit.cfg.py +++ b/mlir/test/lit.cfg.py @@ -306,7 +306,7 @@ def find_real_python_interpreter(): [ ToolSubst( "mlir-opt", - "mlir-opt --debug-only=generate-pattern-catalog --mlir-disable-threading", + "mlir-opt --debug-only=pattern-logging-listener --mlir-disable-threading", unresolved="fatal", ), ToolSubst("FileCheck", "FileCheck --dump-input=always", unresolved="fatal"), From 8b9cbc444aa14971ea5ea06fb789be862b158632 Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Mon, 30 Jun 2025 16:05:12 -0700 Subject: [PATCH 10/11] rename catalogingListener -> loggingListener --- mlir/lib/Rewrite/PatternApplicator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mlir/lib/Rewrite/PatternApplicator.cpp b/mlir/lib/Rewrite/PatternApplicator.cpp index 62ccb7e55659a..b2b372b7b1249 100644 --- a/mlir/lib/Rewrite/PatternApplicator.cpp +++ b/mlir/lib/Rewrite/PatternApplicator.cpp @@ -215,10 +215,10 @@ LogicalResult PatternApplicator::matchAndRewrite( #ifndef NDEBUG OpBuilder::Listener *oldListener = rewriter.getListener(); - auto catalogingListener = + auto loggingListener = std::make_unique( oldListener, pattern->getDebugName()); - rewriter.setListener(catalogingListener.get()); + rewriter.setListener(loggingListener.get()); auto resetListenerCallback = llvm::make_scope_exit( [&] { rewriter.setListener(oldListener); }); #endif From c5cc86aeaf0f7dabac855bf343a916f4eb2d623d Mon Sep 17 00:00:00 2001 From: Jeremy Kun Date: Tue, 1 Jul 2025 22:16:49 -0700 Subject: [PATCH 11/11] use LDBG macro for brevity --- mlir/lib/IR/PatternLoggingListener.cpp | 41 +++++++++++--------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/mlir/lib/IR/PatternLoggingListener.cpp b/mlir/lib/IR/PatternLoggingListener.cpp index 735997bbd5937..ce2123ae1a19a 100644 --- a/mlir/lib/IR/PatternLoggingListener.cpp +++ b/mlir/lib/IR/PatternLoggingListener.cpp @@ -2,54 +2,49 @@ #include "llvm/Support/Debug.h" #define DEBUG_TYPE "pattern-logging-listener" +#define DBGS() (llvm::dbgs() << "[" << DEBUG_TYPE << "] ") +#define LDBG(X) LLVM_DEBUG(DBGS() << X << "\n") using namespace mlir; -static constexpr StringLiteral catalogPrefix = "PatternLoggingListener: "; - void RewriterBase::PatternLoggingListener::notifyOperationInserted( Operation *op, InsertPoint previous) { - LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName - << " | notifyOperationInserted" - << " | " << op->getName() << "\n"); + LDBG(patternName << " | notifyOperationInserted" + << " | " << op->getName()); ForwardingListener::notifyOperationInserted(op, previous); } -void RewriterBase::PatternLoggingListener::notifyOperationModified(Operation *op) { - LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName - << " | notifyOperationModified" - << " | " << op->getName() << "\n"); +void RewriterBase::PatternLoggingListener::notifyOperationModified( + Operation *op) { + LDBG(patternName << " | notifyOperationModified" + << " | " << op->getName()); ForwardingListener::notifyOperationModified(op); } void RewriterBase::PatternLoggingListener::notifyOperationReplaced( Operation *op, Operation *newOp) { - LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName - << " | notifyOperationReplaced (with op)" - << " | " << op->getName() << " | " << newOp->getName() - << "\n"); + LDBG(patternName << " | notifyOperationReplaced (with op)" + << " | " << op->getName() << " | " << newOp->getName()); ForwardingListener::notifyOperationReplaced(op, newOp); } void RewriterBase::PatternLoggingListener::notifyOperationReplaced( Operation *op, ValueRange replacement) { - LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName - << " | notifyOperationReplaced (with values)" - << " | " << op->getName() << "\n"); + LDBG(patternName << " | notifyOperationReplaced (with values)" + << " | " << op->getName()); ForwardingListener::notifyOperationReplaced(op, replacement); } -void RewriterBase::PatternLoggingListener::notifyOperationErased(Operation *op) { - LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName - << " | notifyOperationErased" - << " | " << op->getName() << "\n"); +void RewriterBase::PatternLoggingListener::notifyOperationErased( + Operation *op) { + LDBG(patternName << " | notifyOperationErased" + << " | " << op->getName()); ForwardingListener::notifyOperationErased(op); } void RewriterBase::PatternLoggingListener::notifyPatternBegin( const Pattern &pattern, Operation *op) { - LLVM_DEBUG(llvm::dbgs() << catalogPrefix << patternName - << " | notifyPatternBegin" - << " | " << op->getName() << "\n"); + LDBG(patternName << " | notifyPatternBegin" + << " | " << op->getName()); ForwardingListener::notifyPatternBegin(pattern, op); }