1*3798678bSMatthias Springer //===- BufferizableOpInterfaceImpl.cpp - Impl. of BufferizableOpInterface -===// 2*3798678bSMatthias Springer // 3*3798678bSMatthias Springer // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*3798678bSMatthias Springer // See https://llvm.org/LICENSE.txt for license information. 5*3798678bSMatthias Springer // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*3798678bSMatthias Springer // 7*3798678bSMatthias Springer //===----------------------------------------------------------------------===// 8*3798678bSMatthias Springer // 9*3798678bSMatthias Springer // These BufferizableOpInterface implementations provide analysis-related 10*3798678bSMatthias Springer // interface methods only. They are getting bufferized by the 11*3798678bSMatthias Springer // SparseTensorConversion pass. 12*3798678bSMatthias Springer 13*3798678bSMatthias Springer #include "mlir/Dialect/SparseTensor/Transforms/BufferizableOpInterfaceImpl.h" 14*3798678bSMatthias Springer 15*3798678bSMatthias Springer #include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h" 16*3798678bSMatthias Springer #include "mlir/Dialect/Bufferization/IR/Bufferization.h" 17*3798678bSMatthias Springer #include "mlir/Dialect/SparseTensor/IR/SparseTensor.h" 18*3798678bSMatthias Springer #include "mlir/IR/Dialect.h" 19*3798678bSMatthias Springer #include "mlir/IR/Operation.h" 20*3798678bSMatthias Springer #include "mlir/IR/PatternMatch.h" 21*3798678bSMatthias Springer 22*3798678bSMatthias Springer using namespace mlir::bufferization; 23*3798678bSMatthias Springer using namespace mlir::sparse_tensor; 24*3798678bSMatthias Springer 25*3798678bSMatthias Springer namespace mlir { 26*3798678bSMatthias Springer namespace sparse_tensor { 27*3798678bSMatthias Springer namespace { 28*3798678bSMatthias Springer 29*3798678bSMatthias Springer struct ConvertOpInterface 30*3798678bSMatthias Springer : public BufferizableOpInterface::ExternalModel<ConvertOpInterface, 31*3798678bSMatthias Springer sparse_tensor::ConvertOp> { 32*3798678bSMatthias Springer bool bufferizesToAllocation(Operation *op, OpResult opResult) const { 33*3798678bSMatthias Springer // ConvertOps may allocate. (Unless they convert between two identical 34*3798678bSMatthias Springer // types, then they fold away.) 35*3798678bSMatthias Springer return true; 36*3798678bSMatthias Springer } 37*3798678bSMatthias Springer 38*3798678bSMatthias Springer bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, 39*3798678bSMatthias Springer const AnalysisState &state) const { 40*3798678bSMatthias Springer return true; 41*3798678bSMatthias Springer } 42*3798678bSMatthias Springer 43*3798678bSMatthias Springer bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, 44*3798678bSMatthias Springer const AnalysisState &state) const { 45*3798678bSMatthias Springer return false; 46*3798678bSMatthias Springer } 47*3798678bSMatthias Springer 48*3798678bSMatthias Springer SmallVector<OpResult> getAliasingOpResult(Operation *op, OpOperand &opOperand, 49*3798678bSMatthias Springer const AnalysisState &state) const { 50*3798678bSMatthias Springer return {}; 51*3798678bSMatthias Springer } 52*3798678bSMatthias Springer 53*3798678bSMatthias Springer bool isWritable(Operation *op, Value value, 54*3798678bSMatthias Springer const AnalysisState &state) const { 55*3798678bSMatthias Springer return true; 56*3798678bSMatthias Springer } 57*3798678bSMatthias Springer }; 58*3798678bSMatthias Springer 59*3798678bSMatthias Springer struct LoadOpInterface 60*3798678bSMatthias Springer : public BufferizableOpInterface::ExternalModel<LoadOpInterface, 61*3798678bSMatthias Springer sparse_tensor::LoadOp> { 62*3798678bSMatthias Springer bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, 63*3798678bSMatthias Springer const AnalysisState &state) const { 64*3798678bSMatthias Springer return false; 65*3798678bSMatthias Springer } 66*3798678bSMatthias Springer 67*3798678bSMatthias Springer bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, 68*3798678bSMatthias Springer const AnalysisState &state) const { 69*3798678bSMatthias Springer return false; 70*3798678bSMatthias Springer } 71*3798678bSMatthias Springer 72*3798678bSMatthias Springer SmallVector<OpResult> getAliasingOpResult(Operation *op, OpOperand &opOperand, 73*3798678bSMatthias Springer const AnalysisState &state) const { 74*3798678bSMatthias Springer return {op->getOpResult(0)}; 75*3798678bSMatthias Springer } 76*3798678bSMatthias Springer 77*3798678bSMatthias Springer BufferRelation bufferRelation(Operation *op, OpResult opResult, 78*3798678bSMatthias Springer const AnalysisState &state) const { 79*3798678bSMatthias Springer return BufferRelation::Equivalent; 80*3798678bSMatthias Springer } 81*3798678bSMatthias Springer }; 82*3798678bSMatthias Springer 83*3798678bSMatthias Springer struct NewOpInterface 84*3798678bSMatthias Springer : public BufferizableOpInterface::ExternalModel<NewOpInterface, 85*3798678bSMatthias Springer sparse_tensor::NewOp> { 86*3798678bSMatthias Springer bool isMemoryWrite(Operation *op, OpResult opResult, 87*3798678bSMatthias Springer const AnalysisState &state) const { 88*3798678bSMatthias Springer // NewOps allocate but do not write. 89*3798678bSMatthias Springer return false; 90*3798678bSMatthias Springer } 91*3798678bSMatthias Springer 92*3798678bSMatthias Springer bool bufferizesToAllocation(Operation *op, OpResult opResult) const { 93*3798678bSMatthias Springer return true; 94*3798678bSMatthias Springer } 95*3798678bSMatthias Springer }; 96*3798678bSMatthias Springer 97*3798678bSMatthias Springer struct ReleaseOpInterface 98*3798678bSMatthias Springer : public BufferizableOpInterface::ExternalModel<ReleaseOpInterface, 99*3798678bSMatthias Springer sparse_tensor::ReleaseOp> { 100*3798678bSMatthias Springer bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand, 101*3798678bSMatthias Springer const AnalysisState &state) const { 102*3798678bSMatthias Springer return false; 103*3798678bSMatthias Springer } 104*3798678bSMatthias Springer 105*3798678bSMatthias Springer bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand, 106*3798678bSMatthias Springer const AnalysisState &state) const { 107*3798678bSMatthias Springer return false; 108*3798678bSMatthias Springer } 109*3798678bSMatthias Springer 110*3798678bSMatthias Springer SmallVector<OpResult> getAliasingOpResult(Operation *op, OpOperand &opOperand, 111*3798678bSMatthias Springer const AnalysisState &state) const { 112*3798678bSMatthias Springer return {}; 113*3798678bSMatthias Springer } 114*3798678bSMatthias Springer }; 115*3798678bSMatthias Springer 116*3798678bSMatthias Springer } // namespace 117*3798678bSMatthias Springer } // namespace sparse_tensor 118*3798678bSMatthias Springer } // namespace mlir 119*3798678bSMatthias Springer 120*3798678bSMatthias Springer void mlir::sparse_tensor::registerBufferizableOpInterfaceExternalModels( 121*3798678bSMatthias Springer DialectRegistry ®istry) { 122*3798678bSMatthias Springer registry.addExtension( 123*3798678bSMatthias Springer +[](MLIRContext *ctx, sparse_tensor::SparseTensorDialect *dialect) { 124*3798678bSMatthias Springer sparse_tensor::ConvertOp::attachInterface<ConvertOpInterface>(*ctx); 125*3798678bSMatthias Springer sparse_tensor::LoadOp::attachInterface<LoadOpInterface>(*ctx); 126*3798678bSMatthias Springer sparse_tensor::NewOp::attachInterface<NewOpInterface>(*ctx); 127*3798678bSMatthias Springer sparse_tensor::ReleaseOp::attachInterface<ReleaseOpInterface>(*ctx); 128*3798678bSMatthias Springer }); 129*3798678bSMatthias Springer } 130