34 DeviceOp device = getOperation();
35 const auto &targetModel = device.getTargetModel();
36 OpBuilder builder = OpBuilder::atBlockTerminator(device.getBody());
38 DenseSet<TileOp> tilesWithCascadeFlow;
39 DenseMap<TileOp, WireBundle> cascadeInputsPerTile;
40 DenseMap<TileOp, WireBundle> cascadeOutputsPerTile;
43 for (
auto cascadeFlow : device.getOps<CascadeFlowOp>()) {
45 TileOp src = cascadeFlow.getSourceTileOp();
46 TileOp dst = cascadeFlow.getDestTileOp();
47 tilesWithCascadeFlow.insert(src);
48 tilesWithCascadeFlow.insert(dst);
50 if (targetModel.isSouth(src.getCol(), src.getRow(), dst.getCol(),
52 cascadeInputsPerTile[dst] = WireBundle::North;
53 cascadeOutputsPerTile[src] = WireBundle::South;
54 }
else if (targetModel.isEast(src.getCol(), src.getRow(), dst.getCol(),
56 cascadeInputsPerTile[dst] = WireBundle::West;
57 cascadeOutputsPerTile[src] = WireBundle::East;
60 cascadeFlow.emitOpError(
61 "source tile must be to the North or West of the destination tile");
62 return signalPassFailure();
67 for (TileOp tile : device.getOps<TileOp>()) {
68 if (!tilesWithCascadeFlow.contains(tile))
71 if (cascadeInputsPerTile.find(tile) != cascadeInputsPerTile.end()) {
72 inputDir = cascadeInputsPerTile[tile];
74 inputDir = WireBundle::North;
77 if (cascadeOutputsPerTile.find(tile) != cascadeOutputsPerTile.end()) {
78 outputDir = cascadeOutputsPerTile[tile];
80 outputDir = WireBundle::South;
82 ConfigureCascadeOp::create(builder, tile.getLoc(), tile,
83 static_cast<CascadeDir
>(inputDir),
84 static_cast<CascadeDir
>(outputDir));
88 SetVector<Operation *> opsToErase;
89 device.walk([&](Operation *op) {
90 if (isa<CascadeFlowOp>(op))
91 opsToErase.insert(op);
93 IRRewriter rewriter(&getContext());
94 for (
auto it = opsToErase.rbegin(); it != opsToErase.rend(); ++it)