-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[mlir][core] Add an MLIR "pattern catalog" generator #146228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-mlir-core Author: Jeremy Kun (j2kun) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/146228.diff 5 Files Affected:
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<std::mutex> lock(writeMutex);
+ os << patternName << " | notifyOperationInserted"
+ << " | " << op->getName() << "\n";
+ os.flush();
+ }
+ ForwardingListener::notifyOperationInserted(op, previous);
+ }
+
+ void notifyOperationModified(Operation *op) override {
+ {
+ std::lock_guard<std::mutex> lock(writeMutex);
+ os << patternName << " | notifyOperationModified"
+ << " | " << op->getName() << "\n";
+ os.flush();
+ }
+ ForwardingListener::notifyOperationModified(op);
+ }
+
+ void notifyOperationReplaced(Operation *op, Operation *newOp) override {
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> lock(writeMutex);
+ os << patternName << " | notifyOperationReplaced (with values)"
+ << " | " << op->getName() << "\n";
+ os.flush();
+ }
+ ForwardingListener::notifyOperationReplaced(op, replacement);
+ }
+
+ void notifyOperationErased(Operation *op) override {
+ {
+ std::lock_guard<std::mutex> lock(writeMutex);
+ os << patternName << " | notifyOperationErased"
+ << " | " << op->getName() << "\n";
+ os.flush();
+ }
+ ForwardingListener::notifyOperationErased(op);
+ }
+
+ void notifyPatternBegin(const Pattern &pattern, Operation *op) override {
+ {
+ std::lock_guard<std::mutex> 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 <cxxabi.h>
+#include <mutex>
+#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<const RewritePattern *>(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",
|
@llvm/pr-subscribers-mlir Author: Jeremy Kun (j2kun) ChangesThis 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. Full diff: https://github.com/llvm/llvm-project/pull/146228.diff 5 Files Affected:
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<std::mutex> lock(writeMutex);
+ os << patternName << " | notifyOperationInserted"
+ << " | " << op->getName() << "\n";
+ os.flush();
+ }
+ ForwardingListener::notifyOperationInserted(op, previous);
+ }
+
+ void notifyOperationModified(Operation *op) override {
+ {
+ std::lock_guard<std::mutex> lock(writeMutex);
+ os << patternName << " | notifyOperationModified"
+ << " | " << op->getName() << "\n";
+ os.flush();
+ }
+ ForwardingListener::notifyOperationModified(op);
+ }
+
+ void notifyOperationReplaced(Operation *op, Operation *newOp) override {
+ {
+ std::lock_guard<std::mutex> 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<std::mutex> lock(writeMutex);
+ os << patternName << " | notifyOperationReplaced (with values)"
+ << " | " << op->getName() << "\n";
+ os.flush();
+ }
+ ForwardingListener::notifyOperationReplaced(op, replacement);
+ }
+
+ void notifyOperationErased(Operation *op) override {
+ {
+ std::lock_guard<std::mutex> lock(writeMutex);
+ os << patternName << " | notifyOperationErased"
+ << " | " << op->getName() << "\n";
+ os.flush();
+ }
+ ForwardingListener::notifyOperationErased(op);
+ }
+
+ void notifyPatternBegin(const Pattern &pattern, Operation *op) override {
+ {
+ std::lock_guard<std::mutex> 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 <cxxabi.h>
+#include <mutex>
+#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<const RewritePattern *>(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",
|
|
I support this with every fiber of my being! Bravo. My only comment (aside from |
I had originally tried something like this, and my obstacle was that I couldn't get the test suite to produce useful outputs because stuff was piped to FileCheck (when I tried just dumping to llvm::outs()), and I didn't have a way to modify the RUN command of all the lit tests in a systematic/pragmatic way to add a debug-only flag. |
If you make |
err sorry - you'd have to get |
Is not relying on a filesystem all that critical? The mutex is mildly annoying, but it's scoped pretty tightly, and the alternative requires changes in a few other components (wouldn't I also need to plumb these environment variables through the lit config?) and additional cleanup of the output. I agree setting environment variables would be the cleanest approach. I'm just not confident in my ability to push a big change to |
I personally don't care (I think it's a reasonable use) - maybe someone else can comment on whether this kind of thing is acceptable. |
Spot checking a few examples, it looks like I also need to hook into the dialect conversion framework. |
✅ With the latest revision this PR passed the Python code formatter. |
Using ToolSubst I modified the PR to no longer use file writing and/or the mutex. It's quite simple now, and the last two steps before this PR can feasibly be merged are:
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That LGTM, but @jpienaar is out for a few days and we should wait since he worked on an alternative.
After discussing with @matthias-springer it seems the dialect conversion framework is not immediately compatible with this change (in large part because the conversion rewriter is itself implemented as a listener that overrides much of the default behavior to do stateful things). The immediate result is that the catalog only includes "insert op" actions for dialect conversion patterns. I am looking into a different way to support this for dialect conversion, until (perhaps in the distant future) dialect conversion is refactored so that it can operate with listeners more smoothly. If it's OK, I will split that into a different PR, and so the last thing I need here is a lit test that ensures the debug output is produced in a pass that uses the greedy driver. |
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.
Co-authored-by: Mehdi Amini <[email protected]>
Co-authored-by: Mehdi Amini <[email protected]>
@jpienaar any final suggestions? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good, seems unobtrusive enough
Operation *op, ValueRange replacement) { | ||
LDBG(patternName << " | notifyOperationReplaced (with values)" | ||
<< " | " << op->getName()); | ||
ForwardingListener::notifyOperationReplaced(op, replacement); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So all of these may end up with duplicate notifications (e.g., a pattern could insert the same op 10 times and this would report 10 times), and so that would be handled by post-processing? (I think also conditional emission, would just be squashed right, so would end up with union of all that pattern can do)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the postprocessing includes sort | uniq
, and I don't have any immediate plans to support a more structured sort of query.
|
||
void RewriterBase::PatternLoggingListener::notifyOperationReplaced( | ||
Operation *op, Operation *newOp) { | ||
LDBG(patternName << " | notifyOperationReplaced (with op)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OOC why does with op vs value matter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping originally to be able to query for a source and target op, but then I found that almost all upstream patterns replace an op with values rather than calling replaceOpWithNewOp
(even when replaceOp
is given an operation, it is cast to the results and the notification hook is treated as replacing with values).
I'm not sure what to do with this in the end: keep it and expose it in the search, or just treat "operation replaced" as if it is "operation erased"
|
||
#define DEBUG_TYPE "pattern-logging-listener" | ||
#define DBGS() (llvm::dbgs() << "[" << DEBUG_TYPE << "] ") | ||
#define LDBG(X) LLVM_DEBUG(DBGS() << X << "\n") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, funnily was working on a general utility that does such logging as I ended up writing it often :)
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/140/builds/27168 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/117/builds/11597 Here is the relevant piece of the build log for the reference
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/116/builds/15719 Here is the relevant piece of the build log for the reference
|
Hi there, This PR has failed mlir test currently breaking our bots. Could you please take a look? Thanks!
bot: https://lab.llvm.org/buildbot/#/builders/140/builds/27168 |
Some platforms print `{anonymous}` instead of the other two forms accepted by the test regex. This PR just removes the attempt to guess how the anonymous namespace will be printed. @Kewen12 is there a way to trigger the particular CIs that failed in #146228 on this PR? Co-authored-by: Jeremy Kun <[email protected]>
…378) Some platforms print `{anonymous}` instead of the other two forms accepted by the test regex. This PR just removes the attempt to guess how the anonymous namespace will be printed. @Kewen12 is there a way to trigger the particular CIs that failed in llvm/llvm-project#146228 on this PR? Co-authored-by: Jeremy Kun <[email protected]>
I missed something on the initial PR: we don't test debug output, because it is supposed to be exclusively a debug output. Tests should not rely on it ever be present. |
@joker-eph what alternative testing option is best? |
I don’t have one that I can’t think of, it has to be maintained on a kind of best effort basis. |
This PR adds a feature that, when enabled, it attaches a listener to all RewritePatterns that emits the name of the operation being modified to
llvm::dbgs
. When the MLIR test suite is run, these debug outputs can be filtered and 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.The feature is enabled when MLIR is combined in debug mode, though a previous version of this PR used a CMake build flag to trigger the behavior. The debug logs emitted can be viewed with
--debug-only=generate-pattern-catalog
, and the lit config is modified to do this when the env varMLIR_GENERATE_PATTERN_CATALOG
is set.Example usage:
Sample pattern catalog output (that fits in a gist): https://gist.github.com/j2kun/02d1ab8d31c10d71027724984c89905a
[edit]: removed use of RTTI, removed cmake build flag