[Mlir-commits] [mlir] [mlir][bufferization][NFC] Remove yielded tensor analysis (PR #67126)
Matthias Springer
llvmlistbot at llvm.org
Fri Sep 22 05:39:31 PDT 2023
https://github.com/matthias-springer created https://github.com/llvm/llvm-project/pull/67126
Remove the yielded tensor analysis. This analysis was used to detect cases where One-Shot Bufferize cannot deallocate buffers. Deallocation has recently been removed from One-Shot Bufferize. Buffers are now deallocated by the buffer deallocation pass. This analysis is no longer needed.
>From 0762fcc65d594f4f5e6697aaaad5982c2754b927 Mon Sep 17 00:00:00 2001
From: Matthias Springer <me at m-sp.org>
Date: Fri, 22 Sep 2023 14:37:27 +0200
Subject: [PATCH] [mlir][bufferization][NFC] Remove yielded tensor analysis
Remove the yielded tensor analysis. This analysis was used to detect cases where One-Shot Bufferize cannot deallocate buffers. Deallocation has recently been removed from One-Shot Bufferize (and delegated to the buffer deallocation pass) and this analysis is no longer needed.
BEGIN_PUBLIC
No public commit message needed for presubmit.
END_PUBLIC
---
.../IR/BufferizableOpInterface.h | 7 ---
.../Transforms/OneShotAnalysis.h | 12 -----
.../IR/BufferizableOpInterface.cpp | 47 -------------------
.../Transforms/OneShotAnalysis.cpp | 39 ---------------
4 files changed, 105 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
index 1c715f8b9a53ef3..8859f6e2a5bcaf9 100644
--- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
+++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h
@@ -528,13 +528,6 @@ class AnalysisState {
/// Return `true` if the given tensor has undefined contents.
virtual bool hasUndefinedContents(OpOperand *opOperand) const;
- /// Return true if the given tensor (or an aliasing tensor) is yielded from
- /// the containing block. Also include all aliasing tensors in the same block.
- ///
- /// Note: In the absence of an analysis, an implementation may return true for
- /// any given tensor.
- virtual bool isTensorYielded(Value tensor) const;
-
/// Return a reference to the BufferizationOptions.
const BufferizationOptions &getOptions() const { return options; }
diff --git a/mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h b/mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h
index 328aff07280a92b..a29af853eb21ba6 100644
--- a/mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h
+++ b/mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h
@@ -101,10 +101,6 @@ class OneShotAnalysisState : public AnalysisState {
/// and store them in `undefinedTensorUses`.
void gatherUndefinedTensorUses(Operation *op);
- /// Find all tensors that are yielded/returned from a block and store them in
- /// `yieldedTensors`. Also include all aliasing tensors in the same block.
- void gatherYieldedTensors(Operation *op);
-
int64_t getStatNumTensorOutOfPlace() const { return statNumTensorOutOfPlace; }
int64_t getStatNumTensorInPlace() const { return statNumTensorInPlace; }
@@ -114,10 +110,6 @@ class OneShotAnalysisState : public AnalysisState {
/// Return `true` if the given OpResult has been decided to bufferize inplace.
bool isInPlace(OpOperand &opOperand) const override;
- /// Return true if the given tensor (or an aliasing tensor) is yielded from
- /// the containing block. Also include all aliasing tensors in the same block.
- bool isTensorYielded(Value tensor) const override;
-
/// Return true if the buffer of the given tensor value is written to. Must
/// not be called for values inside not yet analyzed functions.
bool isValueWritten(Value value) const;
@@ -261,10 +253,6 @@ class OneShotAnalysisState : public AnalysisState {
int64_t statNumTensorOutOfPlace = 0;
int64_t statNumTensorInPlace = 0;
- /// A set of all tensors (and maybe aliasing tensors) that yielded from a
- /// block.
- DenseSet<Value> yieldedTensors;
-
/// A set of uses of tensors that have undefined contents.
DenseSet<OpOperand *> undefinedTensorUses;
diff --git a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
index 57cd303d2076e73..837b22b4a82a396 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
@@ -628,53 +628,6 @@ bool AnalysisState::hasUndefinedContents(OpOperand *opOperand) const {
return false;
}
-bool AnalysisState::isTensorYielded(Value tensor) const {
- // In the absence of analysis information, the conservative answer is "true".
- if (!tensor.getDefiningOp<AllocTensorOp>())
- return true;
-
- // For AllocTensorOp results, we can do better: They do not alias with any
- // preceding value, so we can follow SSA use-def chains and do a simple
- // analysis.
- SmallVector<OpOperand *> worklist;
- DenseSet<OpOperand *> visited;
- for (OpOperand &use : tensor.getUses())
- worklist.push_back(&use);
-
- while (!worklist.empty()) {
- OpOperand *operand = worklist.pop_back_val();
- if (visited.contains(operand))
- continue;
- visited.insert(operand);
- Operation *op = operand->getOwner();
-
- // If the op is not bufferizable, we can safely assume that the value is not
- // yielded. (When bufferizing that op, it must handle such cases.)
- if (!options.dynCastBufferizableOp(op))
- continue;
-
- // We cannot analyze through ToMemrefOps, so we have to conservatively
- // assume that the value is yielded.
- if (isa<ToMemrefOp>(op))
- return true;
-
- // Check if the op is returning/yielding.
- if (isa<RegionBranchTerminatorOpInterface>(op))
- return true;
-
- // Add all aliasing Values to the worklist.
- // Note: In the absence of detailed analysis information (e.g., there may be
- // no function call analysis information), this `getAliasingValues` is
- // conservative and may report additional Values as potentially aliasing.
- for (AliasingValue alias : getAliasingValues(*operand))
- for (OpOperand &use : alias.value.getUses())
- worklist.push_back(&use);
- }
-
- // No ReturnLike op found: The value is not yielded.
- return false;
-}
-
// bufferization.to_memref is not allowed to change the rank.
static void ensureToMemrefOpIsValid(Value tensor, Type memrefType) {
#ifndef NDEBUG
diff --git a/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp b/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp
index 09205388a644720..1c85dbb5688be4b 100644
--- a/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp
+++ b/mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp
@@ -181,40 +181,6 @@ void OneShotAnalysisState::createAliasInfoEntry(Value v) {
equivalentInfo.insert(v);
}
-// Gather yielded tensors in `yieldedTensors` by querying all aliases. This is
-// to ensure that such information is available during bufferization time.
-// Alias information can no longer be queried once we have started modifying
-// the IR.
-void OneShotAnalysisState::gatherYieldedTensors(Operation *op) {
- op->walk([&](Operation *returnOp) {
- if (!isa<RegionBranchTerminatorOpInterface>(returnOp) ||
- !getOptions().isOpAllowed(returnOp))
- return WalkResult::advance();
-
- for (OpOperand &returnValOperand : returnOp->getOpOperands()) {
- Value returnVal = returnValOperand.get();
- // Skip non-tensor values.
- if (!isa<TensorType>(returnVal.getType()))
- continue;
-
- // Add all aliases of the returned value. But only the ones that are in
- // the same block.
- applyOnAliases(returnVal, [&](Value v) {
- if (auto bbArg = dyn_cast<BlockArgument>(v)) {
- if (bbArg.getOwner()->getParentOp() == returnOp->getParentOp())
- yieldedTensors.insert(bbArg);
- return;
- }
- Operation *definingOp = v.getDefiningOp();
- if (definingOp->getParentOp() == returnOp->getParentOp())
- yieldedTensors.insert(v);
- });
- }
-
- return WalkResult::advance();
- });
-}
-
void OneShotAnalysisState::gatherUndefinedTensorUses(Operation *op) {
op->walk([&](Operation *op) {
// Skip unknown ops.
@@ -246,10 +212,6 @@ bool OneShotAnalysisState::isInPlace(OpOperand &opOperand) const {
return inplaceBufferized.contains(&opOperand);
}
-bool OneShotAnalysisState::isTensorYielded(Value tensor) const {
- return yieldedTensors.contains(tensor);
-}
-
bool OneShotAnalysisState::isValueWritten(Value value) const {
bool isWritten = false;
applyOnAliases(value, [&](Value val) {
@@ -1328,7 +1290,6 @@ LogicalResult bufferization::analyzeOp(Operation *op,
bool failedAnalysis = false;
// Gather some extra analysis data.
- state.gatherYieldedTensors(op);
state.gatherUndefinedTensorUses(op);
// Analysis verification: After setting up alias/equivalence sets, each op
More information about the Mlir-commits
mailing list