[Mlir-commits] [mlir] [mlir][bufferization] Remove allow-return-allocs and create-deallocs pass options, remove bufferization.escape attribute (PR #66619)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Mon Sep 18 02:04:01 PDT 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-linalg
<details>
<summary>Changes</summary>
This commit removes the deallocation capabilities of one-shot-bufferization. One-shot-bufferization should never deallocate any memrefs as this should be entirely handled by the ownership-based-buffer-deallocation pass going forward. This means the `allow-return-allocs` pass option will default to true now, `create-deallocs` defaults to false and they, as well as the escape attribute indicating whether a memref escapes the current region, will be removed. A new `allow-return-allocs-from-loops` option is added as a temporary workaround for some bufferization limitations.
Already reviewed in https://reviews.llvm.org/D156662
Depends on #<!-- -->66517
Thus, only review the top commit
---
Patch is 151.00 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/66619.diff
66 Files Affected:
- (modified) mlir/docs/Bufferization.md (+10-36)
- (modified) mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h (+1-15)
- (modified) mlir/include/mlir/Dialect/Bufferization/IR/BufferizationBase.td (-10)
- (modified) mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td (+1-2)
- (modified) mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h (+3-3)
- (modified) mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td (+6-17)
- (modified) mlir/include/mlir/Dialect/SparseTensor/Pipelines/Passes.h (+1-2)
- (modified) mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp (+4-57)
- (modified) mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp (-35)
- (modified) mlir/lib/Dialect/Bufferization/IR/BufferizationOps.cpp (-11)
- (modified) mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp (+2-3)
- (modified) mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp (+3-10)
- (modified) mlir/lib/Dialect/Bufferization/Transforms/EmptyTensorElimination.cpp (+1-1)
- (modified) mlir/lib/Dialect/Bufferization/Transforms/FuncBufferizableOpInterfaceImpl.cpp (+1-7)
- (modified) mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp (-78)
- (modified) mlir/lib/Dialect/Bufferization/Transforms/TensorCopyInsertion.cpp (-21)
- (modified) mlir/lib/Dialect/ControlFlow/Transforms/BufferizableOpInterfaceImpl.cpp (+1-6)
- (modified) mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp (+1-1)
- (modified) mlir/lib/Dialect/SCF/Transforms/BufferizableOpInterfaceImpl.cpp (+7-16)
- (modified) mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorConversion.cpp (-6)
- (modified) mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp (-8)
- (modified) mlir/lib/Dialect/SparseTensor/Transforms/SparsificationAndBufferizationPass.cpp (-3)
- (modified) mlir/lib/Dialect/Tensor/Transforms/BufferizableOpInterfaceImpl.cpp (+11-29)
- (modified) mlir/python/mlir/dialects/_bufferization_transform_ops_ext.py (+4-8)
- (modified) mlir/test/Dialect/Arith/one-shot-bufferize.mlir (+5-5)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-allow-return-allocs.mlir (+6-11)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-analysis-empty-tensor-elimination.mlir (+1-1)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-compat.mlir (+6-16)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-empty-tensor-elimination.mlir (+1-1)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-partial.mlir (+7-9)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-pass-statistics.mlir (-1)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize.mlir (-6)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize-allow-return-allocs.mlir (+6-6)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize-analysis.mlir (+4-4)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize-invalid.mlir (-147)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize-out-params.mlir (+3-11)
- (modified) mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize.mlir (+6-15)
- (modified) mlir/test/Dialect/Bufferization/Transforms/tensor-copy-insertion-memory-space.mlir (+3-3)
- (modified) mlir/test/Dialect/Bufferization/Transforms/tensor-copy-insertion.mlir (+9-18)
- (modified) mlir/test/Dialect/Bufferization/Transforms/transform-ops.mlir (-3)
- (modified) mlir/test/Dialect/Bufferization/invalid.mlir (-32)
- (modified) mlir/test/Dialect/ControlFlow/one-shot-bufferize-analysis.mlir (+1-1)
- (modified) mlir/test/Dialect/ControlFlow/one-shot-bufferize-invalid.mlir (+1-1)
- (modified) mlir/test/Dialect/ControlFlow/one-shot-bufferize.mlir (+2-2)
- (modified) mlir/test/Dialect/Linalg/one-shot-bufferize-analysis.mlir (+1-1)
- (modified) mlir/test/Dialect/Linalg/one-shot-bufferize.mlir (+5-7)
- (modified) mlir/test/Dialect/SCF/one-shot-bufferize-allow-return-allocs-no-deallocs.mlir (+1-4)
- (modified) mlir/test/Dialect/SCF/one-shot-bufferize-analysis.mlir (+4-4)
- (modified) mlir/test/Dialect/SCF/one-shot-bufferize-invalid.mlir (+1-1)
- (modified) mlir/test/Dialect/SCF/one-shot-bufferize-tensor-copy-insertion.mlir (+15-15)
- (modified) mlir/test/Dialect/SCF/one-shot-bufferize.mlir (+27-83)
- (modified) mlir/test/Dialect/SparseTensor/one_shot_bufferize_tensor_copy_insertion.mlir (+12-12)
- (modified) mlir/test/Dialect/SparseTensor/sparse_sddmm.mlir (+6-6)
- (modified) mlir/test/Dialect/Tensor/one-shot-bufferize-tensor-copy-insertion.mlir (+3-3)
- (modified) mlir/test/Dialect/Tensor/one-shot-bufferize.mlir (+5-43)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-collapse-tensor.mlir (+2-2)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-elementwise.mlir (+4-4)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-expand-tensor.mlir (+2-2)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-one-shot-bufferize.mlir (+1-1)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-padtensor.mlir (+3-2)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-subtensor-insert-multiple-uses.mlir (+4-2)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-subtensor-insert.mlir (+4-2)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-tensor-e2e.mlir (+2-2)
- (modified) mlir/test/Integration/Dialect/Linalg/CPU/test-tensor-matmul.mlir (+2-2)
- (modified) mlir/test/lib/Dialect/Bufferization/TestTensorCopyInsertion.cpp (+4-9)
- (modified) mlir/test/python/dialects/transform_bufferization_ext.py (+2-4)
``````````diff
diff --git a/mlir/docs/Bufferization.md b/mlir/docs/Bufferization.md
index 09bec06743c7a65..d9d0751cae8c9dd 100644
--- a/mlir/docs/Bufferization.md
+++ b/mlir/docs/Bufferization.md
@@ -266,42 +266,16 @@ must be inserted due to a RaW conflict. E.g.:
In the above example, a buffer copy of buffer(`%another_tensor`) (with `%cst`
inserted) is yielded from the "then" branch.
-In both examples, a buffer is allocated inside of a block and then yielded from
-the block. Deallocation of such buffers is tricky and not currently implemented
-in an efficient way. For this reason, One-Shot Bufferize must be explicitly
-configured with `allow-return-allocs` to support such IR.
-
-When running with `allow-return-allocs`, One-Shot Bufferize may introduce
-allocations that cannot be deallocated by One-Shot Bufferize yet. For that
-reason, `-buffer-deallocation` must be run after One-Shot Bufferize. This buffer
-deallocation pass resolves yields of newly allocated buffers with copies. E.g.,
-the `scf.if` example above would bufferize to IR similar to the following:
-
-```mlir
-%0 = scf.if %c -> (memref<?xf32>) {
- %1 = memref.alloc(...) : memref<?xf32>
- ...
- scf.yield %1 : memref<?xf32>
-} else {
- %2 = memref.alloc(...) : memref<?xf32>
- memref.copy %another_memref, %2
- scf.yield %2 : memref<?xf32>
-}
-```
-
-In the bufferized IR, both branches return a newly allocated buffer, so it does
-not matter which if-branch was taken. In both cases, the resulting buffer `%0`
-must be deallocated at some point after the `scf.if` (unless the `%0` is
-returned/yielded from its block).
-
-Note: Buffer allocations that are returned from a function are not deallocated,
-not even with `-buffer-deallocation`. It is the caller's responsibility to
-deallocate the buffer. In the future, this could be automated with allocation
-hoisting (across function boundaries) or reference counting.
-
-One-Shot Bufferize can be configured to leak all memory and not generate any
-buffer deallocations with `create-deallocs=0`. This can be useful for
-compatibility with legacy code that has its own method of deallocating buffers.
+Note: Buffer allocations that are returned from a function are not deallocated.
+It is the caller's responsibility to deallocate the buffer. For the full
+function boundary ABI for MemRefs w.r.t. buffer deallocation refer to the
+[*Function Boundary ABI*](#function-boundary-abi) section. In the future, this
+could be automated with allocation hoisting (across function boundaries) or
+reference counting.
+
+One-Shot Bufferize leaks all memory and does not generate any buffer
+deallocations. The `-buffer-deallocation-pipeline` has to be run afterwards to
+insert the deallocation operations.
## Ownership-based Buffer Deallocation
diff --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
index 9ec44dfd16a0c00..1c715f8b9a53ef3 100644
--- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
+++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
@@ -361,10 +361,6 @@ struct BufferizationOptions {
/// used.
UnknownTypeConverterFn unknownTypeConverterFn = nullptr;
- /// Specifies whether dealloc ops should be generated along with alloc ops. If
- /// not, new memory allocations will leak.
- bool createDeallocs = true;
-
/// Seed for the analysis fuzzer. If set to `0`, the fuzzer is deactivated.
/// Should be used only with `testAnalysisOnly = true`.
unsigned analysisFuzzerSeed = 0;
@@ -588,13 +584,9 @@ class AnalysisState {
/// undefined contents is allocated.
FailureOr<Value>
allocateTensorForShapedValue(OpBuilder &b, Location loc, Value shapedValue,
- bool escape, const BufferizationOptions &options,
+ const BufferizationOptions &options,
bool copy = true);
-/// Return `true` if the allocation of the given op is guaranteed to not escape
-/// the containing block.
-bool allocationDoesNotEscape(OpResult opResult);
-
/// Lookup the buffer for the given value. If the value was not bufferized
/// yet, wrap it in a ToMemrefOp. Otherwise, it is the result of a ToTensorOp,
/// from which the memref operand is returned.
@@ -641,12 +633,6 @@ OpTy replaceOpWithNewBufferizedOp(RewriterBase &rewriter, Operation *op,
return newOp;
}
-/// Return `true` if the buffer of given OpResult should be deallocated. This
-/// function should be called during `BufferizableOpInterface::bufferize`
-/// implementations that allocate a new buffer for the given OpResult.
-bool shouldDeallocateOpResult(OpResult opResult,
- const BufferizationOptions &options);
-
/// Return a MemRefType to which the type of the given value can be bufferized.
///
/// If possible, op bufferization implementations should not use this function
diff --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationBase.td b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationBase.td
index e9c140859344ef8..0d509e69349e918 100644
--- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationBase.td
+++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizationBase.td
@@ -60,16 +60,6 @@ def Bufferization_Dialect : Dialect {
/// arguments during One-Shot Module Bufferize.
constexpr const static ::llvm::StringLiteral
kBufferLayoutAttrName = "bufferization.buffer_layout";
-
- /// Attribute name used to mark escaping behavior of buffer allocations.
- /// Escaping allocations cannot be deallocated in the same block and must
- /// be treated specially: They are currently deallocated with the
- /// BufferDeallocation pass.
- ///
- /// Note: Only ops with at least one OpResult that bufferizes to a buffer
- /// allocation (as per BufferizableOpInterface) may have this attribute.
- constexpr const static ::llvm::StringLiteral
- kEscapeAttrName = "bufferization.escape";
}];
let hasOperationAttrVerify = 1;
}
diff --git a/mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td b/mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td
index 84bd047e6d51eed..a0eb5ff00cb9fea 100644
--- a/mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td
+++ b/mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td
@@ -82,10 +82,9 @@ def OneShotBufferizeOp
let arguments = (
ins TransformHandleTypeInterface:$target,
OptionalAttr<LayoutMapOption>:$function_boundary_type_conversion,
- DefaultValuedAttr<BoolAttr, "false">:$allow_return_allocs,
+ DefaultValuedAttr<BoolAttr, "false">:$allow_return_allocs_from_loops,
DefaultValuedAttr<BoolAttr, "false">:$allow_unknown_ops,
DefaultValuedAttr<BoolAttr, "false">:$bufferize_function_boundaries,
- DefaultValuedAttr<BoolAttr, "true">:$create_deallocs,
DefaultValuedAttr<BoolAttr, "false">:$test_analysis_only,
DefaultValuedAttr<BoolAttr, "false">:$print_conflicts,
DefaultValuedAttr<StrAttr, "\"memref.copy\"">:$memcpy_op);
diff --git a/mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h b/mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h
index 585c7ca92c71895..328aff07280a92b 100644
--- a/mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h
+++ b/mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h
@@ -28,9 +28,9 @@ struct OneShotBufferizationOptions : public BufferizationOptions {
OneShotBufferizationOptions() = default;
- /// Specifies whether returning newly allocated memrefs should be allowed.
- /// Otherwise, a pass failure is triggered.
- bool allowReturnAllocs = false;
+ /// Specifies whether returning newly allocated memrefs from loops should be
+ /// allowed. Otherwise, a pass failure is triggered.
+ bool allowReturnAllocsFromLoops = false;
/// Specifies whether the tensor IR should be annotated with alias sets.
bool dumpAliasSets = false;
diff --git a/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td b/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td
index f3c2a29c0589f29..62383e376f6f7a3 100644
--- a/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td
@@ -387,15 +387,9 @@ def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
example, `tensor.generate` is not in destination-passing style and always
results in a new buffer allocation.
- One-Shot Bufferize deallocates all buffers that it allocates. Yielding newly
- allocated buffers from a block can lead to bad performance because
- additional buffer copies are often needed to make sure that every buffer
- allocation is also deallocated again. By default, such IR is rejected by
- One-Shot Bufferize. Such IR can be allowed with `allow-return-allocs`. In
- that case, the `-buffer-deallocation` pass should be run after One-Shot
- Bufferize. Note that new buffer allocations that are returned from a
- function can currently not be deallocated by `-buffer-deallocation` and
- leak.
+ One-Shot Bufferize does not deallocate any buffers that it allocates. The
+ `-buffer-deallocation` pass should be run after One-Shot Bufferize to insert
+ the deallocation operations necessary to eliminate memory leaks.
One-Shot Bufferize will by default reject IR that contains non-bufferizable
op, i.e., ops that do not implemement BufferizableOpInterface. Such IR can
@@ -462,9 +456,9 @@ def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
`test-analysis-only`.
}];
let options = [
- Option<"allowReturnAllocs", "allow-return-allocs", "bool",
- /*default=*/"false",
- "Allows returning/yielding new allocations from a block.">,
+ Option<"allowReturnAllocsFromLoops", "allow-return-allocs-from-loops",
+ "bool", /*default=*/"false",
+ "Allows returning/yielding new allocations from a loop.">,
Option<"allowUnknownOps", "allow-unknown-ops", "bool",
/*default=*/"false",
"Allows unknown (not bufferizable) ops in the input IR.">,
@@ -479,9 +473,6 @@ def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
"Bufferize function boundaries (experimental).">,
Option<"copyBeforeWrite", "copy-before-write", "bool", /*default=*/"false",
"Skip the analysis. Make a buffer copy on every write.">,
- Option<"createDeallocs", "create-deallocs", "bool", /*default=*/"true",
- "Specify if buffers should be deallocated. For compatibility with "
- "core bufferization passes.">,
ListOption<"dialectFilter", "dialect-filter", "std::string",
"Restrict bufferization to ops from these dialects.">,
Option<"dumpAliasSets", "dump-alias-sets", "bool", /*default=*/"false",
@@ -513,8 +504,6 @@ def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
let statistics = [
Statistic<"numBufferAlloc", "num-buffer-alloc",
"Number of buffer allocations">,
- Statistic<"numBufferDealloc", "num-buffer-dealloc",
- "Number of buffer deallocations">,
Statistic<"numTensorInPlace", "num-tensor-in-place",
"Number of in-place tensor OpOperands">,
Statistic<"numTensorOutOfPlace", "num-tensor-out-of-place",
diff --git a/mlir/include/mlir/Dialect/SparseTensor/Pipelines/Passes.h b/mlir/include/mlir/Dialect/SparseTensor/Pipelines/Passes.h
index 71fcfc84919eb5c..c88963d399c4c92 100644
--- a/mlir/include/mlir/Dialect/SparseTensor/Pipelines/Passes.h
+++ b/mlir/include/mlir/Dialect/SparseTensor/Pipelines/Passes.h
@@ -93,8 +93,7 @@ struct SparseCompilerOptions
desc("Specify if the temporary buffers created by the sparse "
"compiler should be deallocated. For compatibility with core "
"bufferization passes. "
- "This option is only used when enable-runtime-library=false. "
- "See also create-deallocs for BufferizationOption."),
+ "This option is only used when enable-runtime-library=false."),
init(true)};
PassOptions::Option<int32_t> vectorLength{
diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
index 2e549b0335688cb..57cd303d2076e73 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
@@ -140,27 +140,11 @@ Operation *bufferization::getOwnerOfValue(Value value) {
return llvm::cast<BlockArgument>(value).getOwner()->getParentOp();
}
-bool bufferization::allocationDoesNotEscape(OpResult opResult) {
-#ifndef NDEBUG
- auto bufferizableOp = opResult.getDefiningOp<BufferizableOpInterface>();
- assert(bufferizableOp && bufferizableOp.bufferizesToAllocation(opResult) &&
- "expected op that bufferizes to an allocation");
-#endif // NDEBUG
-
- Operation *op = opResult.getDefiningOp();
- // If there is no 'escape' attribute, we cannot say for sure.
- if (!op->hasAttr(BufferizationDialect::kEscapeAttrName))
- return false;
- auto attr =
- op->getAttrOfType<ArrayAttr>(BufferizationDialect::kEscapeAttrName);
- return !llvm::cast<BoolAttr>(attr[opResult.getResultNumber()]).getValue();
-}
-
/// Create an AllocTensorOp for the given shaped value. If `copy` is set, the
/// shaped value is copied. Otherwise, a tensor with undefined contents is
/// allocated.
FailureOr<Value> bufferization::allocateTensorForShapedValue(
- OpBuilder &b, Location loc, Value shapedValue, bool escape,
+ OpBuilder &b, Location loc, Value shapedValue,
const BufferizationOptions &options, bool copy) {
Value tensor;
if (llvm::isa<RankedTensorType>(shapedValue.getType())) {
@@ -202,8 +186,6 @@ FailureOr<Value> bufferization::allocateTensorForShapedValue(
// Create AllocTensorOp.
auto allocTensorOp = b.create<AllocTensorOp>(loc, tensorType, dynamicSizes,
copy ? tensor : Value());
- allocTensorOp->setAttr(BufferizationDialect::kEscapeAttrName,
- b.getBoolArrayAttr({escape}));
// Add 'memory_space' attribute. Not needed if 'copy' operand is specified.
if (copy)
@@ -224,10 +206,8 @@ LogicalResult BufferizableOpInterface::resolveTensorOpOperandConflicts(
Operation *op = getOperation();
SmallVector<OpOperand *> outOfPlaceOpOperands;
DenseSet<OpOperand *> copiedOpOperands;
- DenseSet<OpOperand *> escapingOpOperandCopies;
SmallVector<Value> outOfPlaceValues;
DenseSet<Value> copiedOpValues;
- DenseSet<Value> escapingValueCopies;
// Find all out-of-place OpOperands.
for (OpOperand &opOperand : op->getOpOperands()) {
@@ -243,11 +223,6 @@ LogicalResult BufferizableOpInterface::resolveTensorOpOperandConflicts(
// Is the result yielded from a block? Or are deallocations turned off
// entirely? In either case, mark the allocation as "escaping", so that it
// will not be deallocated.
- bool escape = !state.getOptions().createDeallocs ||
- llvm::any_of(aliasingValues, [&](AliasingValue a) {
- return state.isTensorYielded(a.value);
- });
-
if (aliasingValues.getNumAliases() == 1 &&
isa<OpResult>(aliasingValues.getAliases()[0].value) &&
!state.bufferizesToMemoryWrite(opOperand) &&
@@ -265,15 +240,11 @@ LogicalResult BufferizableOpInterface::resolveTensorOpOperandConflicts(
outOfPlaceValues.push_back(value);
if (!state.canOmitTensorCopy(opOperand))
copiedOpValues.insert(value);
- if (escape)
- escapingValueCopies.insert(value);
} else {
// In all other cases, make a copy of the OpOperand.
outOfPlaceOpOperands.push_back(&opOperand);
if (!state.canOmitTensorCopy(opOperand))
copiedOpOperands.insert(&opOperand);
- if (escape)
- escapingOpOperandCopies.insert(&opOperand);
}
}
@@ -281,8 +252,7 @@ LogicalResult BufferizableOpInterface::resolveTensorOpOperandConflicts(
rewriter.setInsertionPoint(op);
for (OpOperand *opOperand : outOfPlaceOpOperands) {
FailureOr<Value> copy = allocateTensorForShapedValue(
- rewriter, op->getLoc(), opOperand->get(),
- escapingOpOperandCopies.contains(opOperand), state.getOptions(),
+ rewriter, op->getLoc(), opOperand->get(), state.getOptions(),
copiedOpOperands.contains(opOperand));
if (failed(copy))
return failure();
@@ -293,8 +263,8 @@ LogicalResult BufferizableOpInterface::resolveTensorOpOperandConflicts(
rewriter.setInsertionPointAfter(op);
for (Value value : outOfPlaceValues) {
FailureOr<Value> copy = allocateTensorForShapedValue(
- rewriter, op->getLoc(), value, escapingValueCopies.contains(value),
- state.getOptions(), copiedOpValues.count(value));
+ rewriter, op->getLoc(), value, state.getOptions(),
+ copiedOpValues.count(value));
if (failed(copy))
return failure();
SmallVector<OpOperand *> uses = llvm::to_vector(
@@ -314,29 +284,6 @@ LogicalResult BufferizableOpInterface::resolveTensorOpOperandConflicts(
return success();
}
-bool bufferization::shouldDeallocateOpResult(
- OpResult opResult, const BufferizationOptions &options) {
- Operation *op = opResult.getOwner();
- assert(options.dynCastBufferizableOp(op).bufferizesToAllocation(opResult) &&
- "expected that op allocates");
-
- AnalysisState analysisState(options);
- if (op->hasAttr(BufferizationDialect::kEscapeAttrName)) {
- // AllocTensorOp has one result.
- ArrayAttr escapeAttr = llvm::cast<ArrayAttr>(
- op->getAttr(BufferizationDialect::kEscapeAttrName));
- return !llvm::cast<BoolAttr>(escapeAttr[0]).getValue();
- }
-
- // No "escape" annotation found.
- if (options.createDeallocs) {
- // Perform an ad-hoc analysis.
- return !analysisState.isTensorYielded(opResult);
- }
-
- return false;
-}
-
//===----------------------------------------------------------------------===//
// OpFilter
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp b/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
index 2805e9a43e446f7..802bd52269419b4 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizationDialect.cpp
@@ -28,9 +28,6 @@ constexpr const ::llvm::StringLiteral BufferizationDialect::kWritableAttrName;
constexpr const ::llvm::StringLiteral
BufferizationDialect::kBufferLayoutAttrName;
-/// Attribute name used to mark escaping behavior of buffer allocations.
-constexpr const ::llvm::StringLiteral BufferizationDialect::kEscapeAttrName;
-
//===----------------------------------------------------------------------===//
// Bufferization Dialect Interfaces
//===----------------------------------------------------------------------===//
@@ -108,38 +105,6 @@ BufferizationDialect::verifyOperationAttribute(Operation *op,
NamedAttribute attr) {
using bufferization::BufferizableOpInterface;
- if (attr.getName() == kEscapeAttrName) {
- auto arrayAttr = llvm::dyn_cast<ArrayAttr>(attr.getValue());
- if (!arrayAttr)
- return op->emitError() << "'" << kEscapeAttrName
- << "' is expected to be a bool array attribute";
- if (arrayAttr.size() != op->getNumResults())
- return op->emitError()
- << "'" << kEscapeAttrName
- << "' has wrong number of elements, expected "
- << op->getNumResults() << ", got " << arrayAttr.size();
- auto bufferizableOp = dyn_cast<BufferizableOpInterface>(op);
- if (!bufferizableOp)
- return op->emitError()
- << "'" << kEscapeAttrName << "' only valid on bufferizable ops";
- for (const auto &it : llvm::enumerate(arrayAttr)) {
- auto attr = it.value();
- auto boolAttr = llvm::dyn_cast<BoolAttr>(attr);
- if (!boolAttr)
- return op->emitError() << "'" << kEscapeAttrName
- << "' is expected to be a bool array attribute";
- if (!b...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/66619
More information about the Mlir-commits
mailing list