llvm-project/mlir/lib/Dialect/SparseTensor/Transforms/BufferizableOpInterfaceImpl.cpp
Matthias Springer 3798678bd1 [mlir][sparse][bufferize] Implement BufferizableOpInterface
Only the analysis part of the interface is implemented. The bufferization itself is performed by the SparseTensorConversion pass.

Differential Revision: https://reviews.llvm.org/D128138
2022-06-24 13:47:01 +02:00

130 lines
4.5 KiB
C++

//===- BufferizableOpInterfaceImpl.cpp - Impl. of BufferizableOpInterface -===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// These BufferizableOpInterface implementations provide analysis-related
// interface methods only. They are getting bufferized by the
// SparseTensorConversion pass.
#include "mlir/Dialect/SparseTensor/Transforms/BufferizableOpInterfaceImpl.h"
#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
#include "mlir/Dialect/Bufferization/IR/Bufferization.h"
#include "mlir/Dialect/SparseTensor/IR/SparseTensor.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/PatternMatch.h"
using namespace mlir::bufferization;
using namespace mlir::sparse_tensor;
namespace mlir {
namespace sparse_tensor {
namespace {
struct ConvertOpInterface
: public BufferizableOpInterface::ExternalModel<ConvertOpInterface,
sparse_tensor::ConvertOp> {
bool bufferizesToAllocation(Operation *op, OpResult opResult) const {
// ConvertOps may allocate. (Unless they convert between two identical
// types, then they fold away.)
return true;
}
bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return true;
}
bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return false;
}
SmallVector<OpResult> getAliasingOpResult(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return {};
}
bool isWritable(Operation *op, Value value,
const AnalysisState &state) const {
return true;
}
};
struct LoadOpInterface
: public BufferizableOpInterface::ExternalModel<LoadOpInterface,
sparse_tensor::LoadOp> {
bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return false;
}
bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return false;
}
SmallVector<OpResult> getAliasingOpResult(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return {op->getOpResult(0)};
}
BufferRelation bufferRelation(Operation *op, OpResult opResult,
const AnalysisState &state) const {
return BufferRelation::Equivalent;
}
};
struct NewOpInterface
: public BufferizableOpInterface::ExternalModel<NewOpInterface,
sparse_tensor::NewOp> {
bool isMemoryWrite(Operation *op, OpResult opResult,
const AnalysisState &state) const {
// NewOps allocate but do not write.
return false;
}
bool bufferizesToAllocation(Operation *op, OpResult opResult) const {
return true;
}
};
struct ReleaseOpInterface
: public BufferizableOpInterface::ExternalModel<ReleaseOpInterface,
sparse_tensor::ReleaseOp> {
bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return false;
}
bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return false;
}
SmallVector<OpResult> getAliasingOpResult(Operation *op, OpOperand &opOperand,
const AnalysisState &state) const {
return {};
}
};
} // namespace
} // namespace sparse_tensor
} // namespace mlir
void mlir::sparse_tensor::registerBufferizableOpInterfaceExternalModels(
DialectRegistry &registry) {
registry.addExtension(
+[](MLIRContext *ctx, sparse_tensor::SparseTensorDialect *dialect) {
sparse_tensor::ConvertOp::attachInterface<ConvertOpInterface>(*ctx);
sparse_tensor::LoadOp::attachInterface<LoadOpInterface>(*ctx);
sparse_tensor::NewOp::attachInterface<NewOpInterface>(*ctx);
sparse_tensor::ReleaseOp::attachInterface<ReleaseOpInterface>(*ctx);
});
}