MLIR-AIE 1.4.5.dev
AIELowerMulticast.cpp
Go to the documentation of this file.
1//===- AIELowerMulticast.cpp ------------------------------------*- C++ -*-===//
2//
3// Copyright (C) 2020-2022 Xilinx, Inc.
4// Copyright (C) 2022-2026 Advanced Micro Devices, Inc.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12
13#include "mlir/IR/Attributes.h"
14#include "mlir/IR/PatternMatch.h"
15#include "mlir/Pass/Pass.h"
16#include "mlir/Tools/mlir-translate/MlirTranslateMain.h"
17#include "mlir/Transforms/DialectConversion.h"
18
19#include "llvm/ADT/Twine.h"
20
21namespace xilinx::AIEX {
22#define GEN_PASS_DEF_AIEMULTICAST
23#include "aie/Dialect/AIEX/Transforms/AIEXPasses.h.inc"
24} // namespace xilinx::AIEX
25
26#define DEBUG_TYPE "aie-lower-multicast"
27
28using namespace mlir;
29using namespace xilinx;
30using namespace xilinx::AIE;
31using namespace xilinx::AIEX;
32
33template <typename MyOp>
34struct AIEOpRemoval : public OpConversionPattern<MyOp> {
35 using OpConversionPattern<MyOp>::OpConversionPattern;
36 using OpAdaptor = typename MyOp::Adaptor;
37
38 AIEOpRemoval(MLIRContext *context, PatternBenefit benefit = 1)
39 : OpConversionPattern<MyOp>(context, benefit) {}
40
41 LogicalResult
42 matchAndRewrite(MyOp op, OpAdaptor adaptor,
43 ConversionPatternRewriter &rewriter) const override {
44 Operation *Op = op.getOperation();
45
46 rewriter.eraseOp(Op);
47 return success();
48 }
49};
50
52 : public xilinx::AIEX::impl::AIEMulticastBase<AIELowerMulticastPass> {
53 void runOnOperation() override {
54
55 DeviceOp device = getOperation();
56 OpBuilder builder = OpBuilder::atBlockTerminator(device.getBody());
57
58 for (auto multicast : device.getOps<MulticastOp>()) {
59 Region &r = multicast.getPorts();
60 Block &b = r.front();
61 Port sourcePort = multicast.port();
62 TileOp srcTile = cast<TileOp>(multicast.getTile().getDefiningOp());
63 for (Operation &Op : b.getOperations()) {
64 if (MultiDestOp multiDest = dyn_cast<MultiDestOp>(Op)) {
65 TileOp destTile = cast<TileOp>(multiDest.getTile().getDefiningOp());
66 Port destPort = multiDest.port();
67 FlowOp::create(builder, multiDest.getLoc(), srcTile,
68 sourcePort.bundle, sourcePort.channel, destTile,
69 destPort.bundle, destPort.channel);
70 }
71 }
72 }
73
74 ConversionTarget target(getContext());
75 RewritePatternSet patterns(&getContext());
76
77 patterns.add<AIEOpRemoval<MulticastOp>>(device.getContext());
78
79 if (failed(applyPartialConversion(device, target, std::move(patterns))))
80 signalPassFailure();
81 }
82};
83
84std::unique_ptr<OperationPass<DeviceOp>>
86 return std::make_unique<AIELowerMulticastPass>();
87}
std::unique_ptr< mlir::OperationPass< AIE::DeviceOp > > createAIELowerMulticastPass()
struct Port { WireBundle bundle; int channel; bool operator==(const Port &rhs) const { return std::tie(bundle, channel)==std::tie(rhs.bundle, rhs.channel); } bool operator!=(const Port &rhs) const { return !(*this==rhs);} bool operator<(const Port &rhs) const { return std::tie(bundle, channel)< std::tie(rhs.bundle, rhs.channel); } friend std::ostream &operator<<(std::ostream &os, const Port &port) { os<< "("; os<< stringifyWireBundle(port.bundle).str(); os<< ": "<< std::to_string(port.channel)<< ")"; return os; } friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Port &port) { os<< to_string(port); return os; } } Port
Definition AIEDialect.h:265
void runOnOperation() override
AIEOpRemoval(MLIRContext *context, PatternBenefit benefit=1)
typename MyOp::Adaptor OpAdaptor
LogicalResult matchAndRewrite(MyOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override