/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\ |* *| |* Interface Declarations *| |* *| |* Automatically generated file, do not edit! *| |* *| \*===----------------------------------------------------------------------===*/ namespace mlir { /// Encodes properties of an operation on vectors that can be unrolled. class VectorUnrollOpInterface; } // namespace mlir namespace mlir { /// Encodes properties of a `vector.transfer_read` or `vector.transfer_write` /// operation. Vector transfer ops have: /// /// - A shaped value that the op reads from/writes to: a memref or a tensor. /// - A vector, either as a result or as an operand. /// - Indices that describe where the transfer from/to the shaped value starts. /// - An optional mask. /// - An optional in_bounds array to indicate transfer dimensions that are /// guaranteed to be in-bounds. /// - A permutation map to indicate transposes and broadcasts. /// /// The "vector rank" is the rank of the vector type. E.g.: /// ``` /// // Transfer with shaped value rank 2 and vector (transfer) rank 1. /// %0 = vector.transfer_read %arg0[%c3, %c3], %f0 /// {permutation_map = affine_map<(d0, d1) -> (d0)>} /// : memref, vector<128xf32> /// ``` /// /// The "vector transfer rank" is the number of dimensions that participate in /// the transfer and broadcasts, and matches the number of results in the /// permutation map. In most cases, the vector rank matches the vector transfer /// rank; the only exception is when a vector is flattened as part of the /// transfer (see `getPermutationMap`). class VectorTransferOpInterface; } // namespace mlir namespace mlir { /// Encodes properties of an operation on vectors that can be unrolled. namespace detail { struct VectorUnrollOpInterfaceInterfaceTraits { struct Concept { /// The methods defined by the interface. ::std::optional<::llvm::SmallVector> (*getShapeForUnroll)(const Concept *impl, ::mlir::Operation *); }; template class Model : public Concept { public: using Interface = ::mlir::VectorUnrollOpInterface; Model() : Concept{getShapeForUnroll} {} static inline ::std::optional<::llvm::SmallVector> getShapeForUnroll(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); }; template class FallbackModel : public Concept { public: using Interface = ::mlir::VectorUnrollOpInterface; FallbackModel() : Concept{getShapeForUnroll} {} static inline ::std::optional<::llvm::SmallVector> getShapeForUnroll(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); }; template class ExternalModel : public FallbackModel { public: using ConcreteEntity = ConcreteOp; ::std::optional<::llvm::SmallVector> getShapeForUnroll(::mlir::Operation *tablegen_opaque_val) const; }; }; template struct VectorUnrollOpInterfaceTrait; } // namespace detail class VectorUnrollOpInterface : public ::mlir::OpInterface { public: using ::mlir::OpInterface::OpInterface; template struct Trait : public detail::VectorUnrollOpInterfaceTrait {}; /// Return the shape ratio of unrolling to the target vector shape /// `targetShape`. Return `std::nullopt` if the op cannot be unrolled to the /// target vector shape. ::std::optional<::llvm::SmallVector> getShapeForUnroll(); }; } // namespace mlir namespace mlir { /// Encodes properties of a `vector.transfer_read` or `vector.transfer_write` /// operation. Vector transfer ops have: /// /// - A shaped value that the op reads from/writes to: a memref or a tensor. /// - A vector, either as a result or as an operand. /// - Indices that describe where the transfer from/to the shaped value starts. /// - An optional mask. /// - An optional in_bounds array to indicate transfer dimensions that are /// guaranteed to be in-bounds. /// - A permutation map to indicate transposes and broadcasts. /// /// The "vector rank" is the rank of the vector type. E.g.: /// ``` /// // Transfer with shaped value rank 2 and vector (transfer) rank 1. /// %0 = vector.transfer_read %arg0[%c3, %c3], %f0 /// {permutation_map = affine_map<(d0, d1) -> (d0)>} /// : memref, vector<128xf32> /// ``` /// /// The "vector transfer rank" is the number of dimensions that participate in /// the transfer and broadcasts, and matches the number of results in the /// permutation map. In most cases, the vector rank matches the vector transfer /// rank; the only exception is when a vector is flattened as part of the /// transfer (see `getPermutationMap`). namespace detail { struct VectorTransferOpInterfaceInterfaceTraits { struct Concept { /// The methods defined by the interface. ::mlir::StringRef (*getInBoundsAttrName)(const Concept *impl, ::mlir::Operation *); ::mlir::StringRef (*getPermutationMapAttrName)(const Concept *impl, ::mlir::Operation *); ::mlir::ArrayAttr (*getInBounds)(const Concept *impl, ::mlir::Operation *); ::mlir::Value (*getBase)(const Concept *impl, ::mlir::Operation *); ::mlir::Value (*getVector)(const Concept *impl, ::mlir::Operation *); ::mlir::VectorType (*getVectorType)(const Concept *impl, ::mlir::Operation *); ::mlir::OperandRange (*getIndices)(const Concept *impl, ::mlir::Operation *); ::mlir::AffineMap (*getPermutationMap)(const Concept *impl, ::mlir::Operation *); Value (*getMask)(const Concept *impl, ::mlir::Operation *); ::mlir::LogicalResult (*mayUpdateStartingPosition)(const Concept *impl, ::mlir::Operation *, ::mlir::ShapedType, ::mlir::AffineMap); void (*updateStartingPosition)(const Concept *impl, ::mlir::Operation *, ::mlir::RewriterBase&, ::mlir::Value, ::mlir::ValueRange, ::mlir::AffineMapAttr); }; template class Model : public Concept { public: using Interface = ::mlir::VectorTransferOpInterface; Model() : Concept{getInBoundsAttrName, getPermutationMapAttrName, getInBounds, getBase, getVector, getVectorType, getIndices, getPermutationMap, getMask, mayUpdateStartingPosition, updateStartingPosition} {} static inline ::mlir::StringRef getInBoundsAttrName(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::StringRef getPermutationMapAttrName(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::ArrayAttr getInBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::Value getBase(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::Value getVector(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::VectorType getVectorType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::OperandRange getIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::AffineMap getPermutationMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline Value getMask(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::LogicalResult mayUpdateStartingPosition(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::ShapedType newBaseType, ::mlir::AffineMap newPermutationMap); static inline void updateStartingPosition(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newBase, ::mlir::ValueRange newIndices, ::mlir::AffineMapAttr newPermutationMap); }; template class FallbackModel : public Concept { public: using Interface = ::mlir::VectorTransferOpInterface; FallbackModel() : Concept{getInBoundsAttrName, getPermutationMapAttrName, getInBounds, getBase, getVector, getVectorType, getIndices, getPermutationMap, getMask, mayUpdateStartingPosition, updateStartingPosition} {} static inline ::mlir::StringRef getInBoundsAttrName(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::StringRef getPermutationMapAttrName(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::ArrayAttr getInBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::Value getBase(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::Value getVector(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::VectorType getVectorType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::OperandRange getIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::AffineMap getPermutationMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline Value getMask(const Concept *impl, ::mlir::Operation *tablegen_opaque_val); static inline ::mlir::LogicalResult mayUpdateStartingPosition(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::ShapedType newBaseType, ::mlir::AffineMap newPermutationMap); static inline void updateStartingPosition(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newBase, ::mlir::ValueRange newIndices, ::mlir::AffineMapAttr newPermutationMap); }; template class ExternalModel : public FallbackModel { public: using ConcreteEntity = ConcreteOp; ::mlir::LogicalResult mayUpdateStartingPosition(::mlir::Operation *tablegen_opaque_val, ::mlir::ShapedType newBaseType, ::mlir::AffineMap newPermutationMap) const; void updateStartingPosition(::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase&rewriter, ::mlir::Value newBase, ::mlir::ValueRange newIndices, ::mlir::AffineMapAttr newPermutationMap) const; }; }; template struct VectorTransferOpInterfaceTrait; } // namespace detail class VectorTransferOpInterface : public ::mlir::OpInterface { public: using ::mlir::OpInterface::OpInterface; template struct Trait : public detail::VectorTransferOpInterfaceTrait {}; /// Return the `in_bounds` attribute name. ::mlir::StringRef getInBoundsAttrName(); /// Return the `permutation_map` attribute name. ::mlir::StringRef getPermutationMapAttrName(); /// Return the optional in_bounds attribute that specifies for each vector /// dimension whether it is in-bounds or not. (Broadcast dimensions are /// always in-bounds). ::mlir::ArrayAttr getInBounds(); /// Return the memref or ranked tensor operand that this operation operates /// on. In case of a "read" operation, that's the source from which the /// operation reads. In case of a "write" operation, that's the destination /// into which the operation writes. /// TODO: Change name of operand, which is not accurate for xfer_write. ::mlir::Value getBase(); /// Return the vector that this operation operates on. In case of a "read", /// that's the vector OpResult. In case of a "write", that's the vector /// operand value that is written by the op. ::mlir::Value getVector(); /// Return the type of the vector that this operation operates on. ::mlir::VectorType getVectorType(); /// Return the indices that specify the starting offsets into the source /// operand. The starting offsets are guaranteed to be in-bounds except /// when the transfer operation is masked or the `in_bounds` array doesn't /// specify that that dimension is not necessarily in bounds. It is undefinied /// behavior if these guarantees are violated. ::mlir::OperandRange getIndices(); /// Return the permutation map that describes the mapping of vector /// dimensions to source dimensions, as well as broadcast dimensions. /// /// The permutation result has one result per vector transfer dimension. /// Each result is either a dim expression, indicating the corresponding /// dimension in the source operand, or a constant "0" expression, /// indicating a broadcast dimension. /// /// Note: Nested vector dimensions that are flattened by this op are not /// accounted for in the permutation map. E.g.: /// ``` /// // Vector type has rank 4, but permutation map has only 2 results. That /// // is because there are only 2 transfer dimensions. /// %0 = vector.transfer_read %arg1[%c3, %c3], %vf0 /// {permutation_map = affine_map<(d0, d1) -> (d0, d1)>} /// : memref>, vector<1x1x4x3xf32> /// ``` ::mlir::AffineMap getPermutationMap(); /// Return the mask operand if the op has a mask. Otherwise, return an /// empty value. Value getMask(); /// Returns whether replacing the base operand with a shaped value of /// `newBaseType` and updating the permutation map according to /// `newPermutationMap`, where the replacement would adhere to the /// conditions specified by `updateStartingPosition`, passes any additional /// op-specific constraints. ::mlir::LogicalResult mayUpdateStartingPosition(::mlir::ShapedType newBaseType, ::mlir::AffineMap newPermutationMap); /// Updates the base of this transfer operation to `newBase`, the indices into /// that base into `newIndices`, and the permutation map to `newPermutationMap`. /// The new base, indices, and map must: /// - Keep the same element type as the base (this condition could be relaxed /// in the future) /// - Preserve the number of transfer dimensions and avoid inserting new /// dimensions unaccounted for in the permutation map - that is, if the transfer operation is /// reading or writing a 4x2 vector to/from an Nx4x2 tensor or memref, it is /// not valid to update that base to an Nx8 one, but updating in an N0xN1x4x2 /// base - or even an Nx16x32 one - is acceptable. Similarly, if the transfer /// rank is 2 and the base is MxN, replacing it with a base that is Mx1xN or /// MxKxN is only permitted if the permutation map is updated to skip the new /// dimension. This restriction means that the updater does not need to reshape /// or otherwise adjust the vector type of the transfer or other related attributes /// like the inbounds attribute array. /// - Must not shrink the size of a transfer dimension such that an `inbounds` /// annotation becomes incorrect. /// - Must pass any op-specific conditions in `mayUpdateStartingPosition` /// /// The update is performed in-place. Implementations of the interface /// should use `RewriterBase::modifyOpInPlace` to ensure proper pattern /// rewriter operation. void updateStartingPosition(::mlir::RewriterBase& rewriter, ::mlir::Value newBase, ::mlir::ValueRange newIndices, ::mlir::AffineMapAttr newPermutationMap); /// Return a vector of all in_bounds values as booleans (one per vector /// transfer dimension). ::llvm::SmallVector getInBoundsValues() { ::llvm::SmallVector inBounds; for (int64_t i = 0, e = (*this).getTransferRank(); i < e; ++i) inBounds.push_back((*this).isDimInBounds(i)); return inBounds; } /// Return the number of leading shaped dimensions (of the "source" operand) /// that do not participate in the permutation map. unsigned getLeadingShapedRank() { return (*this).getShapedType().getRank() - (*this).getTransferRank(); } /// Return the mask type if the op has a mask. Otherwise, return an empty /// VectorType. ::mlir::VectorType getMaskType() { return (*this).getMask() ? ::llvm::cast<::mlir::VectorType>((*this).getMask().getType()) : ::mlir::VectorType(); } /// Return the shaped type of the "source" operand value. ::mlir::ShapedType getShapedType() { return ::llvm::cast<::mlir::ShapedType>((*this).getBase().getType()); } /// Return the number of dimensions that participate in the permutation map. unsigned getTransferRank() { return (*this).getPermutationMap().getNumResults(); } /// Return "true" if at least one of the vector dimensions is a broadcasted /// dimension. bool hasBroadcastDim() { for (unsigned i = 0, e = (*this).getTransferRank(); i < e; ++i) { if ((*this).isBroadcastDim(i)) return true; } return false; } /// Return "true" if at least one of the vector dimensions may be /// out-of-bounds. bool hasOutOfBoundsDim() { for (unsigned idx = 0, e = (*this).getTransferRank(); idx < e; ++idx) if (!(*this).isDimInBounds(idx)) return true; return false; } /// Return "true" if the specified vector transfer dimension is a /// broadcasted dimension. bool isBroadcastDim(unsigned dim) { auto expr = (*this).getPermutationMap().getResult(dim); auto constExpr = ::llvm::dyn_cast<::mlir::AffineConstantExpr>(expr); return constExpr && constExpr.getValue() == 0; } /// Return "true" if the vector transfer dimension `dim` is in-bounds. /// Return "false" otherwise. bool isDimInBounds(unsigned dim) { auto inBounds = (*this).getInBounds(); return ::llvm::cast<::mlir::BoolAttr>(inBounds[dim]).getValue(); } /// Helper function to account for the fact that `permutationMap` results /// and `op.getIndices` sizes may not match and may not be aligned. The /// first `getLeadingShapedRank()` indices may just be indexed and not /// transferred from/into the vector. /// For example: /// ``` /// vector.transfer %0[%i, %j, %k, %c0] /// : memref, vector<2x4xf32> /// ``` /// with `permutation_map = (d0, d1, d2, d3) -> (d2, d3)`. /// Provide a zip function to coiterate on 2 running indices: `resultIdx` /// and `indicesIdx` which accounts for this misalignment. void zipResultAndIndexing( ::llvm::function_ref fun) { for (int64_t resultIdx = 0, indicesIdx = (*this).getLeadingShapedRank(), eResult = (*this).getTransferRank(); resultIdx < eResult; ++resultIdx, ++indicesIdx) fun(resultIdx, indicesIdx); } /// Return the shape of the hyperrectangular slice within the tensor/memref /// operand that is accessed by the transfer op. /// For example: /// ``` /// vector.transfer %w0[%i, %j, %k] { /// permutation_map = affine_map<(d0, d1, d2) -> (d1, d0, 0)>} : /// : tensor, vector<4x2x6xf32> /// ``` /// returns a shape [2, 4, 1]. SmallVector getTransferChunkAccessed() { SmallVector dimSizes((*this).getPermutationMap().getNumDims(), 1); for (auto vecDims : llvm::zip((*this).getPermutationMap().getResults(), (*this).getVectorType().getShape())) { AffineExpr dim = std::get<0>(vecDims); int64_t size = std::get<1>(vecDims); // Skip broadcast. if (::llvm::isa(dim)) continue; dimSizes[::llvm::cast(dim).getPosition()] = size; } return dimSizes; } }; } // namespace mlir namespace mlir::detail { template struct VectorUnrollOpInterfaceTrait : public ::mlir::OpInterface::Trait { /// Return the shape ratio of unrolling to the target vector shape /// `targetShape`. Return `std::nullopt` if the op cannot be unrolled to the /// target vector shape. ::std::optional<::llvm::SmallVector> getShapeForUnroll() { assert((*static_cast(this))->getNumResults() == 1); auto vt = ::llvm::dyn_cast<::mlir::VectorType>((*static_cast(this)).getResult().getType()); if (!vt) return ::std::nullopt; ::llvm::SmallVector res( vt.getShape().begin(), vt.getShape().end()); return res; } }; } // namespace mlir::detail namespace mlir::detail { template struct VectorTransferOpInterfaceTrait : public ::mlir::OpInterface::Trait { /// Returns whether replacing the base operand with a shaped value of /// `newBaseType` and updating the permutation map according to /// `newPermutationMap`, where the replacement would adhere to the /// conditions specified by `updateStartingPosition`, passes any additional /// op-specific constraints. ::mlir::LogicalResult mayUpdateStartingPosition(::mlir::ShapedType newBaseType, ::mlir::AffineMap newPermutationMap) { return ::mlir::success(); } /// Updates the base of this transfer operation to `newBase`, the indices into /// that base into `newIndices`, and the permutation map to `newPermutationMap`. /// The new base, indices, and map must: /// - Keep the same element type as the base (this condition could be relaxed /// in the future) /// - Preserve the number of transfer dimensions and avoid inserting new /// dimensions unaccounted for in the permutation map - that is, if the transfer operation is /// reading or writing a 4x2 vector to/from an Nx4x2 tensor or memref, it is /// not valid to update that base to an Nx8 one, but updating in an N0xN1x4x2 /// base - or even an Nx16x32 one - is acceptable. Similarly, if the transfer /// rank is 2 and the base is MxN, replacing it with a base that is Mx1xN or /// MxKxN is only permitted if the permutation map is updated to skip the new /// dimension. This restriction means that the updater does not need to reshape /// or otherwise adjust the vector type of the transfer or other related attributes /// like the inbounds attribute array. /// - Must not shrink the size of a transfer dimension such that an `inbounds` /// annotation becomes incorrect. /// - Must pass any op-specific conditions in `mayUpdateStartingPosition` /// /// The update is performed in-place. Implementations of the interface /// should use `RewriterBase::modifyOpInPlace` to ensure proper pattern /// rewriter operation. void updateStartingPosition(::mlir::RewriterBase& rewriter, ::mlir::Value newBase, ::mlir::ValueRange newIndices, ::mlir::AffineMapAttr newPermutationMap) { rewriter.modifyOpInPlace((*static_cast(this)), [&]() { (*static_cast(this)).getBaseMutable().assign(newBase); (*static_cast(this)).getIndicesMutable().assign(newIndices); (*static_cast(this)).setPermutationMapAttr(newPermutationMap); }); } /// Return a vector of all in_bounds values as booleans (one per vector /// transfer dimension). ::llvm::SmallVector getInBoundsValues() { ::llvm::SmallVector inBounds; for (int64_t i = 0, e = (*static_cast(this)).getTransferRank(); i < e; ++i) inBounds.push_back((*static_cast(this)).isDimInBounds(i)); return inBounds; } /// Return the number of leading shaped dimensions (of the "source" operand) /// that do not participate in the permutation map. unsigned getLeadingShapedRank() { return (*static_cast(this)).getShapedType().getRank() - (*static_cast(this)).getTransferRank(); } /// Return the mask type if the op has a mask. Otherwise, return an empty /// VectorType. ::mlir::VectorType getMaskType() { return (*static_cast(this)).getMask() ? ::llvm::cast<::mlir::VectorType>((*static_cast(this)).getMask().getType()) : ::mlir::VectorType(); } /// Return the shaped type of the "source" operand value. ::mlir::ShapedType getShapedType() { return ::llvm::cast<::mlir::ShapedType>((*static_cast(this)).getBase().getType()); } /// Return the number of dimensions that participate in the permutation map. unsigned getTransferRank() { return (*static_cast(this)).getPermutationMap().getNumResults(); } /// Return "true" if at least one of the vector dimensions is a broadcasted /// dimension. bool hasBroadcastDim() { for (unsigned i = 0, e = (*static_cast(this)).getTransferRank(); i < e; ++i) { if ((*static_cast(this)).isBroadcastDim(i)) return true; } return false; } /// Return "true" if at least one of the vector dimensions may be /// out-of-bounds. bool hasOutOfBoundsDim() { for (unsigned idx = 0, e = (*static_cast(this)).getTransferRank(); idx < e; ++idx) if (!(*static_cast(this)).isDimInBounds(idx)) return true; return false; } /// Return "true" if the specified vector transfer dimension is a /// broadcasted dimension. bool isBroadcastDim(unsigned dim) { auto expr = (*static_cast(this)).getPermutationMap().getResult(dim); auto constExpr = ::llvm::dyn_cast<::mlir::AffineConstantExpr>(expr); return constExpr && constExpr.getValue() == 0; } /// Return "true" if the vector transfer dimension `dim` is in-bounds. /// Return "false" otherwise. bool isDimInBounds(unsigned dim) { auto inBounds = (*static_cast(this)).getInBounds(); return ::llvm::cast<::mlir::BoolAttr>(inBounds[dim]).getValue(); } /// Helper function to account for the fact that `permutationMap` results /// and `op.getIndices` sizes may not match and may not be aligned. The /// first `getLeadingShapedRank()` indices may just be indexed and not /// transferred from/into the vector. /// For example: /// ``` /// vector.transfer %0[%i, %j, %k, %c0] /// : memref, vector<2x4xf32> /// ``` /// with `permutation_map = (d0, d1, d2, d3) -> (d2, d3)`. /// Provide a zip function to coiterate on 2 running indices: `resultIdx` /// and `indicesIdx` which accounts for this misalignment. void zipResultAndIndexing( ::llvm::function_ref fun) { for (int64_t resultIdx = 0, indicesIdx = (*static_cast(this)).getLeadingShapedRank(), eResult = (*static_cast(this)).getTransferRank(); resultIdx < eResult; ++resultIdx, ++indicesIdx) fun(resultIdx, indicesIdx); } /// Return the shape of the hyperrectangular slice within the tensor/memref /// operand that is accessed by the transfer op. /// For example: /// ``` /// vector.transfer %w0[%i, %j, %k] { /// permutation_map = affine_map<(d0, d1, d2) -> (d1, d0, 0)>} : /// : tensor, vector<4x2x6xf32> /// ``` /// returns a shape [2, 4, 1]. SmallVector getTransferChunkAccessed() { SmallVector dimSizes((*static_cast(this)).getPermutationMap().getNumDims(), 1); for (auto vecDims : llvm::zip((*static_cast(this)).getPermutationMap().getResults(), (*static_cast(this)).getVectorType().getShape())) { AffineExpr dim = std::get<0>(vecDims); int64_t size = std::get<1>(vecDims); // Skip broadcast. if (::llvm::isa(dim)) continue; dimSizes[::llvm::cast(dim).getPosition()] = size; } return dimSizes; } }; } // namespace mlir::detail namespace mlir { template ::std::optional<::llvm::SmallVector> detail::VectorUnrollOpInterfaceInterfaceTraits::Model::getShapeForUnroll(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getShapeForUnroll(); } template ::std::optional<::llvm::SmallVector> detail::VectorUnrollOpInterfaceInterfaceTraits::FallbackModel::getShapeForUnroll(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getShapeForUnroll(tablegen_opaque_val); } template ::std::optional<::llvm::SmallVector> detail::VectorUnrollOpInterfaceInterfaceTraits::ExternalModel::getShapeForUnroll(::mlir::Operation *tablegen_opaque_val) const { assert((llvm::cast(tablegen_opaque_val))->getNumResults() == 1); auto vt = ::llvm::dyn_cast<::mlir::VectorType>((llvm::cast(tablegen_opaque_val)).getResult().getType()); if (!vt) return ::std::nullopt; ::llvm::SmallVector res( vt.getShape().begin(), vt.getShape().end()); return res; } } // namespace mlir namespace mlir { template ::mlir::StringRef detail::VectorTransferOpInterfaceInterfaceTraits::Model::getInBoundsAttrName(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getInBoundsAttrName(); } template ::mlir::StringRef detail::VectorTransferOpInterfaceInterfaceTraits::Model::getPermutationMapAttrName(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getPermutationMapAttrName(); } template ::mlir::ArrayAttr detail::VectorTransferOpInterfaceInterfaceTraits::Model::getInBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getInBounds(); } template ::mlir::Value detail::VectorTransferOpInterfaceInterfaceTraits::Model::getBase(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getBase(); } template ::mlir::Value detail::VectorTransferOpInterfaceInterfaceTraits::Model::getVector(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getVector(); } template ::mlir::VectorType detail::VectorTransferOpInterfaceInterfaceTraits::Model::getVectorType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getVectorType(); } template ::mlir::OperandRange detail::VectorTransferOpInterfaceInterfaceTraits::Model::getIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getIndices(); } template ::mlir::AffineMap detail::VectorTransferOpInterfaceInterfaceTraits::Model::getPermutationMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getPermutationMap(); } template Value detail::VectorTransferOpInterfaceInterfaceTraits::Model::getMask(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return (llvm::cast(tablegen_opaque_val)).getMask(); } template ::mlir::LogicalResult detail::VectorTransferOpInterfaceInterfaceTraits::Model::mayUpdateStartingPosition(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::ShapedType newBaseType, ::mlir::AffineMap newPermutationMap) { return (llvm::cast(tablegen_opaque_val)).mayUpdateStartingPosition(newBaseType, newPermutationMap); } template void detail::VectorTransferOpInterfaceInterfaceTraits::Model::updateStartingPosition(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newBase, ::mlir::ValueRange newIndices, ::mlir::AffineMapAttr newPermutationMap) { return (llvm::cast(tablegen_opaque_val)).updateStartingPosition(rewriter, newBase, newIndices, newPermutationMap); } template ::mlir::StringRef detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getInBoundsAttrName(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getInBoundsAttrName(tablegen_opaque_val); } template ::mlir::StringRef detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getPermutationMapAttrName(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getPermutationMapAttrName(tablegen_opaque_val); } template ::mlir::ArrayAttr detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getInBounds(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getInBounds(tablegen_opaque_val); } template ::mlir::Value detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getBase(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getBase(tablegen_opaque_val); } template ::mlir::Value detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getVector(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getVector(tablegen_opaque_val); } template ::mlir::VectorType detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getVectorType(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getVectorType(tablegen_opaque_val); } template ::mlir::OperandRange detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getIndices(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getIndices(tablegen_opaque_val); } template ::mlir::AffineMap detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getPermutationMap(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getPermutationMap(tablegen_opaque_val); } template Value detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::getMask(const Concept *impl, ::mlir::Operation *tablegen_opaque_val) { return static_cast(impl)->getMask(tablegen_opaque_val); } template ::mlir::LogicalResult detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::mayUpdateStartingPosition(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::ShapedType newBaseType, ::mlir::AffineMap newPermutationMap) { return static_cast(impl)->mayUpdateStartingPosition(tablegen_opaque_val, newBaseType, newPermutationMap); } template void detail::VectorTransferOpInterfaceInterfaceTraits::FallbackModel::updateStartingPosition(const Concept *impl, ::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase& rewriter, ::mlir::Value newBase, ::mlir::ValueRange newIndices, ::mlir::AffineMapAttr newPermutationMap) { return static_cast(impl)->updateStartingPosition(tablegen_opaque_val, rewriter, newBase, newIndices, newPermutationMap); } template ::mlir::LogicalResult detail::VectorTransferOpInterfaceInterfaceTraits::ExternalModel::mayUpdateStartingPosition(::mlir::Operation *tablegen_opaque_val, ::mlir::ShapedType newBaseType, ::mlir::AffineMap newPermutationMap) const { return ::mlir::success(); } template void detail::VectorTransferOpInterfaceInterfaceTraits::ExternalModel::updateStartingPosition(::mlir::Operation *tablegen_opaque_val, ::mlir::RewriterBase&rewriter, ::mlir::Value newBase, ::mlir::ValueRange newIndices, ::mlir::AffineMapAttr newPermutationMap) const { rewriter.modifyOpInPlace((llvm::cast(tablegen_opaque_val)), [&]() { (llvm::cast(tablegen_opaque_val)).getBaseMutable().assign(newBase); (llvm::cast(tablegen_opaque_val)).getIndicesMutable().assign(newIndices); (llvm::cast(tablegen_opaque_val)).setPermutationMapAttr(newPermutationMap); }); } } // namespace mlir