12#include "mlir/IR/Location.h"
13#include "mlir/IR/PatternMatch.h"
14#include "mlir/Transforms/DialectConversion.h"
19#define GEN_PASS_DEF_AIEPLACETILES
20#include "aie/Dialect/AIE/Transforms/AIEPasses.h.inc"
23#define DEBUG_TYPE "aie-place-tiles"
31struct ConvertLogicalTileToTile : OpConversionPattern<LogicalTileOp> {
32 ConvertLogicalTileToTile(MLIRContext *context, DeviceOp &d,
Placer &p,
33 PatternBenefit benefit = 1)
34 : OpConversionPattern(context, benefit), device(d), placer(p) {}
37 matchAndRewrite(LogicalTileOp logicalTile, OpAdaptor adaptor,
38 ConversionPatternRewriter &rewriter)
const override {
39 auto placement = placer.getPlacement(logicalTile);
41 return logicalTile.emitError(
"no placement found for logical tile");
44 TileOp tileOp = TileOp::getOrCreate(rewriter, device, placement->col,
45 placement->row, logicalTile.getLoc());
46 rewriter.modifyOpInPlace(tileOp, [&] {
48 rewriter.getFusedLoc({tileOp.getLoc(), logicalTile.getLoc()}));
51 if (
auto controllerId = logicalTile->getAttr(
"controller_id"))
52 tileOp->setAttr(
"controller_id", controllerId);
54 rewriter.replaceOp(logicalTile, tileOp.getResult());
63struct AIEPlaceTilesPass
64 : xilinx::AIE::impl::AIEPlaceTilesBase<AIEPlaceTilesPass> {
66 AIEPlaceTilesPass() =
default;
68 AIEPlaceTilesPass(
const AIEPlaceTilesOptions &options)
69 : AIEPlaceTilesBase(options) {}
71 void runOnOperation()
override {
72 DeviceOp device = getOperation();
75 std::shared_ptr<Placer> placer;
76 std::shared_ptr<SAPlacer> saPlacer;
77 switch (clPlacerType) {
79 std::optional<int> coresPerCol = std::nullopt;
80 if (clCoresPerCol >= 0)
81 coresPerCol = clCoresPerCol;
82 placer = std::make_shared<SequentialPlacer>(
83 coresPerCol, clMergeLogicalTiles, clSpreadUnanchoredTiles);
87 double effort = clSAEffort.getValue();
88 if (!std::isfinite(effort) || effort <= 0) {
89 device.emitError(
"sa-effort must be positive and finite, got ")
91 return signalPassFailure();
95 placer = saPlacer = std::make_shared<SAPlacer>(clSASeed, config);
100 placer->initialize(device.getTargetModel());
101 if (failed(placer->place(device)))
102 return signalPassFailure();
104 saFinalCost += saPlacer->getFinalCost();
106 ConversionTarget target(getContext());
107 target.addLegalOp<TileOp>();
108 target.addIllegalOp<LogicalTileOp>();
109 target.addLegalDialect<AIEDialect>();
111 RewritePatternSet patterns(&getContext());
112 patterns.add<ConvertLogicalTileToTile>(device.getContext(), device,
115 if (failed(applyPartialConversion(device, target, std::move(patterns))))
116 return signalPassFailure();
119 auto &allocs = placer->getAllocates();
120 if (!allocs.empty()) {
122 llvm::DenseSet<Operation *> emitted;
123 for (
auto &[fifoOp, delegateTileID] : allocs) {
124 if (emitted.count(fifoOp))
126 emitted.insert(fifoOp);
128 auto ofOp = dyn_cast<ObjectFifoCreateOp>(fifoOp);
133 OpBuilder builder(ofOp->getContext());
134 builder.setInsertionPointAfter(ofOp);
136 TileOp delegateTile =
137 TileOp::getOrCreate(builder, device, delegateTileID.col,
138 delegateTileID.row, ofOp.getLoc());
139 ObjectFifoAllocateOp::create(
140 builder, ofOp.getLoc(),
141 SymbolRefAttr::get(builder.getContext(), ofOp.getSymName()),
142 delegateTile.getResult());
151 return std::make_unique<AIEPlaceTilesPass>();
154std::unique_ptr<OperationPass<DeviceOp>>
156 return std::make_unique<AIEPlaceTilesPass>(options);
std::unique_ptr< mlir::OperationPass< DeviceOp > > createAIEPlaceTilesPass()