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 {
37 assert(&opOperand == &cast<AllocTensorOp>(op).getCopyMutable()[0] &&
38 "expected copy operand");
42 bool bufferizesToMemoryWrite(Operation *op, OpOperand &opOperand,
43 const AnalysisState &state)
const {
44 assert(&opOperand == &cast<AllocTensorOp>(op).getCopyMutable()[0] &&
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.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
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.