[llvm-branch-commits] [mlir] [mlir][IR] Add listener notifications for pattern begin/end (PR #84131)
Matthias Springer via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Mar 7 21:09:57 PST 2024
================
@@ -68,9 +68,9 @@ class PatternApplicator {
/// invalidate the match and try another pattern.
LogicalResult
matchAndRewrite(Operation *op, PatternRewriter &rewriter,
- function_ref<bool(const Pattern &)> canApply = {},
- function_ref<void(const Pattern &)> onFailure = {},
- function_ref<LogicalResult(const Pattern &)> onSuccess = {});
+ std::function<bool(const Pattern &)> canApply = {},
+ std::function<void(const Pattern &)> onFailure = {},
+ std::function<LogicalResult(const Pattern &)> onSuccess = {});
----------------
matthias-springer wrote:
There is a `stack-use-after-scope` (reported by ASAN, also crashes in opt mode) with `function_ref`. The callback in the greedy pattern rewriter is defined inside of an `if` check:
```c++
function_ref<bool(const Pattern &)> canApply = {};
function_ref<void(const Pattern &)> onFailure = {};
function_ref<LogicalResult(const Pattern &)> onSuccess = {};
bool debugBuild = false;
#ifdef NDEBUG
debugBuild = true;
#endif // NDEBUG
if (debugBuild || config.listener) {
canApply = [&](const Pattern &pattern) {
if (this->config.listener) { /* ... */ }
// ...
}
// ...
}
// `canApply` points to a lambda that is out of scope.
LogicalResult matchResult =
matcher.matchAndRewrite(op, *this, canApply, onFailure, onSuccess);
```
`function_ref` is a "non-owning function wrapper", but the lambda captures `this`.
Changing to `std::function` is one way to fix it. I could also just always pass a lambda. That would actually be my preferred solution, but there is a slight overhead when running in opt mode and without listener because the callback would always be called (even if it does not do anything):
```c++
LogicalResult matchResult = matcher.matchAndRewrite(
op, *this,
/*canApply=*/[&](const Pattern &pattern) {
if (this->listener) { /* ... */ }
// ...
},
/*onFailure=*/[&](const Pattern &pattern) { /* ... */},
/*onSuccess=*/[&](const Pattern &pattern) { /* ... */});
```
What do you think?
https://github.com/llvm/llvm-project/pull/84131
More information about the llvm-branch-commits
mailing list