MLIR-AIE 1.4.5.dev
ConvertVectorToAIEVec.cpp
Go to the documentation of this file.
1//===-ConvertVectorToAIEVec.cpp - Lower Vector to AIE vector ----*- C++ -*-===//
2//
3// Copyright (C) 2022 Xilinx, Inc.
4// Copyright (C) 2022-2025 Advanced Micro Devices, Inc.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8// This is the implementation of the lowering pass from standard Vector
9// dialect to AIEVec, compatible with the AIE vector architecture.
10//===----------------------------------------------------------------------===//
11
13
14#include "mlir/Dialect/Vector/Transforms/VectorTransforms.h"
15#include "mlir/IR/PatternMatch.h"
16#include "mlir/IR/TypeUtilities.h"
17#include "mlir/Pass/PassManager.h"
18#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
19#include "mlir/Transforms/Passes.h"
20
21namespace xilinx::aievec {
22#define GEN_PASS_DEF_LOWERVECTORTOAIEVEC
23#define GEN_PASS_DEF_CANONICALIZEFORAIEVEC
24#define GEN_PASS_DEF_REDUNDANTLOADSTOREOPTIMIZATION
25#define GEN_PASS_DEF_AIEVECTRANSFORMATION
26#define GEN_PASS_DEF_AIEVECCONVOPTRANSFORMATION
27
28#include "aie/Dialect/AIEVec/Transforms/Passes.h.inc"
29} // namespace xilinx::aievec
30
31using namespace mlir;
32using namespace arith;
33using namespace vector;
34using namespace xilinx;
35using namespace xilinx::aievec;
36
37#define DEBUG_TYPE "vector-to-aievec-conversion"
38
39//===----------------------------------------------------------------------===//
40// Rewrite patterns
41//===----------------------------------------------------------------------===//
42
43template <typename OpTy>
44struct SetInboundsToReadStoreOpPattern : public RewritePattern {
45 SetInboundsToReadStoreOpPattern(MLIRContext *context)
46 : RewritePattern(OpTy::getOperationName(), /*benefit=*/1, context) {}
47
48 LogicalResult matchAndRewrite(Operation *op,
49 PatternRewriter &rewriter) const override {
50 OpTy writeOrReadOp = cast<OpTy>(op);
51
52 // TODO: We are currently setting all `vector.transfer_read` and
53 // TODO: `vector.transfer_write` as "in bounds". We need to add
54 // TODO: an analysis to verify that this is true before doing so.
55 auto inBounds =
56 writeOrReadOp.getInBounds().template getAsValueRange<BoolAttr>();
57 if (std::all_of(inBounds.begin(), inBounds.end(),
58 [](bool v) { return v; }) ||
59 writeOrReadOp.getTransferRank() == 0)
60 return failure();
61
62 SmallVector<bool, 4> bools(writeOrReadOp.getTransferRank(), true);
63 auto inBoundsAttr = rewriter.getBoolArrayAttr(bools);
64 rewriter.modifyOpInPlace(writeOrReadOp, [&]() {
65 writeOrReadOp->setAttr(writeOrReadOp.getInBoundsAttrName(), inBoundsAttr);
66 });
67 return success();
68 }
69};
70
73
74//===----------------------------------------------------------------------===//
75// Lowering passes
76//===----------------------------------------------------------------------===//
77
79 : public PassWrapper<RedundantLoadStoreOptimizationPass, OperationPass<>> {
80
81 void runOnOperation() override {
82 auto *op = getOperation();
83 MLIRContext *context = &getContext();
84 RewritePatternSet patterns(context);
85
87 patterns.getContext());
88
89 (void)applyPatternsGreedily(op, std::move(patterns));
90 IRRewriter rewriter(&getContext());
91 vector::transferOpflowOpt(rewriter, op);
92 }
93};
94
95static std::unique_ptr<::mlir::Pass>
96createRedundantLoadStoreOptimizationPass() {
97 return std::make_unique<RedundantLoadStoreOptimizationPass>();
98}
99
100//===---------------------------------------------------------------------------
101// Pipeline implementations
102//===---------------------------------------------------------------------------
104 OpPassManager &pm, const ConvertVectorToAIEVecOptions &options) {
105
106 // Pre-conversion passes.
107 pm.addPass(createCanonicalizerPass());
108 pm.addPass(createRedundantLoadStoreOptimizationPass());
109
110 //============================================================================
111 // Vector canonicalization for AIEVec: Vector to Vector conversion.
112 //============================================================================
113
114 // NOTE: This sub-pipeline ingests arbitrary MLIR Vector code.
117 // NOTE: At this stage, all the Vector code in the IR can be mapped
118 // NOTE: to AIEVec operations.
119
120 //============================================================================
121 // Vector to AIEVec lowering: Vector to AIEVec conversion.
122 //============================================================================
123
124 // NOTE: This sub-pipeline ingests MLIR Vector code that can be mapped to
125 // NOTE: AIEVec operations.
127 // NOTE: At this stage, all vector operations are expressed in AIEVec dialect.
128
129 //============================================================================
130 // AIEVec optimization: AIEVec to AIEVec conversion.
131 //============================================================================
132
133 // NOTE: This sub-pipeline ingests AIEVec operations.
135
136 // Post-conversion passes.
137 pm.addPass(createLoopInvariantCodeMotionPass());
138 pm.addPass(createCanonicalizerPass());
139}
140
141//===---------------------------------------------------------------------------
142// Pipeline registration
143//===---------------------------------------------------------------------------
145 PassPipelineRegistration<ConvertVectorToAIEVecOptions>(
146 "convert-vector-to-aievec",
147 "This pass pipeline takes standard \"Vector\" code and converts it to "
148 "\"AIEVec\" code targeting the selected Xilinx AIE vector "
149 "architecture.",
151
152 PassPipelineRegistration<CanonicalizeVectorForAIEVecOptions>(
153 "canonicalize-vector-for-aievec",
154 "This pass pipeline takes standard \"Vector\" code and converts it to "
155 "\"Vector\" code compatible with the selected AIE vector architecture.",
157
158 PassPipelineRegistration<LowerVectorToAIEVecOptions>(
159 "lower-vector-to-aievec",
160 "This pass pipeline takes AIE-compatible \"Vector\" code and lowers it "
161 "to \"AIE\" vector code targeting the selected AIE vector "
162 "architecture.",
164
165 PassPipelineRegistration<OptimizeAIEVecOptions>(
166 "optimize-aievec",
167 "This pass pipeline takes AIE vector code and applies target-specific "
168 "optimizations.",
170
171 PassPipelineRegistration<>(
172 "dynamic-size-no-implicit-broadcast",
173 "This pass pipeline rewrites arith operations when assuming no implict "
174 "broadcast of dynamic sizes",
176}
SetInboundsToReadStoreOpPattern< TransferWriteOp > SetInboundsToWriteOp
SetInboundsToReadStoreOpPattern< TransferReadOp > SetInboundsToReadOp
void registerAIEVecPipelines()
Register all pipelines for the AIE Vector dialect.
void buildLowerVectorToAIEVec(mlir::OpPassManager &pm, const LowerVectorToAIEVecOptions &options)
void buildCanonicalizeVectorForAIEVec(mlir::OpPassManager &pm, const CanonicalizeVectorForAIEVecOptions &options)
void buildConvertVectorToAIEVec(mlir::OpPassManager &pm, const ConvertVectorToAIEVecOptions &options)
Adds the "convert-vector-to-aievec" pipeline to the OpPassManager.
void buildDynamicSizeNoImplicitBroadcastPass(mlir::OpPassManager &pm)
void buildOptimizeAIEVec(mlir::OpPassManager &pm, const OptimizeAIEVecOptions &options)
LogicalResult matchAndRewrite(Operation *op, PatternRewriter &rewriter) const override
SetInboundsToReadStoreOpPattern(MLIRContext *context)
Options for the "convert-vector-to-aievec" pipeline.
Definition Passes.h:74
const LowerVectorToAIEVecOptions & getLowerVectorToAIEVecOptions() const
Definition Passes.h:115
const CanonicalizeVectorForAIEVecOptions & getCanonicalizeVectorForAIEVecOptions() const
Definition Passes.h:120
const OptimizeAIEVecOptions & getOptimizeAIEVecOptions() const
Definition Passes.h:124