//===- VectorLinearize.cpp - vector linearization transforms --------------===// // // 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 // //===----------------------------------------------------------------------===// // // This file implements patterns and pass for linearizing ND vectors into 1D. // //===----------------------------------------------------------------------===// #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/Vector/IR/VectorOps.h" #include "mlir/Dialect/Vector/Transforms/VectorRewritePatterns.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Operation.h" #include "mlir/IR/PatternMatch.h" #include "mlir/IR/TypeUtilities.h" #include "mlir/Transforms/DialectConversion.h" #include "llvm/ADT/ArrayRef.h" #include <cstdint> #include <numeric> usingnamespacemlir; static bool isLessThanTargetBitWidth(Operation *op, unsigned targetBitWidth) { … } static bool isLessThanOrEqualTargetBitWidth(Type t, unsigned targetBitWidth) { … } namespace { struct LinearizeConstant final : OpConversionPattern<arith::ConstantOp> { … }; struct LinearizeVectorizable final : OpTraitConversionPattern<OpTrait::Vectorizable> { … }; /// This pattern converts the ExtractStridedSliceOp into a ShuffleOp that works /// on a linearized vector. /// Following, /// vector.extract_strided_slice %source /// { offsets = [..], strides = [..], sizes = [..] } /// is converted to : /// %source_1d = vector.shape_cast %source /// %out_1d = vector.shuffle %source_1d, %source_1d [ shuffle_indices_1d ] /// %out_nd = vector.shape_cast %out_1d /// `shuffle_indices_1d` is computed using the offsets and sizes of the /// extraction. struct LinearizeVectorExtractStridedSlice final : public mlir::OpConversionPattern<mlir::vector::ExtractStridedSliceOp> { … }; /// This pattern converts the ShuffleOp that works on nD (n > 1) /// vectors to a ShuffleOp that works on linearized vectors. /// Following, /// vector.shuffle %v1, %v2 [ shuffle_indices ] /// is converted to : /// %v1_1d = vector.shape_cast %v1 /// %v2_1d = vector.shape_cast %v2 /// %out_1d = vector.shuffle %v1_1d, %v2_1d [ shuffle_indices_1d ] /// %out_nd = vector.shape_cast %out_1d // `shuffle_indices_1d` is computed using the sizes and `shuffle_indices` /// of the original shuffle operation. struct LinearizeVectorShuffle final : public OpConversionPattern<vector::ShuffleOp> { … }; /// This pattern converts the ExtractOp to a ShuffleOp that works on a /// linearized vector. /// Following, /// vector.extract %source [ position ] /// is converted to : /// %source_1d = vector.shape_cast %source /// %out_1d = vector.shuffle %source_1d, %source_1d [ shuffle_indices_1d ] /// %out_nd = vector.shape_cast %out_1d /// `shuffle_indices_1d` is computed using the position of the original extract. struct LinearizeVectorExtract final : public OpConversionPattern<vector::ExtractOp> { … }; /// This pattern converts the InsertOp to a ShuffleOp that works on a /// linearized vector. /// Following, /// vector.insert %source %destination [ position ] /// is converted to : /// %source_1d = vector.shape_cast %source /// %destination_1d = vector.shape_cast %destination /// %out_1d = vector.shuffle %destination_1d, %source_1d [ shuffle_indices_1d /// ] %out_nd = vector.shape_cast %out_1d /// `shuffle_indices_1d` is computed using the position of the original insert. struct LinearizeVectorInsert final : public OpConversionPattern<vector::InsertOp> { … }; } // namespace void mlir::vector::populateVectorLinearizeTypeConversionsAndLegality( TypeConverter &typeConverter, RewritePatternSet &patterns, ConversionTarget &target, unsigned targetBitWidth) { … } void mlir::vector::populateVectorLinearizeShuffleLikeOpsPatterns( const TypeConverter &typeConverter, RewritePatternSet &patterns, ConversionTarget &target, unsigned int targetBitWidth) { … }