blob: e04eab8b564965505163eff20fe50c1e59b8ee05 [file] [log] [blame]
//===- BufferizationOps.td - Bufferization op definitions ----------*- tablegen -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#ifndef BUFFERIZATION_OPS
#define BUFFERIZATION_OPS
include "mlir/Dialect/Bufferization/IR/AllocationOpInterface.td"
include "mlir/Dialect/Bufferization/IR/BufferizationBase.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/Interfaces/CopyOpInterface.td"
class Bufferization_Op<string mnemonic, list<OpTrait> traits = []>
: Op<Bufferization_Dialect, mnemonic, traits>;
//===----------------------------------------------------------------------===//
// CloneOp
//===----------------------------------------------------------------------===//
def Bufferization_CloneOp : Bufferization_Op<"clone", [
CopyOpInterface,
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
DeclareOpInterfaceMethods<AllocationOpInterface, ["buildDealloc", "buildClone"]>
]> {
let builders = [
OpBuilder<(ins "Value":$value), [{
return build($_builder, $_state, value.getType(), value);
}]>];
let description = [{
Clones the data in the input view into an implicitly defined output view.
Usage:
```mlir
%arg1 = bufferization.clone %arg0 : memref<?xf32> to memref<?xf32>
```
Valid implementations of this operation may alias the input and output
views or create an actual copy. Mutating the source or result
of the clone operation after the clone operation thus leads to undefined
behavior.
}];
let arguments = (ins Arg<AnyRankedOrUnrankedMemRef, "", []>:$input);
let results = (outs Arg<AnyRankedOrUnrankedMemRef, "", []>:$output);
let extraClassDeclaration = [{
Value getSource() { return input(); }
Value getTarget() { return output(); }
}];
let assemblyFormat = "$input attr-dict `:` type($input) `to` type($output)";
let hasFolder = 1;
let verifier = ?;
let hasCanonicalizer = 1;
}
//===----------------------------------------------------------------------===//
// ToTensorOp
//===----------------------------------------------------------------------===//
def Bufferization_ToTensorOp : Bufferization_Op<"to_tensor",
[SameOperandsAndResultShape, SameOperandsAndResultElementType,
TypesMatchWith<"result type matches tensor equivalent of 'memref'",
"memref", "result",
"memref::getTensorTypeFromMemRefType($_self)">]> {
let summary = "memref to tensor operation";
let description = [{
Create a tensor from a memref, making an independent copy of the element
data. The result value is a tensor whose shape and element type match the
memref operand.
The opposite of this op is to_memref. Together, these two ops are
useful for source/target materializations when doing type conversions
involving tensors and memrefs.
Example:
```mlir
// Produces a value of tensor<4x?xf32> type.
%12 = bufferization.to_tensor %10 : memref<4x?xf32, #layout, memspace0>
```
If tensor load is used in the bufferization steps, mutating the source
buffer after loading leads to undefined behavior.
}];
let arguments = (ins Arg<AnyRankedOrUnrankedMemRef,
"the reference to load from", [MemRead]>:$memref);
let results = (outs AnyTensor:$result);
// MemrefToTensor is fully verified by traits.
let verifier = ?;
let builders = [
OpBuilder<(ins "Value":$memref), [{
$_state.addOperands(memref);
$_state.addTypes(memref::getTensorTypeFromMemRefType(memref.getType()));
}]>];
let extraClassDeclaration = [{
/// The result of a to_tensor is always a tensor.
TensorType getType() {
Type resultType = getResult().getType();
if (resultType.isa<TensorType>())
return resultType.cast<TensorType>();
return {};
}
}];
let assemblyFormat = "$memref attr-dict `:` type($memref)";
let hasCanonicalizer = 1;
let hasFolder = 1;
}
//===----------------------------------------------------------------------===//
// ToMemrefOp
//===----------------------------------------------------------------------===//
def Bufferization_ToMemrefOp : Bufferization_Op<"to_memref",
[SameOperandsAndResultShape, SameOperandsAndResultElementType, NoSideEffect,
TypesMatchWith<"type of 'tensor' is the tensor equivalent of 'memref'",
"memref", "tensor",
"memref::getTensorTypeFromMemRefType($_self)">]> {
let summary = "tensor to memref cast operation";
let description = [{
Casts a tensor to a memref.
```mlir
// Result type is tensor<4x?xf32>
%12 = bufferization.to_memref %10 : memref<4x?xf32, #map0, 42>
```
Note, that mutating the result of the to_buffer operation leads to
undefined behavior.
This operation is a specialized variant of the built-in
unrealized_conversion_cast and is intended for use in the context of
gradual bufferization.
}];
let arguments = (ins AnyTensor:$tensor);
let results = (outs AnyRankedOrUnrankedMemRef:$memref);
// This op is fully verified by traits.
let verifier = ?;
let assemblyFormat = "$tensor attr-dict `:` type($memref)";
let hasFolder = 1;
let hasCanonicalizer = 1;
}
#endif // BUFFERIZATION_OPS