24struct AllocTensorOpInterface
25 :
public BufferizableOpInterface::ExternalModel<AllocTensorOpInterface,
27 bool bufferizesToAllocation(Operation *op, Value value)
const {
return true; }
29 bool resultBufferizesToMemoryWrite(Operation *op, OpResult opResult,
30 const AnalysisState &state)
const {
32 return static_cast<bool>(cast<AllocTensorOp>(op).getCopy());
35 bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
36 const AnalysisState &state)
const {
38 "expected copy operand");
42 bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
43 const AnalysisState &state)
const {
45 "expected copy operand");
49 AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand,
50 const AnalysisState &state)
const {
55 FailureOr<BufferLikeType>
57 const BufferizationState &state,
58 SmallVector<Value> &invocationStack)
const {
59 auto allocTensorOp = cast<AllocTensorOp>(op);
60 assert(value == allocTensorOp.getResult() &&
"invalid value");
63 Attribute memorySpace;
64 if (allocTensorOp.getMemorySpace().has_value()) {
65 memorySpace = *allocTensorOp.getMemorySpace();
66 }
else if (allocTensorOp.getCopy()) {
68 bufferization::detail::asMemRefType(bufferization::getBufferType(
69 allocTensorOp.getCopy(),
options, state, invocationStack));
70 if (
failed(copyBufferType))
72 memorySpace = copyBufferType->getMemorySpace();
73 }
else if (
auto ms =
options.defaultMemorySpaceFn(
74 cast<TensorLikeType>(allocTensorOp.getType()))) {
77 return op->
emitError(
"could not infer memory space");
80 return cast<BufferLikeType>(getMemRefTypeWithStaticIdentityLayout(
81 allocTensorOp.getType(), memorySpace));
84 LogicalResult bufferize(Operation *op, RewriterBase &rewriter,
85 const BufferizationOptions &
options,
86 BufferizationState &state)
const {
87 auto allocTensorOp = cast<AllocTensorOp>(op);
88 OpBuilder::InsertionGuard g(rewriter);
89 Location loc = allocTensorOp.getLoc();
99 if (allocTensorOp.getCopy()) {
100 FailureOr<Value> maybeCopyBuffer = bufferization::getBuffer(
101 rewriter, allocTensorOp.getCopy(),
options, state);
102 if (
failed(maybeCopyBuffer))
104 copyBuffer = *maybeCopyBuffer;
109 bufferization::getBufferType(allocTensorOp.getResult(),
options, state);
112 SmallVector<Value> dynamicDims = allocTensorOp.getDynamicSizes();
113 if (allocTensorOp.getCopy()) {
114 assert(dynamicDims.empty() &&
"expected either `copy` or `dynamicDims`");
117 FailureOr<Value> alloc =
118 options.allocationFn(rewriter, loc, llvm::cast<MemRefType>(*allocType),
119 dynamicDims,
options.bufferAlignment);
124 if (allocTensorOp.getCopy()) {
125 if (
failed(
options.memCpyFn(rewriter, loc, copyBuffer, *alloc)))
130 replaceOpWithBufferizedValues(rewriter, op, *alloc);
136struct DeallocTensorOpInterface
137 :
public BufferizableOpInterface::ExternalModel<DeallocTensorOpInterface,
139 bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
140 const AnalysisState &state)
const {
144 bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
145 const AnalysisState &state)
const {
149 AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand,
150 const AnalysisState &state)
const {
154 LogicalResult bufferize(Operation *op, RewriterBase &rewriter,
155 const BufferizationOptions &
options,
156 BufferizationState &state)
const {
157 auto deallocTensorOp = cast<DeallocTensorOp>(op);
158 FailureOr<Value> buffer = bufferization::getBuffer(
159 rewriter, deallocTensorOp.getTensor(),
options, state);
162 memref::DeallocOp::create(rewriter, deallocTensorOp.getLoc(), *buffer);
168struct MaterializeInDestinationOpInterface
169 :
public BufferizableOpInterface::ExternalModel<
170 MaterializeInDestinationOpInterface, MaterializeInDestinationOp> {
171 bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
172 const AnalysisState &state)
const {
173 return opOperand == cast<MaterializeInDestinationOp>(op).getSourceMutable();
176 bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
177 const AnalysisState &state)
const {
178 auto materializeOp = cast<MaterializeInDestinationOp>(op);
179 if (opOperand == materializeOp.getDestMutable()) {
180 assert(isa<TensorType>(materializeOp.getDest().getType()) &&
181 "expected tensor type");
187 bool mustBufferizeInPlace(Operation *op, OpOperand &opOperand,
188 const AnalysisState &state)
const {
195 AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand,
196 const AnalysisState &state)
const {
197 auto materializeOp = cast<MaterializeInDestinationOp>(op);
198 if (opOperand == materializeOp.getDestMutable()) {
199 assert(isa<TensorType>(materializeOp.getDest().getType()) &&
200 "expected tensor type");
201 return {{op->
getResult(0), BufferRelation::Equivalent}};
206 LogicalResult bufferize(Operation *op, RewriterBase &rewriter,
207 const BufferizationOptions &
options,
208 BufferizationState &state)
const {
209 auto materializeOp = cast<MaterializeInDestinationOp>(op);
210 bool tensorDest = isa<TensorType>(materializeOp.getDest().getType());
213 FailureOr<Value> maybeBuffer = bufferization::getBuffer(
214 rewriter, materializeOp.getDest(),
options, state);
217 buffer = *maybeBuffer;
219 assert(isa<BaseMemRefType>(materializeOp.getDest().getType()) &&
220 "expected memref type");
221 buffer = materializeOp.getDest();
223 auto srcBuffer = bufferization::getBuffer(
224 rewriter, materializeOp.getSource(),
options, state);
227 if (
failed(
options.memCpyFn(rewriter, materializeOp.getLoc(), *srcBuffer,
230 replaceOpWithBufferizedValues(
235 bool bufferizesToElementwiseAccess(Operation *op,
const AnalysisState &state,
236 ArrayRef<OpOperand *> opOperands)
const {
242 bool isWritable(Operation *op, Value value,
243 const AnalysisState &state)
const {
244 auto materializeOp = cast<MaterializeInDestinationOp>(op);
245 return isa<TensorType>(materializeOp.getDest().getType())
247 : materializeOp.getWritable();
257struct ToTensorOpInterface
258 :
public BufferizableOpInterface::ExternalModel<ToTensorOpInterface,
260 bool isWritable(Operation *op, Value value,
261 const AnalysisState &state)
const {
262 return cast<ToTensorOp>(op).getWritable();
265 FailureOr<BufferLikeType>
267 const BufferizationState &state,
268 SmallVector<Value> &invocationStack)
const {
269 return cast<ToTensorOp>(op).getBuffer().getType();
272 LogicalResult bufferize(Operation *op, RewriterBase &rewriter,
273 const BufferizationOptions &
options,
274 BufferizationState &state)
const {
280struct ToBufferOpInterface
281 :
public BufferizableOpInterface::ExternalModel<ToBufferOpInterface,
283 bool bufferizesToMemoryRead(Operation *op, OpOperand &opOperand,
284 const AnalysisState &state)
const {
289 bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
290 const AnalysisState &state)
const {
291 return !cast<ToBufferOp>(op).getReadOnly();
294 AliasingValueList getAliasingValues(Operation *op, OpOperand &opOperand,
295 const AnalysisState &state)
const {
299 LogicalResult bufferize(Operation *op, RewriterBase &rewriter,
300 const BufferizationOptions &
options,
301 BufferizationState &state)
const {
317 AllocTensorOp::attachInterface<AllocTensorOpInterface>(*ctx);
318 DeallocTensorOp::attachInterface<DeallocTensorOpInterface>(*ctx);
319 MaterializeInDestinationOp::attachInterface<
320 MaterializeInDestinationOpInterface>(*ctx);
321 ToBufferOp::attachInterface<ToBufferOpInterface>(*ctx);
322 ToTensorOp::attachInterface<ToTensorOpInterface>(*ctx);
true
Given two iterators into the same block, return "true" if a is before `b.
static llvm::ManagedStatic< PassManagerOptions > options
static RankedTensorType getBufferType(const SparseTensorType &stt, bool needTmpCOO)
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
MLIRContext is the top-level object for a collection of MLIR operations.
unsigned getOperandNumber() const
Return which operand this is in the OpOperand list of the Operation.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
unsigned getNumOperands()
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
use_range getUses()
Returns a range of all uses, which is useful for iterating over all uses.
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
LogicalResult foldToBufferToTensorPair(RewriterBase &rewriter, ToBufferOp toBuffer, const BufferizationOptions &options)
Try to fold to_buffer(to_tensor(x)).
void registerBufferizableOpInterfaceExternalModels(DialectRegistry ®istry)
void populateDynamicDimSizes(OpBuilder &b, Location loc, Value shapedValue, SmallVector< Value > &dynamicDims)
Populate dynamicDims with tensor::DimOp / memref::DimOp results for all dynamic dimensions of the giv...
Include the generated interface declarations.