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