Skip to content

Commit 24a56ca

Browse files
[mlir][IR] Add listener notifications for pattern begin/end
1 parent c698363 commit 24a56ca

File tree

3 files changed

+73
-28
lines changed

3 files changed

+73
-28
lines changed

mlir/include/mlir/IR/PatternMatch.h

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -432,11 +432,22 @@ class RewriterBase : public OpBuilder {
432432
/// Note: This notification is not triggered when unlinking an operation.
433433
virtual void notifyOperationErased(Operation *op) {}
434434

435-
/// Notify the listener that the pattern failed to match the given
436-
/// operation, and provide a callback to populate a diagnostic with the
437-
/// reason why the failure occurred. This method allows for derived
438-
/// listeners to optionally hook into the reason why a rewrite failed, and
439-
/// display it to users.
435+
/// Notify the listener that the specified pattern is about to be applied
436+
/// at the specified root operation.
437+
virtual void notifyPatternBegin(const Pattern &pattern, Operation *op) {}
438+
439+
/// Notify the listener that a pattern application finished with the
440+
/// specified status. "success" indicates that the pattern was applied
441+
/// successfully. "failure" indicates that the pattern could not be
442+
/// applied. The pattern may have communicated the reason for the failure
443+
/// with `notifyMatchFailure`.
444+
virtual void notifyPatternEnd(const Pattern &pattern,
445+
LogicalResult status) {}
446+
447+
/// Notify the listener that the pattern failed to match, and provide a
448+
/// callback to populate a diagnostic with the reason why the failure
449+
/// occurred. This method allows for derived listeners to optionally hook
450+
/// into the reason why a rewrite failed, and display it to users.
440451
virtual void
441452
notifyMatchFailure(Location loc,
442453
function_ref<void(Diagnostic &)> reasonCallback) {}
@@ -478,6 +489,15 @@ class RewriterBase : public OpBuilder {
478489
if (auto *rewriteListener = dyn_cast<RewriterBase::Listener>(listener))
479490
rewriteListener->notifyOperationErased(op);
480491
}
492+
void notifyPatternBegin(const Pattern &pattern, Operation *op) override {
493+
if (auto *rewriteListener = dyn_cast<RewriterBase::Listener>(listener))
494+
rewriteListener->notifyPatternBegin(pattern, op);
495+
}
496+
void notifyPatternEnd(const Pattern &pattern,
497+
LogicalResult status) override {
498+
if (auto *rewriteListener = dyn_cast<RewriterBase::Listener>(listener))
499+
rewriteListener->notifyPatternEnd(pattern, status);
500+
}
481501
void notifyMatchFailure(
482502
Location loc,
483503
function_ref<void(Diagnostic &)> reasonCallback) override {

mlir/lib/Transforms/Utils/DialectConversion.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,7 +1856,8 @@ class OperationLegalizer {
18561856
using LegalizationAction = ConversionTarget::LegalizationAction;
18571857

18581858
OperationLegalizer(const ConversionTarget &targetInfo,
1859-
const FrozenRewritePatternSet &patterns);
1859+
const FrozenRewritePatternSet &patterns,
1860+
const ConversionConfig &config);
18601861

18611862
/// Returns true if the given operation is known to be illegal on the target.
18621863
bool isIllegal(Operation *op) const;
@@ -1948,12 +1949,16 @@ class OperationLegalizer {
19481949

19491950
/// The pattern applicator to use for conversions.
19501951
PatternApplicator applicator;
1952+
1953+
/// Dialect conversion configuration.
1954+
const ConversionConfig &config;
19511955
};
19521956
} // namespace
19531957

19541958
OperationLegalizer::OperationLegalizer(const ConversionTarget &targetInfo,
1955-
const FrozenRewritePatternSet &patterns)
1956-
: target(targetInfo), applicator(patterns) {
1959+
const FrozenRewritePatternSet &patterns,
1960+
const ConversionConfig &config)
1961+
: target(targetInfo), applicator(patterns), config(config) {
19571962
// The set of patterns that can be applied to illegal operations to transform
19581963
// them into legal ones.
19591964
DenseMap<OperationName, LegalizationPatterns> legalizerPatterns;
@@ -2098,7 +2103,10 @@ OperationLegalizer::legalizeWithPattern(Operation *op,
20982103

20992104
// Functor that returns if the given pattern may be applied.
21002105
auto canApply = [&](const Pattern &pattern) {
2101-
return canApplyPattern(op, pattern, rewriter);
2106+
bool canApply = canApplyPattern(op, pattern, rewriter);
2107+
if (canApply && config.listener)
2108+
config.listener->notifyPatternBegin(pattern, op);
2109+
return canApply;
21022110
};
21032111

21042112
// Functor that cleans up the rewriter state after a pattern failed to match.
@@ -2115,6 +2123,8 @@ OperationLegalizer::legalizeWithPattern(Operation *op,
21152123
rewriterImpl.config.notifyCallback(diag);
21162124
}
21172125
});
2126+
if (config.listener)
2127+
config.listener->notifyPatternEnd(pattern, failure());
21182128
rewriterImpl.resetState(curState);
21192129
appliedPatterns.erase(&pattern);
21202130
};
@@ -2127,6 +2137,8 @@ OperationLegalizer::legalizeWithPattern(Operation *op,
21272137
appliedPatterns.erase(&pattern);
21282138
if (failed(result))
21292139
rewriterImpl.resetState(curState);
2140+
if (config.listener)
2141+
config.listener->notifyPatternEnd(pattern, result);
21302142
return result;
21312143
};
21322144

@@ -2502,7 +2514,8 @@ struct OperationConverter {
25022514
const FrozenRewritePatternSet &patterns,
25032515
const ConversionConfig &config,
25042516
OpConversionMode mode)
2505-
: opLegalizer(target, patterns), config(config), mode(mode) {}
2517+
: config(config), opLegalizer(target, patterns, this->config),
2518+
mode(mode) {}
25062519

25072520
/// Converts the given operations to the conversion target.
25082521
LogicalResult convertOperations(ArrayRef<Operation *> ops);
@@ -2539,12 +2552,12 @@ struct OperationConverter {
25392552
ConversionPatternRewriterImpl &rewriterImpl,
25402553
const DenseMap<Value, SmallVector<Value>> &inverseMapping);
25412554

2542-
/// The legalizer to use when converting operations.
2543-
OperationLegalizer opLegalizer;
2544-
25452555
/// Dialect conversion configuration.
25462556
ConversionConfig config;
25472557

2558+
/// The legalizer to use when converting operations.
2559+
OperationLegalizer opLegalizer;
2560+
25482561
/// The conversion mode to use when legalizing operations.
25492562
OpConversionMode mode;
25502563
};

mlir/lib/Transforms/Utils/GreedyPatternRewriteDriver.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -562,8 +562,7 @@ bool GreedyPatternRewriteDriver::processWorklist() {
562562
// Try to match one of the patterns. The rewriter is automatically
563563
// notified of any necessary changes, so there is nothing else to do
564564
// here.
565-
#ifndef NDEBUG
566-
auto canApply = [&](const Pattern &pattern) {
565+
function_ref<bool(const Pattern &)> canApply = [&](const Pattern &pattern) {
567566
LLVM_DEBUG({
568567
logger.getOStream() << "\n";
569568
logger.startLine() << "* Pattern " << pattern.getDebugName() << " : '"
@@ -572,20 +571,33 @@ bool GreedyPatternRewriteDriver::processWorklist() {
572571
logger.getOStream() << ")' {\n";
573572
logger.indent();
574573
});
574+
if (config.listener)
575+
config.listener->notifyPatternBegin(pattern, op);
575576
return true;
576577
};
577-
auto onFailure = [&](const Pattern &pattern) {
578-
LLVM_DEBUG(logResult("failure", "pattern failed to match"));
579-
};
580-
auto onSuccess = [&](const Pattern &pattern) {
581-
LLVM_DEBUG(logResult("success", "pattern applied successfully"));
582-
return success();
583-
};
584-
#else
585-
function_ref<bool(const Pattern &)> canApply = {};
586-
function_ref<void(const Pattern &)> onFailure = {};
587-
function_ref<LogicalResult(const Pattern &)> onSuccess = {};
588-
#endif
578+
function_ref<void(const Pattern &)> onFailure =
579+
[&](const Pattern &pattern) {
580+
LLVM_DEBUG(logResult("failure", "pattern failed to match"));
581+
if (config.listener)
582+
config.listener->notifyPatternEnd(pattern, failure());
583+
};
584+
function_ref<LogicalResult(const Pattern &)> onSuccess =
585+
[&](const Pattern &pattern) {
586+
LLVM_DEBUG(logResult("success", "pattern applied successfully"));
587+
if (config.listener)
588+
config.listener->notifyPatternEnd(pattern, success());
589+
return success();
590+
};
591+
592+
#ifdef NDEBUG
593+
// Optimization: PatternApplicator callbacks are not needed when running in
594+
// optimized mode and without a listener.
595+
if (!config.listener) {
596+
canApply = nullptr;
597+
onFailure = nullptr;
598+
onSuccess = nullptr;
599+
}
600+
#endif // NDEBUG
589601

590602
#if MLIR_ENABLE_EXPENSIVE_PATTERN_API_CHECKS
591603
if (config.scope) {
@@ -731,7 +743,7 @@ void GreedyPatternRewriteDriver::notifyMatchFailure(
731743
LLVM_DEBUG({
732744
Diagnostic diag(loc, DiagnosticSeverity::Remark);
733745
reasonCallback(diag);
734-
logger.startLine() << "** Failure : " << diag.str() << "\n";
746+
logger.startLine() << "** Match Failure : " << diag.str() << "\n";
735747
});
736748
if (config.listener)
737749
config.listener->notifyMatchFailure(loc, reasonCallback);

0 commit comments

Comments
 (0)