710 lines
38 KiB
C++
710 lines
38 KiB
C++
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|
|
|* *|
|
|
|* Interface Declarations *|
|
|
|* *|
|
|
|* Automatically generated file, do not edit! *|
|
|
|* *|
|
|
\*===----------------------------------------------------------------------===*/
|
|
|
|
namespace mlir {
|
|
|
|
/// This interface can be implemented by ops that operate on tensor subsets. A
|
|
/// "subset" is a part of a tensor. This interface describes the subset that
|
|
/// an implementing op operates on. Only the specified subset may be accessed by
|
|
/// the op.
|
|
///
|
|
/// Subset ops come in two flavours and ops that implement the
|
|
/// `SubsetOpInterface` must also implement one of the respective interfaces.
|
|
/// - Insertion flavor: Ops that insert a source value into a destination
|
|
/// tensor at the specified subset. Such ops return an updated destination
|
|
/// tensor and usually implement the `DestinationStyleOpInterface`. Insertion
|
|
/// ops must implement the `SubsetInsertionOpInterface`.
|
|
/// - Extraction flavor: Ops that extract at a subset. Extraction ops must
|
|
/// implement the `SubsetExtractionOpInterface`.
|
|
///
|
|
/// How the subset is specified is up to the implementing op. E.g.:
|
|
/// - `tensor.extract_slice/insert_slice` describe the subset as a
|
|
/// hyperrectangular slice.
|
|
/// - `tensor.gather/scatter` describe the subset as list of indices. (Not
|
|
/// implemented yet.)
|
|
class SubsetOpInterface;
|
|
|
|
} // namespace mlir
|
|
namespace mlir {
|
|
|
|
/// This interface can be implemented by ops that extract a value from
|
|
/// a source tensor at a specified subset. The elements in the source tensor
|
|
/// that are read by this extraction are called "subset".
|
|
///
|
|
/// Extraction ops must have a single result value.
|
|
class SubsetExtractionOpInterface;
|
|
|
|
} // namespace mlir
|
|
namespace mlir {
|
|
|
|
/// This interface can be implemented by ops that insert a source value into
|
|
/// a destination tensor at a specified subset. The elements in the destination
|
|
/// tensor that are overwritten by this insertion are called "subset". The
|
|
/// updated destination tensor is returned.
|
|
///
|
|
/// This interface provides helper methods for efficient bufferization of
|
|
/// subset-based tensor IR. Tensor subsets can bufferize to buffer "views"/
|
|
/// "aliases" (in contrast to one or multiple less efficient buffer allocation).
|
|
///
|
|
/// This interface is queried by One-Shot Bufferize to detect cases where a
|
|
/// seeming read-after-write is not actually a conflict because the respective
|
|
/// ops are operating on equivalent subsets. More details can be found in the
|
|
/// documentation of One-Shot Analysis (see `areNonConflictingSubsets`).
|
|
class SubsetInsertionOpInterface;
|
|
|
|
} // namespace mlir
|
|
namespace mlir {
|
|
|
|
/// This interface can be implemented by ops that operate on tensor subsets. A
|
|
/// "subset" is a part of a tensor. This interface describes the subset that
|
|
/// an implementing op operates on. Only the specified subset may be accessed by
|
|
/// the op.
|
|
///
|
|
/// Subset ops come in two flavours and ops that implement the
|
|
/// `SubsetOpInterface` must also implement one of the respective interfaces.
|
|
/// - Insertion flavor: Ops that insert a source value into a destination
|
|
/// tensor at the specified subset. Such ops return an updated destination
|
|
/// tensor and usually implement the `DestinationStyleOpInterface`. Insertion
|
|
/// ops must implement the `SubsetInsertionOpInterface`.
|
|
/// - Extraction flavor: Ops that extract at a subset. Extraction ops must
|
|
/// implement the `SubsetExtractionOpInterface`.
|
|
///
|
|
/// How the subset is specified is up to the implementing op. E.g.:
|
|
/// - `tensor.extract_slice/insert_slice` describe the subset as a
|
|
/// hyperrectangular slice.
|
|
/// - `tensor.gather/scatter` describe the subset as list of indices. (Not
|
|
/// implemented yet.)
|
|
namespace detail {
|
|
struct SubsetOpInterfaceInterfaceTraits {
|
|
struct Concept {
|
|
/// The methods defined by the interface.
|
|
bool (*operatesOnEquivalentSubset)(const Concept *impl, ::mlir::Operation *, ::mlir::SubsetOpInterface, ::llvm::function_ref<bool(Value, Value)>);
|
|
bool (*operatesOnDisjointSubset)(const Concept *impl, ::mlir::Operation *, ::mlir::SubsetOpInterface, ::llvm::function_ref<bool(Value, Value)>);
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> (*getAccessedHyperrectangularSlice)(const Concept *impl, ::mlir::Operation *);
|
|
};
|
|
template<typename ConcreteOp>
|
|
class Model : public Concept {
|
|
public:
|
|
using Interface = ::mlir::SubsetOpInterface;
|
|
Model() : Concept{operatesOnEquivalentSubset, operatesOnDisjointSubset, getAccessedHyperrectangularSlice} {}
|
|
|
|
static inline bool operatesOnEquivalentSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
static inline bool operatesOnDisjointSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
static inline ::mlir::FailureOr<::mlir::HyperrectangularSlice> getAccessedHyperrectangularSlice(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
};
|
|
template<typename ConcreteOp>
|
|
class FallbackModel : public Concept {
|
|
public:
|
|
using Interface = ::mlir::SubsetOpInterface;
|
|
FallbackModel() : Concept{operatesOnEquivalentSubset, operatesOnDisjointSubset, getAccessedHyperrectangularSlice} {}
|
|
|
|
static inline bool operatesOnEquivalentSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
static inline bool operatesOnDisjointSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
static inline ::mlir::FailureOr<::mlir::HyperrectangularSlice> getAccessedHyperrectangularSlice(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
};
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
class ExternalModel : public FallbackModel<ConcreteModel> {
|
|
public:
|
|
using ConcreteEntity = ConcreteOp;
|
|
bool operatesOnEquivalentSubset(::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) const;
|
|
bool operatesOnDisjointSubset(::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) const;
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> getAccessedHyperrectangularSlice(::mlir::Operation *tablegen_opaque_val) const;
|
|
};
|
|
};
|
|
template <typename ConcreteOp>
|
|
struct SubsetOpInterfaceTrait;
|
|
|
|
} // namespace detail
|
|
class SubsetOpInterface : public ::mlir::OpInterface<SubsetOpInterface, detail::SubsetOpInterfaceInterfaceTraits> {
|
|
public:
|
|
using ::mlir::OpInterface<SubsetOpInterface, detail::SubsetOpInterfaceInterfaceTraits>::OpInterface;
|
|
template <typename ConcreteOp>
|
|
struct Trait : public detail::SubsetOpInterfaceTrait<ConcreteOp> {};
|
|
|
|
/// Return "true" if this op and the given candidate subset op operate on
|
|
/// equivalent subsets. Return "false" if the two subsets are disjoint
|
|
/// or cannot be proven to be equivalent.
|
|
///
|
|
/// This interface method does not have to be implemented if
|
|
/// `getAccessedHyperrectangularSlice` is implemented.
|
|
bool operatesOnEquivalentSubset(::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
|
|
/// Return "true" if this op and the given candidate subset op operate on
|
|
/// disjoint subsets. Return "false" if the two subsets are equivalent,
|
|
/// overlapping or cannot be proven to be disjoint.
|
|
///
|
|
/// This interface method does not have to be implemented if
|
|
/// `getAccessedHyperrectangularSlice` is implemented.
|
|
bool operatesOnDisjointSubset(::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
|
|
/// If this op operates on a hyperrectangular subset, return a
|
|
/// description of the subset in terms of offsets, sizes and strides.
|
|
/// Otherwise, return "failure".
|
|
///
|
|
/// This interface method is a convenience method for the most common case
|
|
/// of hyperrectangular subset ops. It is optional. If it is implemented,
|
|
/// `operatesOnEquivalentSubset` and `operatesOnDisjointSubset` do not
|
|
/// have to be implemented.
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> getAccessedHyperrectangularSlice();
|
|
|
|
/// Return the container that this operation is operating on. In case of an
|
|
/// extraction op, the container is the source tensor. In case of an
|
|
/// insertion op, the container is the destination tensor.
|
|
Value getTensorContainer() {
|
|
return ::mlir::detail::getTensorContainer(getOperation());
|
|
}
|
|
};
|
|
|
|
} // namespace mlir
|
|
namespace mlir {
|
|
|
|
/// This interface can be implemented by ops that extract a value from
|
|
/// a source tensor at a specified subset. The elements in the source tensor
|
|
/// that are read by this extraction are called "subset".
|
|
///
|
|
/// Extraction ops must have a single result value.
|
|
namespace detail {
|
|
struct SubsetExtractionOpInterfaceInterfaceTraits {
|
|
struct Concept {
|
|
/// The methods defined by the interface.
|
|
::mlir::OpOperand &(*getSourceOperand)(const Concept *impl, ::mlir::Operation *);
|
|
/// The base classes of this interface.
|
|
const ::mlir::SubsetOpInterface::Concept *implSubsetOpInterface = nullptr;
|
|
|
|
void initializeInterfaceConcept(::mlir::detail::InterfaceMap &interfaceMap) {
|
|
implSubsetOpInterface = interfaceMap.lookup<::mlir::SubsetOpInterface>();
|
|
assert(implSubsetOpInterface && "`::mlir::SubsetExtractionOpInterface` expected its base interface `::mlir::SubsetOpInterface` to be registered");
|
|
}
|
|
};
|
|
template<typename ConcreteOp>
|
|
class Model : public Concept {
|
|
public:
|
|
using Interface = ::mlir::SubsetExtractionOpInterface;
|
|
Model() : Concept{getSourceOperand} {}
|
|
|
|
static inline ::mlir::OpOperand &getSourceOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
};
|
|
template<typename ConcreteOp>
|
|
class FallbackModel : public Concept {
|
|
public:
|
|
using Interface = ::mlir::SubsetExtractionOpInterface;
|
|
FallbackModel() : Concept{getSourceOperand} {}
|
|
|
|
static inline ::mlir::OpOperand &getSourceOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
};
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
class ExternalModel : public FallbackModel<ConcreteModel> {
|
|
public:
|
|
using ConcreteEntity = ConcreteOp;
|
|
};
|
|
};
|
|
template <typename ConcreteOp>
|
|
struct SubsetExtractionOpInterfaceTrait;
|
|
|
|
} // namespace detail
|
|
class SubsetExtractionOpInterface : public ::mlir::OpInterface<SubsetExtractionOpInterface, detail::SubsetExtractionOpInterfaceInterfaceTraits> {
|
|
public:
|
|
using ::mlir::OpInterface<SubsetExtractionOpInterface, detail::SubsetExtractionOpInterfaceInterfaceTraits>::OpInterface;
|
|
template <typename ConcreteOp>
|
|
struct Trait : public detail::SubsetExtractionOpInterfaceTrait<ConcreteOp> {};
|
|
|
|
/// Return the source tensor operand.
|
|
::mlir::OpOperand &getSourceOperand();
|
|
|
|
/// Return the single result of this op.
|
|
::mlir::Value getResult() {
|
|
return getOperation()->getResult(0);
|
|
}
|
|
//===----------------------------------------------------------------===//
|
|
// Inherited from ::mlir::SubsetOpInterface
|
|
//===----------------------------------------------------------------===//
|
|
|
|
operator ::mlir::SubsetOpInterface () const {
|
|
if (!*this) return nullptr;
|
|
return ::mlir::SubsetOpInterface(*this, getImpl()->implSubsetOpInterface);
|
|
}
|
|
|
|
|
|
/// Return "true" if this op and the given candidate subset op operate on
|
|
/// equivalent subsets. Return "false" if the two subsets are disjoint
|
|
/// or cannot be proven to be equivalent.
|
|
///
|
|
/// This interface method does not have to be implemented if
|
|
/// `getAccessedHyperrectangularSlice` is implemented.
|
|
bool operatesOnEquivalentSubset(::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
|
|
/// Return "true" if this op and the given candidate subset op operate on
|
|
/// disjoint subsets. Return "false" if the two subsets are equivalent,
|
|
/// overlapping or cannot be proven to be disjoint.
|
|
///
|
|
/// This interface method does not have to be implemented if
|
|
/// `getAccessedHyperrectangularSlice` is implemented.
|
|
bool operatesOnDisjointSubset(::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
|
|
/// If this op operates on a hyperrectangular subset, return a
|
|
/// description of the subset in terms of offsets, sizes and strides.
|
|
/// Otherwise, return "failure".
|
|
///
|
|
/// This interface method is a convenience method for the most common case
|
|
/// of hyperrectangular subset ops. It is optional. If it is implemented,
|
|
/// `operatesOnEquivalentSubset` and `operatesOnDisjointSubset` do not
|
|
/// have to be implemented.
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> getAccessedHyperrectangularSlice();
|
|
|
|
/// Return the container that this operation is operating on. In case of an
|
|
/// extraction op, the container is the source tensor. In case of an
|
|
/// insertion op, the container is the destination tensor.
|
|
Value getTensorContainer() {
|
|
return ::mlir::detail::getTensorContainer(getOperation());
|
|
}
|
|
};
|
|
|
|
} // namespace mlir
|
|
namespace mlir {
|
|
|
|
/// This interface can be implemented by ops that insert a source value into
|
|
/// a destination tensor at a specified subset. The elements in the destination
|
|
/// tensor that are overwritten by this insertion are called "subset". The
|
|
/// updated destination tensor is returned.
|
|
///
|
|
/// This interface provides helper methods for efficient bufferization of
|
|
/// subset-based tensor IR. Tensor subsets can bufferize to buffer "views"/
|
|
/// "aliases" (in contrast to one or multiple less efficient buffer allocation).
|
|
///
|
|
/// This interface is queried by One-Shot Bufferize to detect cases where a
|
|
/// seeming read-after-write is not actually a conflict because the respective
|
|
/// ops are operating on equivalent subsets. More details can be found in the
|
|
/// documentation of One-Shot Analysis (see `areNonConflictingSubsets`).
|
|
namespace detail {
|
|
struct SubsetInsertionOpInterfaceInterfaceTraits {
|
|
struct Concept {
|
|
/// The methods defined by the interface.
|
|
::mlir::OpOperand &(*getSourceOperand)(const Concept *impl, ::mlir::Operation *);
|
|
::mlir::OpOperand &(*getDestinationOperand)(const Concept *impl, ::mlir::Operation *);
|
|
::mlir::OpResult (*getUpdatedDestination)(const Concept *impl, ::mlir::Operation *);
|
|
bool (*isEquivalentSubset)(const Concept *impl, ::mlir::Operation *, ::mlir::Value, ::llvm::function_ref<bool(Value, Value)>);
|
|
::mlir::Value (*buildSubsetExtraction)(const Concept *impl, ::mlir::Operation *, ::mlir::OpBuilder &, Location);
|
|
::llvm::SmallVector<::mlir::Value> (*getValuesNeededToBuildSubsetExtraction)(const Concept *impl, ::mlir::Operation *);
|
|
/// The base classes of this interface.
|
|
const ::mlir::SubsetOpInterface::Concept *implSubsetOpInterface = nullptr;
|
|
|
|
void initializeInterfaceConcept(::mlir::detail::InterfaceMap &interfaceMap) {
|
|
implSubsetOpInterface = interfaceMap.lookup<::mlir::SubsetOpInterface>();
|
|
assert(implSubsetOpInterface && "`::mlir::SubsetInsertionOpInterface` expected its base interface `::mlir::SubsetOpInterface` to be registered");
|
|
}
|
|
};
|
|
template<typename ConcreteOp>
|
|
class Model : public Concept {
|
|
public:
|
|
using Interface = ::mlir::SubsetInsertionOpInterface;
|
|
Model() : Concept{getSourceOperand, getDestinationOperand, getUpdatedDestination, isEquivalentSubset, buildSubsetExtraction, getValuesNeededToBuildSubsetExtraction} {}
|
|
|
|
static inline ::mlir::OpOperand &getSourceOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
static inline ::mlir::OpOperand &getDestinationOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
static inline ::mlir::OpResult getUpdatedDestination(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
static inline bool isEquivalentSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Value candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
static inline ::mlir::Value buildSubsetExtraction(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::OpBuilder & builder, Location loc);
|
|
static inline ::llvm::SmallVector<::mlir::Value> getValuesNeededToBuildSubsetExtraction(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
};
|
|
template<typename ConcreteOp>
|
|
class FallbackModel : public Concept {
|
|
public:
|
|
using Interface = ::mlir::SubsetInsertionOpInterface;
|
|
FallbackModel() : Concept{getSourceOperand, getDestinationOperand, getUpdatedDestination, isEquivalentSubset, buildSubsetExtraction, getValuesNeededToBuildSubsetExtraction} {}
|
|
|
|
static inline ::mlir::OpOperand &getSourceOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
static inline ::mlir::OpOperand &getDestinationOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
static inline ::mlir::OpResult getUpdatedDestination(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
static inline bool isEquivalentSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Value candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
static inline ::mlir::Value buildSubsetExtraction(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::OpBuilder & builder, Location loc);
|
|
static inline ::llvm::SmallVector<::mlir::Value> getValuesNeededToBuildSubsetExtraction(const Concept *impl, ::mlir::Operation *tablegen_opaque_val);
|
|
};
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
class ExternalModel : public FallbackModel<ConcreteModel> {
|
|
public:
|
|
using ConcreteEntity = ConcreteOp;
|
|
::mlir::OpOperand &getDestinationOperand(::mlir::Operation *tablegen_opaque_val) const;
|
|
::mlir::OpResult getUpdatedDestination(::mlir::Operation *tablegen_opaque_val) const;
|
|
bool isEquivalentSubset(::mlir::Operation *tablegen_opaque_val, ::mlir::Value candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) const;
|
|
};
|
|
};
|
|
template <typename ConcreteOp>
|
|
struct SubsetInsertionOpInterfaceTrait;
|
|
|
|
} // namespace detail
|
|
class SubsetInsertionOpInterface : public ::mlir::OpInterface<SubsetInsertionOpInterface, detail::SubsetInsertionOpInterfaceInterfaceTraits> {
|
|
public:
|
|
using ::mlir::OpInterface<SubsetInsertionOpInterface, detail::SubsetInsertionOpInterfaceInterfaceTraits>::OpInterface;
|
|
template <typename ConcreteOp>
|
|
struct Trait : public detail::SubsetInsertionOpInterfaceTrait<ConcreteOp> {};
|
|
|
|
/// Return the source operand. The source operand can have any type.
|
|
::mlir::OpOperand &getSourceOperand();
|
|
|
|
/// Return the destination operand. The destination operand must be a
|
|
/// tensor.
|
|
///
|
|
/// This function does not have to be implemented for destination style
|
|
/// ops that have exactly one "init" operand.
|
|
::mlir::OpOperand &getDestinationOperand();
|
|
|
|
/// Return the updated destination result.
|
|
///
|
|
/// This function does not have to be implemented for destination style
|
|
/// ops.
|
|
::mlir::OpResult getUpdatedDestination();
|
|
|
|
/// Return "true" if this operation inserts into a subset that is
|
|
/// equivalent to the subset defined by `candidate`.
|
|
///
|
|
/// Two subsets are "equivalent" and "same" if they can bufferize to the
|
|
/// same buffer views/aliases. If they are "equivalent", the tensor IR
|
|
/// may be expressed in terms of different SSA values (but they could
|
|
/// bufferize to MemRef SSA values that can CSE without breaking
|
|
/// correctness). `equivalenceFn` should return "true" if the two given
|
|
/// values are equivalent.
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// // The subset of the SubsetInsertionOpInterface op %1 is equivalent to
|
|
/// // the subset defined by %2 (but not "same"):
|
|
/// %0 = arith.select %c, %t, %t : tensor<?xf32>
|
|
/// %1 = tensor.insert_slice %x into %0[0][5][1]
|
|
/// : tensor<5xf32> into tensor<?xf32>
|
|
/// %2 = tensor.extract_slice %t[0][5][1] : tensor<?xf32> to tensor<5xf32>
|
|
///
|
|
/// // The subset of the SubsetInsertionOpInterface op %1 is equivalent to
|
|
/// // and "same" as the subset defined by %2.
|
|
/// %1 = tensor.insert_slice %x into %t[0][5][1]
|
|
/// : tensor<5xf32> into tensor<?xf32>
|
|
/// %2 = tensor.extract_slice %t[0][5][1] : tensor<?xf32> to tensor<5xf32>
|
|
/// ```
|
|
///
|
|
/// Note: By default, this function calls
|
|
/// `SubsetOpInterface::operatesOnEquivalentSubset`.
|
|
bool isEquivalentSubset(::mlir::Value candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
|
|
/// Return the subset of the destination tensor that this operation
|
|
/// inserts into.
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// // SubsetOpInterface op:
|
|
/// %0 = tensor.insert_slice %t0 into %t1[%pos][5][1]
|
|
/// : tensor<5xf32> into tensor<?xf32>
|
|
/// // Subset (built by this function):
|
|
/// %1 = tensor.extract_slice %t1[%pos][5][1]
|
|
/// : tensor<?xf32> to tensor<5xf32>
|
|
/// ```
|
|
///
|
|
/// Note: Implementations do not necessarily have to build new IR. They
|
|
/// may return existing SSA values.
|
|
::mlir::Value buildSubsetExtraction(::mlir::OpBuilder & builder, Location loc);
|
|
|
|
/// Return all SSA values that are needed (i.e., must be in scope) at the
|
|
/// insertion of the builder when calling `buildSubsetExtraction`. Users
|
|
/// of `buildSubsetExtraction` can use this helper method to find a
|
|
/// suitable insertion point.
|
|
///
|
|
/// Example: The SSA values needed to build the subset in the example of
|
|
/// `buildSubsetExtraction` are %t1 and %pos.
|
|
::llvm::SmallVector<::mlir::Value> getValuesNeededToBuildSubsetExtraction();
|
|
|
|
/// Return "true" if this operation inserts into the same subset as defined
|
|
/// by `candidate`.
|
|
///
|
|
/// Note: This function is useful outside of bufferization, where no tensor
|
|
/// equivalence information is available.
|
|
bool isSameSubset(OpResult candidate) {
|
|
auto subsetOp = cast<::mlir::SubsetInsertionOpInterface>(
|
|
getOperation());
|
|
return subsetOp.isEquivalentSubset(
|
|
candidate, [](Value v1, Value v2) { return v1 == v2; });
|
|
}
|
|
//===----------------------------------------------------------------===//
|
|
// Inherited from ::mlir::SubsetOpInterface
|
|
//===----------------------------------------------------------------===//
|
|
|
|
operator ::mlir::SubsetOpInterface () const {
|
|
if (!*this) return nullptr;
|
|
return ::mlir::SubsetOpInterface(*this, getImpl()->implSubsetOpInterface);
|
|
}
|
|
|
|
|
|
/// Return "true" if this op and the given candidate subset op operate on
|
|
/// equivalent subsets. Return "false" if the two subsets are disjoint
|
|
/// or cannot be proven to be equivalent.
|
|
///
|
|
/// This interface method does not have to be implemented if
|
|
/// `getAccessedHyperrectangularSlice` is implemented.
|
|
bool operatesOnEquivalentSubset(::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
|
|
/// Return "true" if this op and the given candidate subset op operate on
|
|
/// disjoint subsets. Return "false" if the two subsets are equivalent,
|
|
/// overlapping or cannot be proven to be disjoint.
|
|
///
|
|
/// This interface method does not have to be implemented if
|
|
/// `getAccessedHyperrectangularSlice` is implemented.
|
|
bool operatesOnDisjointSubset(::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn);
|
|
|
|
/// If this op operates on a hyperrectangular subset, return a
|
|
/// description of the subset in terms of offsets, sizes and strides.
|
|
/// Otherwise, return "failure".
|
|
///
|
|
/// This interface method is a convenience method for the most common case
|
|
/// of hyperrectangular subset ops. It is optional. If it is implemented,
|
|
/// `operatesOnEquivalentSubset` and `operatesOnDisjointSubset` do not
|
|
/// have to be implemented.
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> getAccessedHyperrectangularSlice();
|
|
|
|
/// Return the container that this operation is operating on. In case of an
|
|
/// extraction op, the container is the source tensor. In case of an
|
|
/// insertion op, the container is the destination tensor.
|
|
Value getTensorContainer() {
|
|
return ::mlir::detail::getTensorContainer(getOperation());
|
|
}
|
|
};
|
|
|
|
} // namespace mlir
|
|
namespace mlir::detail {
|
|
|
|
template <typename ConcreteOp>
|
|
struct SubsetOpInterfaceTrait : public ::mlir::OpInterface<SubsetOpInterface, detail::SubsetOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {
|
|
|
|
/// Return "true" if this op and the given candidate subset op operate on
|
|
/// equivalent subsets. Return "false" if the two subsets are disjoint
|
|
/// or cannot be proven to be equivalent.
|
|
///
|
|
/// This interface method does not have to be implemented if
|
|
/// `getAccessedHyperrectangularSlice` is implemented.
|
|
bool operatesOnEquivalentSubset(::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return ::mlir::detail::defaultOperatesOnEquivalentSubset(
|
|
(*static_cast<ConcreteOp *>(this)), candidate, equivalenceFn);
|
|
}
|
|
|
|
/// Return "true" if this op and the given candidate subset op operate on
|
|
/// disjoint subsets. Return "false" if the two subsets are equivalent,
|
|
/// overlapping or cannot be proven to be disjoint.
|
|
///
|
|
/// This interface method does not have to be implemented if
|
|
/// `getAccessedHyperrectangularSlice` is implemented.
|
|
bool operatesOnDisjointSubset(::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return ::mlir::detail::defaultOperatesOnDisjointSubset(
|
|
(*static_cast<ConcreteOp *>(this)), candidate, equivalenceFn);
|
|
}
|
|
|
|
/// If this op operates on a hyperrectangular subset, return a
|
|
/// description of the subset in terms of offsets, sizes and strides.
|
|
/// Otherwise, return "failure".
|
|
///
|
|
/// This interface method is a convenience method for the most common case
|
|
/// of hyperrectangular subset ops. It is optional. If it is implemented,
|
|
/// `operatesOnEquivalentSubset` and `operatesOnDisjointSubset` do not
|
|
/// have to be implemented.
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> getAccessedHyperrectangularSlice() {
|
|
return ::mlir::failure();
|
|
}
|
|
static ::llvm::LogicalResult verifyTrait(::mlir::Operation *op) {
|
|
return ::mlir::detail::verifySubsetOpInterface(
|
|
::mlir::cast<::mlir::SubsetOpInterface>(op));
|
|
}
|
|
};
|
|
|
|
} // namespace mlir::detail
|
|
namespace mlir::detail {
|
|
|
|
template <typename ConcreteOp>
|
|
struct SubsetExtractionOpInterfaceTrait : public ::mlir::OpInterface<SubsetExtractionOpInterface, detail::SubsetExtractionOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {
|
|
static ::llvm::LogicalResult verifyTrait(::mlir::Operation *op) {
|
|
return ::mlir::detail::verifySubsetExtractionOpInterface(
|
|
::mlir::cast<::mlir::SubsetExtractionOpInterface>(op));
|
|
}
|
|
};
|
|
|
|
} // namespace mlir::detail
|
|
namespace mlir::detail {
|
|
|
|
template <typename ConcreteOp>
|
|
struct SubsetInsertionOpInterfaceTrait : public ::mlir::OpInterface<SubsetInsertionOpInterface, detail::SubsetInsertionOpInterfaceInterfaceTraits>::Trait<ConcreteOp> {
|
|
|
|
/// Return the destination operand. The destination operand must be a
|
|
/// tensor.
|
|
///
|
|
/// This function does not have to be implemented for destination style
|
|
/// ops that have exactly one "init" operand.
|
|
::mlir::OpOperand &getDestinationOperand() {
|
|
return ::mlir::detail::defaultGetDestinationOperand(
|
|
(*static_cast<ConcreteOp *>(this)).getOperation());
|
|
}
|
|
|
|
/// Return the updated destination result.
|
|
///
|
|
/// This function does not have to be implemented for destination style
|
|
/// ops.
|
|
::mlir::OpResult getUpdatedDestination() {
|
|
return ::mlir::detail::defaultGetUpdatedDestination(
|
|
(*static_cast<ConcreteOp *>(this)).getOperation());
|
|
}
|
|
|
|
/// Return "true" if this operation inserts into a subset that is
|
|
/// equivalent to the subset defined by `candidate`.
|
|
///
|
|
/// Two subsets are "equivalent" and "same" if they can bufferize to the
|
|
/// same buffer views/aliases. If they are "equivalent", the tensor IR
|
|
/// may be expressed in terms of different SSA values (but they could
|
|
/// bufferize to MemRef SSA values that can CSE without breaking
|
|
/// correctness). `equivalenceFn` should return "true" if the two given
|
|
/// values are equivalent.
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// // The subset of the SubsetInsertionOpInterface op %1 is equivalent to
|
|
/// // the subset defined by %2 (but not "same"):
|
|
/// %0 = arith.select %c, %t, %t : tensor<?xf32>
|
|
/// %1 = tensor.insert_slice %x into %0[0][5][1]
|
|
/// : tensor<5xf32> into tensor<?xf32>
|
|
/// %2 = tensor.extract_slice %t[0][5][1] : tensor<?xf32> to tensor<5xf32>
|
|
///
|
|
/// // The subset of the SubsetInsertionOpInterface op %1 is equivalent to
|
|
/// // and "same" as the subset defined by %2.
|
|
/// %1 = tensor.insert_slice %x into %t[0][5][1]
|
|
/// : tensor<5xf32> into tensor<?xf32>
|
|
/// %2 = tensor.extract_slice %t[0][5][1] : tensor<?xf32> to tensor<5xf32>
|
|
/// ```
|
|
///
|
|
/// Note: By default, this function calls
|
|
/// `SubsetOpInterface::operatesOnEquivalentSubset`.
|
|
bool isEquivalentSubset(::mlir::Value candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return ::mlir::detail::defaultIsEquivalentSubset(
|
|
(*static_cast<ConcreteOp *>(this)).getOperation(), candidate, equivalenceFn);
|
|
}
|
|
};
|
|
|
|
} // namespace mlir::detail
|
|
namespace mlir {
|
|
|
|
template<typename ConcreteOp>
|
|
bool detail::SubsetOpInterfaceInterfaceTraits::Model<ConcreteOp>::operatesOnEquivalentSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).operatesOnEquivalentSubset(candidate, equivalenceFn);
|
|
}
|
|
template<typename ConcreteOp>
|
|
bool detail::SubsetOpInterfaceInterfaceTraits::Model<ConcreteOp>::operatesOnDisjointSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).operatesOnDisjointSubset(candidate, equivalenceFn);
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> detail::SubsetOpInterfaceInterfaceTraits::Model<ConcreteOp>::getAccessedHyperrectangularSlice(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getAccessedHyperrectangularSlice();
|
|
}
|
|
template<typename ConcreteOp>
|
|
bool detail::SubsetOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::operatesOnEquivalentSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return static_cast<const ConcreteOp *>(impl)->operatesOnEquivalentSubset(tablegen_opaque_val, candidate, equivalenceFn);
|
|
}
|
|
template<typename ConcreteOp>
|
|
bool detail::SubsetOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::operatesOnDisjointSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return static_cast<const ConcreteOp *>(impl)->operatesOnDisjointSubset(tablegen_opaque_val, candidate, equivalenceFn);
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> detail::SubsetOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getAccessedHyperrectangularSlice(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return static_cast<const ConcreteOp *>(impl)->getAccessedHyperrectangularSlice(tablegen_opaque_val);
|
|
}
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
bool detail::SubsetOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::operatesOnEquivalentSubset(::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) const {
|
|
return ::mlir::detail::defaultOperatesOnEquivalentSubset(
|
|
(llvm::cast<ConcreteOp>(tablegen_opaque_val)), candidate, equivalenceFn);
|
|
}
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
bool detail::SubsetOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::operatesOnDisjointSubset(::mlir::Operation *tablegen_opaque_val, ::mlir::SubsetOpInterface candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) const {
|
|
return ::mlir::detail::defaultOperatesOnDisjointSubset(
|
|
(llvm::cast<ConcreteOp>(tablegen_opaque_val)), candidate, equivalenceFn);
|
|
}
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
::mlir::FailureOr<::mlir::HyperrectangularSlice> detail::SubsetOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getAccessedHyperrectangularSlice(::mlir::Operation *tablegen_opaque_val) const {
|
|
return ::mlir::failure();
|
|
}
|
|
|
|
} // namespace mlir
|
|
namespace mlir {
|
|
|
|
template<typename ConcreteOp>
|
|
::mlir::OpOperand &detail::SubsetExtractionOpInterfaceInterfaceTraits::Model<ConcreteOp>::getSourceOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getSourceOperand();
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::OpOperand &detail::SubsetExtractionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getSourceOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return static_cast<const ConcreteOp *>(impl)->getSourceOperand(tablegen_opaque_val);
|
|
}
|
|
|
|
} // namespace mlir
|
|
namespace mlir {
|
|
|
|
template<typename ConcreteOp>
|
|
::mlir::OpOperand &detail::SubsetInsertionOpInterfaceInterfaceTraits::Model<ConcreteOp>::getSourceOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getSourceOperand();
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::OpOperand &detail::SubsetInsertionOpInterfaceInterfaceTraits::Model<ConcreteOp>::getDestinationOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getDestinationOperand();
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::OpResult detail::SubsetInsertionOpInterfaceInterfaceTraits::Model<ConcreteOp>::getUpdatedDestination(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getUpdatedDestination();
|
|
}
|
|
template<typename ConcreteOp>
|
|
bool detail::SubsetInsertionOpInterfaceInterfaceTraits::Model<ConcreteOp>::isEquivalentSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Value candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).isEquivalentSubset(candidate, equivalenceFn);
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::Value detail::SubsetInsertionOpInterfaceInterfaceTraits::Model<ConcreteOp>::buildSubsetExtraction(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::OpBuilder & builder, Location loc) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).buildSubsetExtraction(builder, loc);
|
|
}
|
|
template<typename ConcreteOp>
|
|
::llvm::SmallVector<::mlir::Value> detail::SubsetInsertionOpInterfaceInterfaceTraits::Model<ConcreteOp>::getValuesNeededToBuildSubsetExtraction(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return (llvm::cast<ConcreteOp>(tablegen_opaque_val)).getValuesNeededToBuildSubsetExtraction();
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::OpOperand &detail::SubsetInsertionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getSourceOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return static_cast<const ConcreteOp *>(impl)->getSourceOperand(tablegen_opaque_val);
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::OpOperand &detail::SubsetInsertionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getDestinationOperand(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return static_cast<const ConcreteOp *>(impl)->getDestinationOperand(tablegen_opaque_val);
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::OpResult detail::SubsetInsertionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getUpdatedDestination(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return static_cast<const ConcreteOp *>(impl)->getUpdatedDestination(tablegen_opaque_val);
|
|
}
|
|
template<typename ConcreteOp>
|
|
bool detail::SubsetInsertionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::isEquivalentSubset(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::Value candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) {
|
|
return static_cast<const ConcreteOp *>(impl)->isEquivalentSubset(tablegen_opaque_val, candidate, equivalenceFn);
|
|
}
|
|
template<typename ConcreteOp>
|
|
::mlir::Value detail::SubsetInsertionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::buildSubsetExtraction(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::OpBuilder & builder, Location loc) {
|
|
return static_cast<const ConcreteOp *>(impl)->buildSubsetExtraction(tablegen_opaque_val, builder, loc);
|
|
}
|
|
template<typename ConcreteOp>
|
|
::llvm::SmallVector<::mlir::Value> detail::SubsetInsertionOpInterfaceInterfaceTraits::FallbackModel<ConcreteOp>::getValuesNeededToBuildSubsetExtraction(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) {
|
|
return static_cast<const ConcreteOp *>(impl)->getValuesNeededToBuildSubsetExtraction(tablegen_opaque_val);
|
|
}
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
::mlir::OpOperand &detail::SubsetInsertionOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getDestinationOperand(::mlir::Operation *tablegen_opaque_val) const {
|
|
return ::mlir::detail::defaultGetDestinationOperand(
|
|
(llvm::cast<ConcreteOp>(tablegen_opaque_val)).getOperation());
|
|
}
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
::mlir::OpResult detail::SubsetInsertionOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::getUpdatedDestination(::mlir::Operation *tablegen_opaque_val) const {
|
|
return ::mlir::detail::defaultGetUpdatedDestination(
|
|
(llvm::cast<ConcreteOp>(tablegen_opaque_val)).getOperation());
|
|
}
|
|
template<typename ConcreteModel, typename ConcreteOp>
|
|
bool detail::SubsetInsertionOpInterfaceInterfaceTraits::ExternalModel<ConcreteModel, ConcreteOp>::isEquivalentSubset(::mlir::Operation *tablegen_opaque_val, ::mlir::Value candidate, ::llvm::function_ref<bool(Value, Value)> equivalenceFn) const {
|
|
return ::mlir::detail::defaultIsEquivalentSubset(
|
|
(llvm::cast<ConcreteOp>(tablegen_opaque_val)).getOperation(), candidate, equivalenceFn);
|
|
}
|
|
|
|
} // namespace mlir
|