128 lines
5.3 KiB
C++
128 lines
5.3 KiB
C++
//===- VectorPattern.h - Conversion pattern to the LLVM dialect -*- C++ -*-===//
|
|
//
|
|
// 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 MLIR_CONVERSION_LLVMCOMMON_VECTORPATTERN_H
|
|
#define MLIR_CONVERSION_LLVMCOMMON_VECTORPATTERN_H
|
|
|
|
#include "mlir/Conversion/LLVMCommon/Pattern.h"
|
|
#include "mlir/Transforms/DialectConversion.h"
|
|
|
|
namespace mlir {
|
|
|
|
namespace LLVM {
|
|
namespace detail {
|
|
// Helper struct to "unroll" operations on n-D vectors in terms of operations on
|
|
// 1-D LLVM vectors.
|
|
struct NDVectorTypeInfo {
|
|
// LLVM array struct which encodes n-D vectors.
|
|
Type llvmNDVectorTy;
|
|
// LLVM vector type which encodes the inner 1-D vector type.
|
|
Type llvm1DVectorTy;
|
|
// Multiplicity of llvmNDVectorTy to llvm1DVectorTy.
|
|
SmallVector<int64_t, 4> arraySizes;
|
|
};
|
|
|
|
// For >1-D vector types, extracts the necessary information to iterate over all
|
|
// 1-D subvectors in the underlying llrepresentation of the n-D vector
|
|
// Iterates on the llvm array type until we hit a non-array type (which is
|
|
// asserted to be an llvm vector type).
|
|
NDVectorTypeInfo extractNDVectorTypeInfo(VectorType vectorType,
|
|
const LLVMTypeConverter &converter);
|
|
|
|
// Express `linearIndex` in terms of coordinates of `basis`.
|
|
// Returns the empty vector when linearIndex is out of the range [0, P] where
|
|
// P is the product of all the basis coordinates.
|
|
//
|
|
// Prerequisites:
|
|
// Basis is an array of nonnegative integers (signed type inherited from
|
|
// vector shape type).
|
|
SmallVector<int64_t, 4> getCoordinates(ArrayRef<int64_t> basis,
|
|
unsigned linearIndex);
|
|
|
|
// Iterate of linear index, convert to coords space and insert splatted 1-D
|
|
// vector in each position.
|
|
void nDVectorIterate(const NDVectorTypeInfo &info, OpBuilder &builder,
|
|
function_ref<void(ArrayRef<int64_t>)> fun);
|
|
|
|
LogicalResult handleMultidimensionalVectors(
|
|
Operation *op, ValueRange operands, const LLVMTypeConverter &typeConverter,
|
|
std::function<Value(Type, ValueRange)> createOperand,
|
|
ConversionPatternRewriter &rewriter);
|
|
|
|
LogicalResult vectorOneToOneRewrite(Operation *op, StringRef targetOp,
|
|
ValueRange operands,
|
|
ArrayRef<NamedAttribute> targetAttrs,
|
|
Attribute propertiesAttr,
|
|
const LLVMTypeConverter &typeConverter,
|
|
ConversionPatternRewriter &rewriter);
|
|
} // namespace detail
|
|
} // namespace LLVM
|
|
|
|
// Default attribute conversion class, which passes all source attributes
|
|
// through to the target op, unmodified. The attribute to set properties of the
|
|
// target operation will be nullptr (i.e. any properties that exist in will have
|
|
// default values).
|
|
template <typename SourceOp, typename TargetOp>
|
|
class AttrConvertPassThrough {
|
|
public:
|
|
AttrConvertPassThrough(SourceOp srcOp) : srcAttrs(srcOp->getAttrs()) {}
|
|
|
|
ArrayRef<NamedAttribute> getAttrs() const { return srcAttrs; }
|
|
Attribute getPropAttr() const { return {}; }
|
|
|
|
private:
|
|
ArrayRef<NamedAttribute> srcAttrs;
|
|
};
|
|
|
|
/// Basic lowering implementation to rewrite Ops with just one result to the
|
|
/// LLVM Dialect. This supports higher-dimensional vector types.
|
|
/// The AttrConvert template template parameter should:
|
|
// - be a template class with SourceOp and TargetOp type parameters
|
|
// - have a constructor that takes a SourceOp instance
|
|
// - a getAttrs() method that returns ArrayRef<NamedAttribute> containing
|
|
// attributes that the target operation will have
|
|
// - a getPropAttr() method that returns either a NULL attribute or a
|
|
// DictionaryAttribute with properties that exist for the target operation
|
|
template <typename SourceOp, typename TargetOp,
|
|
template <typename, typename> typename AttrConvert =
|
|
AttrConvertPassThrough,
|
|
bool FailOnUnsupportedFP = false>
|
|
class VectorConvertToLLVMPattern
|
|
: public ConvertOpToLLVMPattern<SourceOp, FailOnUnsupportedFP> {
|
|
public:
|
|
using ConvertOpToLLVMPattern<SourceOp,
|
|
FailOnUnsupportedFP>::ConvertOpToLLVMPattern;
|
|
using Super = VectorConvertToLLVMPattern<SourceOp, TargetOp>;
|
|
|
|
LogicalResult
|
|
matchAndRewrite(SourceOp op, typename SourceOp::Adaptor adaptor,
|
|
ConversionPatternRewriter &rewriter) const override {
|
|
static_assert(
|
|
std::is_base_of<OpTrait::OneResult<SourceOp>, SourceOp>::value,
|
|
"expected single result op");
|
|
|
|
// Bail on unsupported floating point types. (These are type-converted to
|
|
// integer types.)
|
|
if (FailOnUnsupportedFP && LLVM::detail::opHasUnsupportedFloatingPointTypes(
|
|
op, *this->typeConverter)) {
|
|
return rewriter.notifyMatchFailure(op, "unsupported floating point type");
|
|
}
|
|
|
|
// Determine attributes for the target op
|
|
AttrConvert<SourceOp, TargetOp> attrConvert(op);
|
|
|
|
return LLVM::detail::vectorOneToOneRewrite(
|
|
op, TargetOp::getOperationName(), adaptor.getOperands(),
|
|
attrConvert.getAttrs(), attrConvert.getPropAttr(),
|
|
*this->getTypeConverter(), rewriter);
|
|
}
|
|
};
|
|
} // namespace mlir
|
|
|
|
#endif // MLIR_CONVERSION_LLVMCOMMON_VECTORPATTERN_H
|