Skip to content

Commit 1a3abc2

Browse files
[mlir][bufferization][NFC] Remove yielded tensor analysis (#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.
1 parent 07151f0 commit 1a3abc2

File tree

4 files changed

+0
-105
lines changed

4 files changed

+0
-105
lines changed

mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -528,13 +528,6 @@ class AnalysisState {
528528
/// Return `true` if the given tensor has undefined contents.
529529
virtual bool hasUndefinedContents(OpOperand *opOperand) const;
530530

531-
/// Return true if the given tensor (or an aliasing tensor) is yielded from
532-
/// the containing block. Also include all aliasing tensors in the same block.
533-
///
534-
/// Note: In the absence of an analysis, an implementation may return true for
535-
/// any given tensor.
536-
virtual bool isTensorYielded(Value tensor) const;
537-
538531
/// Return a reference to the BufferizationOptions.
539532
const BufferizationOptions &getOptions() const { return options; }
540533

mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,6 @@ class OneShotAnalysisState : public AnalysisState {
101101
/// and store them in `undefinedTensorUses`.
102102
void gatherUndefinedTensorUses(Operation *op);
103103

104-
/// Find all tensors that are yielded/returned from a block and store them in
105-
/// `yieldedTensors`. Also include all aliasing tensors in the same block.
106-
void gatherYieldedTensors(Operation *op);
107-
108104
int64_t getStatNumTensorOutOfPlace() const { return statNumTensorOutOfPlace; }
109105
int64_t getStatNumTensorInPlace() const { return statNumTensorInPlace; }
110106

@@ -114,10 +110,6 @@ class OneShotAnalysisState : public AnalysisState {
114110
/// Return `true` if the given OpResult has been decided to bufferize inplace.
115111
bool isInPlace(OpOperand &opOperand) const override;
116112

117-
/// Return true if the given tensor (or an aliasing tensor) is yielded from
118-
/// the containing block. Also include all aliasing tensors in the same block.
119-
bool isTensorYielded(Value tensor) const override;
120-
121113
/// Return true if the buffer of the given tensor value is written to. Must
122114
/// not be called for values inside not yet analyzed functions.
123115
bool isValueWritten(Value value) const;
@@ -261,10 +253,6 @@ class OneShotAnalysisState : public AnalysisState {
261253
int64_t statNumTensorOutOfPlace = 0;
262254
int64_t statNumTensorInPlace = 0;
263255

264-
/// A set of all tensors (and maybe aliasing tensors) that yielded from a
265-
/// block.
266-
DenseSet<Value> yieldedTensors;
267-
268256
/// A set of uses of tensors that have undefined contents.
269257
DenseSet<OpOperand *> undefinedTensorUses;
270258

mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -628,53 +628,6 @@ bool AnalysisState::hasUndefinedContents(OpOperand *opOperand) const {
628628
return false;
629629
}
630630

631-
bool AnalysisState::isTensorYielded(Value tensor) const {
632-
// In the absence of analysis information, the conservative answer is "true".
633-
if (!tensor.getDefiningOp<AllocTensorOp>())
634-
return true;
635-
636-
// For AllocTensorOp results, we can do better: They do not alias with any
637-
// preceding value, so we can follow SSA use-def chains and do a simple
638-
// analysis.
639-
SmallVector<OpOperand *> worklist;
640-
DenseSet<OpOperand *> visited;
641-
for (OpOperand &use : tensor.getUses())
642-
worklist.push_back(&use);
643-
644-
while (!worklist.empty()) {
645-
OpOperand *operand = worklist.pop_back_val();
646-
if (visited.contains(operand))
647-
continue;
648-
visited.insert(operand);
649-
Operation *op = operand->getOwner();
650-
651-
// If the op is not bufferizable, we can safely assume that the value is not
652-
// yielded. (When bufferizing that op, it must handle such cases.)
653-
if (!options.dynCastBufferizableOp(op))
654-
continue;
655-
656-
// We cannot analyze through ToMemrefOps, so we have to conservatively
657-
// assume that the value is yielded.
658-
if (isa<ToMemrefOp>(op))
659-
return true;
660-
661-
// Check if the op is returning/yielding.
662-
if (isa<RegionBranchTerminatorOpInterface>(op))
663-
return true;
664-
665-
// Add all aliasing Values to the worklist.
666-
// Note: In the absence of detailed analysis information (e.g., there may be
667-
// no function call analysis information), this `getAliasingValues` is
668-
// conservative and may report additional Values as potentially aliasing.
669-
for (AliasingValue alias : getAliasingValues(*operand))
670-
for (OpOperand &use : alias.value.getUses())
671-
worklist.push_back(&use);
672-
}
673-
674-
// No ReturnLike op found: The value is not yielded.
675-
return false;
676-
}
677-
678631
// bufferization.to_memref is not allowed to change the rank.
679632
static void ensureToMemrefOpIsValid(Value tensor, Type memrefType) {
680633
#ifndef NDEBUG

mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -181,40 +181,6 @@ void OneShotAnalysisState::createAliasInfoEntry(Value v) {
181181
equivalentInfo.insert(v);
182182
}
183183

184-
// Gather yielded tensors in `yieldedTensors` by querying all aliases. This is
185-
// to ensure that such information is available during bufferization time.
186-
// Alias information can no longer be queried once we have started modifying
187-
// the IR.
188-
void OneShotAnalysisState::gatherYieldedTensors(Operation *op) {
189-
op->walk([&](Operation *returnOp) {
190-
if (!isa<RegionBranchTerminatorOpInterface>(returnOp) ||
191-
!getOptions().isOpAllowed(returnOp))
192-
return WalkResult::advance();
193-
194-
for (OpOperand &returnValOperand : returnOp->getOpOperands()) {
195-
Value returnVal = returnValOperand.get();
196-
// Skip non-tensor values.
197-
if (!isa<TensorType>(returnVal.getType()))
198-
continue;
199-
200-
// Add all aliases of the returned value. But only the ones that are in
201-
// the same block.
202-
applyOnAliases(returnVal, [&](Value v) {
203-
if (auto bbArg = dyn_cast<BlockArgument>(v)) {
204-
if (bbArg.getOwner()->getParentOp() == returnOp->getParentOp())
205-
yieldedTensors.insert(bbArg);
206-
return;
207-
}
208-
Operation *definingOp = v.getDefiningOp();
209-
if (definingOp->getParentOp() == returnOp->getParentOp())
210-
yieldedTensors.insert(v);
211-
});
212-
}
213-
214-
return WalkResult::advance();
215-
});
216-
}
217-
218184
void OneShotAnalysisState::gatherUndefinedTensorUses(Operation *op) {
219185
op->walk([&](Operation *op) {
220186
// Skip unknown ops.
@@ -246,10 +212,6 @@ bool OneShotAnalysisState::isInPlace(OpOperand &opOperand) const {
246212
return inplaceBufferized.contains(&opOperand);
247213
}
248214

249-
bool OneShotAnalysisState::isTensorYielded(Value tensor) const {
250-
return yieldedTensors.contains(tensor);
251-
}
252-
253215
bool OneShotAnalysisState::isValueWritten(Value value) const {
254216
bool isWritten = false;
255217
applyOnAliases(value, [&](Value val) {
@@ -1328,7 +1290,6 @@ LogicalResult bufferization::analyzeOp(Operation *op,
13281290
bool failedAnalysis = false;
13291291

13301292
// Gather some extra analysis data.
1331-
state.gatherYieldedTensors(op);
13321293
state.gatherUndefinedTensorUses(op);
13331294

13341295
// Analysis verification: After setting up alias/equivalence sets, each op

0 commit comments

Comments
 (0)