[Mlir-commits] [mlir] 81e8c39 - [mlir][linalg][bufferize][NFC] Add bufferizesToAliasOnly
Matthias Springer
llvmlistbot at llvm.org
Sun Oct 31 01:06:58 PDT 2021
Author: Matthias Springer
Date: 2021-10-31T17:06:39+09:00
New Revision: 81e8c391fc05f394eb99871a177bfef40903d9c5
URL: https://github.com/llvm/llvm-project/commit/81e8c391fc05f394eb99871a177bfef40903d9c5
DIFF: https://github.com/llvm/llvm-project/commit/81e8c391fc05f394eb99871a177bfef40903d9c5.diff
LOG: [mlir][linalg][bufferize][NFC] Add bufferizesToAliasOnly
The list of operations that do neither read nor write, but create an alias when bufferizing inplace, is getting longer. This commit adds a helper function so that we do not have to spell out the entire list each time.
Differential Revision: https://reviews.llvm.org/D112515
Added:
Modified:
mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp
Removed:
################################################################################
diff --git a/mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp b/mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp
index 0c383de9b504..0373867ee1b6 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/ComprehensiveBufferize.cpp
@@ -626,6 +626,18 @@ static OpResult getAliasingOpResult(OpOperand &opOperand) {
[&](Operation *op) { return getInplaceableOpResult(opOperand); });
}
+/// Return `true` if the given OpOperand does not bufferize to a memory read or
+/// write, but creates an alias when bufferized inplace.
+static bool bufferizesToAliasOnly(OpOperand &opOperand) {
+ Operation *owner = opOperand.getOwner();
+ // TODO: In the future this may need to evolve into a TypeSwitch. For all
+ // currently supported ops, the aliasing-only OpOperand is always the first
+ // one.
+ return isa<ExtractSliceOp, TensorCollapseShapeOp, TensorExpandShapeOp,
+ tensor::CastOp>(owner) &&
+ &opOperand == &owner->getOpOperand(0);
+}
+
// Predeclaration of function.
static bool bufferizesToMemoryRead(OpOperand &opOperand);
@@ -640,8 +652,8 @@ static bool isValueRead(Value value) {
while (!workingSet.empty()) {
OpOperand *uMaybeReading = workingSet.pop_back_val();
// Skip over all ops that create an alias but do not read.
- if (isa<ExtractSliceOp, tensor::CastOp>(uMaybeReading->getOwner()))
- for (OpOperand &use : uMaybeReading->getOwner()->getResult(0).getUses())
+ if (bufferizesToAliasOnly(*uMaybeReading))
+ for (OpOperand &use : getAliasingOpResult(*uMaybeReading).getUses())
workingSet.push_back(&use);
if (bufferizesToMemoryRead(*uMaybeReading))
return true;
@@ -658,7 +670,7 @@ static bool bufferizesToMemoryRead(OpOperand &opOperand) {
return true;
// Some ops alone do not bufferize to a memory read, but one of their uses
// may.
- if (isa<ExtractSliceOp, tensor::CastOp>(opOperand.getOwner()))
+ if (bufferizesToAliasOnly(opOperand))
return false;
// scf::ForOp alone doesn't bufferize to a memory read, one of the uses of its
// matching bbArg may.
@@ -690,7 +702,7 @@ static bool bufferizesToMemoryWrite(OpOperand &opOperand) {
return false;
// Some ops alone do not bufferize to a memory write, but one of their uses
// may.
- if (isa<ExtractSliceOp, tensor::CastOp>(opOperand.getOwner()))
+ if (bufferizesToAliasOnly(opOperand))
return false;
// CallOpInterface alone doesn't bufferize to a memory write, one of the uses
// of the matching bbArg may. It is the responsibility of the caller to
@@ -2318,9 +2330,8 @@ bufferizableInPlaceAnalysisImpl(OpOperand &operand, OpResult result,
return success();
}
-/// This analysis function is used for ops where the first OpOperand aliases
-/// with the first OpResult, without creating a read or write. There are a few
-/// ops besides ExtractSliceOp that have such semantics.
+/// This analysis function is used for OpOperands that alias with an OpResult
+/// but are not inplaceable on it. E.g., ExtractSliceOp.
///
/// Rationale for bufferizing `%1 = tensor.extract_slice %0[...]` inplace:
///
@@ -2335,11 +2346,12 @@ bufferizableInPlaceAnalysisImpl(OpOperand &operand, OpResult result,
/// An analysis is required to ensure inplace bufferization would not result in
/// RaW dependence violations.
static LogicalResult
-bufferizableInPlaceAnalysisAliasOnlyOp(Operation *op,
+bufferizableInPlaceAnalysisAliasOnlyOp(OpOperand &operand,
BufferizationAliasInfo &aliasInfo,
const DominanceInfo &domInfo) {
- return bufferizableInPlaceAnalysisImpl(
- op->getOpOperand(0), op->getOpResult(0), aliasInfo, domInfo);
+ OpResult result = getAliasingOpResult(operand);
+ assert(result && "expected that the OpOperand has an aliasing OpResult");
+ return bufferizableInPlaceAnalysisImpl(operand, result, aliasInfo, domInfo);
}
/// Determine if `operand` can be bufferized in-place with one of the op's
@@ -2372,16 +2384,17 @@ LogicalResult mlir::linalg::inPlaceAnalysis(SmallVector<Operation *> &ops,
// Walk ops in reverse for better interference analysis.
for (Operation *op : reverse(ops)) {
- for (OpOperand &opOperand : op->getOpOperands())
+ for (OpOperand &opOperand : op->getOpOperands()) {
if (failed(bufferizableInPlaceAnalysis(opOperand, aliasInfo, domInfo)))
return failure();
- // Special logic to analyze ops who's OpResults are not inplaceable on an
- // OpOperand but may create an alias.
- if (isa<ExtractSliceOp, tensor::CastOp>(op))
- if (failed(
- bufferizableInPlaceAnalysisAliasOnlyOp(op, aliasInfo, domInfo)))
- return failure();
+ // Special logic to analyze OpOperands that are not inplaceable on an
+ // OpResult but may create an alias.
+ if (bufferizesToAliasOnly(opOperand))
+ if (failed(bufferizableInPlaceAnalysisAliasOnlyOp(opOperand, aliasInfo,
+ domInfo)))
+ return failure();
+ }
}
return success();
@@ -3049,8 +3062,8 @@ static LogicalResult runInitTensorElimination(FuncOp funcOp,
aliasInfo.createAliasInfoEntry(extractOp.result());
// Run analysis on the ExtractSliceOp.
- if (failed(bufferizableInPlaceAnalysisAliasOnlyOp(extractOp, aliasInfo,
- domInfo)))
+ if (failed(bufferizableInPlaceAnalysisAliasOnlyOp(
+ extractOp->getOpOperand(0), aliasInfo, domInfo)))
return WalkResult::interrupt();
// Advance to the next operation.
More information about the Mlir-commits
mailing list