36 DeviceOp device = getOperation();
37 const auto &targetModel = device.getTargetModel();
38 OpBuilder builder = OpBuilder::atBlockTerminator(device.getBody());
40 std::set<TileOp> tilesWithCascadeFlow;
41 DenseMap<TileOp, WireBundle> cascadeInputsPerTile;
42 DenseMap<TileOp, WireBundle> cascadeOutputsPerTile;
45 for (
auto cascadeFlow : device.getOps<CascadeFlowOp>()) {
47 TileOp
src = cascadeFlow.getSourceTileOp();
48 TileOp
dst = cascadeFlow.getDestTileOp();
49 tilesWithCascadeFlow.insert(
src);
50 tilesWithCascadeFlow.insert(
dst);
52 if (targetModel.isSouth(
src.getCol(),
src.getRow(),
dst.getCol(),
54 cascadeInputsPerTile[
dst] = WireBundle::North;
55 cascadeOutputsPerTile[
src] = WireBundle::South;
56 }
else if (targetModel.isEast(
src.getCol(),
src.getRow(),
dst.getCol(),
58 cascadeInputsPerTile[
dst] = WireBundle::West;
59 cascadeOutputsPerTile[
src] = WireBundle::East;
62 cascadeFlow.emitOpError(
63 "source tile must be to the North or West of the destination tile");
64 return signalPassFailure();
69 for (TileOp tile : tilesWithCascadeFlow) {
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, builder.getUnknownLoc(), 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)