-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[mlir][bufferization] Buffer deallocation: skip ops that do not operate on buffers #75126
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
Closed
matthias-springer
wants to merge
1
commit into
llvm:main
from
matthias-springer:buffer_deallocation_skip_non_buffer_ops
Closed
[mlir][bufferization] Buffer deallocation: skip ops that do not operate on buffers #75126
matthias-springer
wants to merge
1
commit into
llvm:main
from
matthias-springer:buffer_deallocation_skip_non_buffer_ops
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@llvm/pr-subscribers-mlir-bufferization @llvm/pr-subscribers-mlir Author: Matthias Springer (matthias-springer) ChangesSkip ops that do not operate on buffers during ownership-based buffer deallocation. Such ops can be ignored during buffer deallocation. (Except for terminators.) Full diff: https://github.com/llvm/llvm-project/pull/75126.diff 2 Files Affected:
diff --git a/mlir/lib/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation.cpp b/mlir/lib/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation.cpp
index 38ffae68a43de..f9ec6564995c8 100644
--- a/mlir/lib/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation.cpp
+++ b/mlir/lib/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation.cpp
@@ -48,6 +48,19 @@ static Value buildBoolValue(OpBuilder &builder, Location loc, bool value) {
static bool isMemref(Value v) { return v.getType().isa<BaseMemRefType>(); }
+/// Return "true" if the given op has buffer semantics. I.e., it has buffer
+/// operands, buffer results and/or buffer region entry block arguments.
+static bool hasBufferSemantics(Operation *op) {
+ if (llvm::any_of(op->getOperands(), isMemref) ||
+ llvm::any_of(op->getResults(), isMemref))
+ return true;
+ for (Region ®ion : op->getRegions())
+ if (!region.empty())
+ if (llvm::any_of(region.front().getArguments(), isMemref))
+ return true;
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Backedges analysis
//===----------------------------------------------------------------------===//
@@ -462,31 +475,6 @@ BufferDeallocation::materializeUniqueOwnership(OpBuilder &builder, Value memref,
return state.getMemrefWithUniqueOwnership(builder, memref, block);
}
-static bool regionOperatesOnMemrefValues(Region ®ion) {
- auto checkBlock = [](Block *block) {
- if (llvm::any_of(block->getArguments(), isMemref))
- return WalkResult::interrupt();
- for (Operation &op : *block) {
- if (llvm::any_of(op.getOperands(), isMemref))
- return WalkResult::interrupt();
- if (llvm::any_of(op.getResults(), isMemref))
- return WalkResult::interrupt();
- }
- return WalkResult::advance();
- };
- WalkResult result = region.walk(checkBlock);
- if (result.wasInterrupted())
- return true;
-
- // Note: Block::walk/Region::walk visits only blocks that are nested under
- // nested operations, but not direct children.
- for (Block &block : region)
- if (checkBlock(&block).wasInterrupted())
- return true;
-
- return false;
-}
-
LogicalResult
BufferDeallocation::verifyFunctionPreconditions(FunctionOpInterface op) {
// (1) Ensure that there are supported loops only (no explicit control flow
@@ -512,9 +500,8 @@ LogicalResult BufferDeallocation::verifyOperationPreconditions(Operation *op) {
size_t size = regions.size();
if (((size == 1 && !op->getResults().empty()) || size > 1) &&
!dyn_cast<RegionBranchOpInterface>(op)) {
- if (llvm::any_of(regions, regionOperatesOnMemrefValues))
- return op->emitError("All operations with attached regions need to "
- "implement the RegionBranchOpInterface.");
+ return op->emitError("All operations with attached regions need to "
+ "implement the RegionBranchOpInterface.");
}
// (2) The pass does not work properly when deallocations are already present.
@@ -648,6 +635,11 @@ LogicalResult BufferDeallocation::deallocate(Block *block) {
// For each operation in the block, handle the interfaces that affect aliasing
// and ownership of memrefs.
for (Operation &op : llvm::make_early_inc_range(*block)) {
+ // Skip ops that do not operate on buffers and are not terminators.
+ // (bufferization.dealloc ops are inserted in front of terminators, so
+ // terminators cannot be skipped.)
+ if (!op.hasTrait<OpTrait::IsTerminator>() && !hasBufferSemantics(&op))
+ continue;
FailureOr<Operation *> result = handleAllInterfaces(&op);
if (failed(result))
return failure();
diff --git a/mlir/test/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation/dealloc-region-branchop-interface.mlir b/mlir/test/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation/dealloc-region-branchop-interface.mlir
index 1a8a930bc9002..f44b6d74051e2 100644
--- a/mlir/test/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation/dealloc-region-branchop-interface.mlir
+++ b/mlir/test/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation/dealloc-region-branchop-interface.mlir
@@ -545,10 +545,9 @@ func.func @noRegionBranchOpInterface() {
// -----
// Test Case: The op "test.bar" does not implement the RegionBranchOpInterface.
-// This is not allowed in buffer deallocation.
+// But it also does not operate on buffers, so we don't care.
func.func @noRegionBranchOpInterface() {
- // expected-error@+1 {{All operations with attached regions need to implement the RegionBranchOpInterface.}}
%0 = "test.bar"() ({
%2 = "test.get_memref"() : () -> memref<2xi32>
%3 = "test.foo"(%2) : (memref<2xi32>) -> (i32)
|
joker-eph
reviewed
Dec 12, 2023
mlir/lib/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation.cpp
Show resolved
Hide resolved
…te on buffers Skip ops that do not operate on buffers during ownership-based buffer deallocation. Such ops can be ignored during buffer deallocation. (Except for terminators.)
9da3a82
to
ef53714
Compare
Closing this PR and putting everything in #75127. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Skip ops that do not operate on buffers during ownership-based buffer deallocation. Such ops can be ignored during buffer deallocation. (Except for terminators.)