aboutsummaryrefslogtreecommitdiff
path: root/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp
diff options
context:
space:
mode:
authorMatthias Springer <me@m-sp.org>2023-12-22 16:44:07 +0900
committerGitHub <noreply@github.com>2023-12-22 16:44:07 +0900
commit73b86d1b2d6822984c24d27da10ea3de7056931f (patch)
treea363f10440aea1a01027a395debd6a4c3e6f5070 /mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp
parenta15532d7647a8a4b7fd2889bd97f6f72f273c4bf (diff)
downloadllvm-73b86d1b2d6822984c24d27da10ea3de7056931f.zip
llvm-73b86d1b2d6822984c24d27da10ea3de7056931f.tar.gz
llvm-73b86d1b2d6822984c24d27da10ea3de7056931f.tar.bz2
[mlir][Transforms] `GreedyPatternRewriteDriver`: verify IR (#74270)
This commit adds an additional "expensive check" that verifies the IR before starting a greedy pattern rewriter, after every pattern application and after every folding. (Only if `MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS` is set.) It also adds an assertion that the `scope` region (part of `GreedyRewriteConfig`) is not being erased as part of the greedy pattern rewrite. That would break the scoping mechanism and the expensive checks. This commit does not fix any patterns, this is done in separate commits.
Diffstat (limited to 'mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp')
-rw-r--r--mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp45
1 files changed, 41 insertions, 4 deletions
diff --git a/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp b/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp
index 7decbce..eca13f5 100644
--- a/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp
+++ b/mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp
@@ -15,6 +15,7 @@
#include "mlir/Config/mlir-config.h"
#include "mlir/IR/Action.h"
#include "mlir/IR/Matchers.h"
+#include "mlir/IR/Verifier.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Rewrite/PatternApplicator.h"
#include "mlir/Transforms/FoldUtils.h"
@@ -432,6 +433,10 @@ bool GreedyPatternRewriteDriver::processWorklist() {
if (succeeded(folder.tryToFold(op))) {
LLVM_DEBUG(logResultWithLine("success", "operation was folded"));
changed = true;
+#if MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
+ if (config.scope && failed(verify(config.scope->getParentOp())))
+ llvm::report_fatal_error("IR failed to verify after folding");
+#endif // MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
continue;
}
@@ -464,8 +469,9 @@ bool GreedyPatternRewriteDriver::processWorklist() {
#endif
#if MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
- debugFingerPrints.computeFingerPrints(
- /*topLevel=*/config.scope ? config.scope->getParentOp() : op);
+ if (config.scope) {
+ debugFingerPrints.computeFingerPrints(config.scope->getParentOp());
+ }
auto clearFingerprints =
llvm::make_scope_exit([&]() { debugFingerPrints.clear(); });
#endif // MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
@@ -473,17 +479,24 @@ bool GreedyPatternRewriteDriver::processWorklist() {
LogicalResult matchResult =
matcher.matchAndRewrite(op, *this, canApply, onFailure, onSuccess);
+#if MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
+ if (config.scope && failed(verify(config.scope->getParentOp())))
+ llvm::report_fatal_error("IR failed to verify after pattern application");
+#endif // MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
+
if (succeeded(matchResult)) {
LLVM_DEBUG(logResultWithLine("success", "pattern matched"));
#if MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
- debugFingerPrints.notifyRewriteSuccess();
+ if (config.scope)
+ debugFingerPrints.notifyRewriteSuccess();
#endif // MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
changed = true;
++numRewrites;
} else {
LLVM_DEBUG(logResultWithLine("failure", "pattern failed to match"));
#if MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
- debugFingerPrints.notifyRewriteFailure();
+ if (config.scope)
+ debugFingerPrints.notifyRewriteFailure();
#endif // MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
}
}
@@ -562,6 +575,18 @@ void GreedyPatternRewriteDriver::notifyOperationRemoved(Operation *op) {
logger.startLine() << "** Erase : '" << op->getName() << "'(" << op
<< ")\n";
});
+
+#ifndef NDEBUG
+ // Only ops that are within the configured scope are added to the worklist of
+ // the greedy pattern rewriter. Moreover, the parent op of the scope region is
+ // the part of the IR that is taken into account for the "expensive checks".
+ // A greedy pattern rewrite is not allowed to erase the parent op of the scope
+ // region, as that would break the worklist handling and the expensive checks.
+ if (config.scope && config.scope->getParentOp() == op)
+ llvm_unreachable(
+ "scope region must not be erased during greedy pattern rewrite");
+#endif // NDEBUG
+
if (config.listener)
config.listener->notifyOperationRemoved(op);
@@ -721,6 +746,12 @@ mlir::applyPatternsAndFoldGreedily(Region &region,
if (!config.scope)
config.scope = &region;
+#if MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
+ if (failed(verify(config.scope->getParentOp())))
+ llvm::report_fatal_error(
+ "greedy pattern rewriter input IR failed to verify");
+#endif // MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
+
// Start the pattern driver.
RegionPatternRewriteDriver driver(region.getContext(), patterns, config,
region);
@@ -846,6 +877,12 @@ LogicalResult mlir::applyOpPatternsAndFold(
#endif // NDEBUG
}
+#if MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
+ if (config.scope && failed(verify(config.scope->getParentOp())))
+ llvm::report_fatal_error(
+ "greedy pattern rewriter input IR failed to verify");
+#endif // MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
+
// Start the pattern driver.
llvm::SmallDenseSet<Operation *, 4> surviving;
MultiOpPatternRewriteDriver driver(ops.front()->getContext(), patterns,