31 DeviceOp device = getOperation();
32 const auto &targetModel = device.getTargetModel();
33 OpBuilder builder = OpBuilder::atBlockTerminator(device.getBody());
35 std::set<TileOp> tilesWithCascadeFlow;
36 DenseMap<TileOp, WireBundle> cascadeInputsPerTile;
37 DenseMap<TileOp, WireBundle> cascadeOutputsPerTile;
40 for (
auto cascadeFlow : device.getOps<CascadeFlowOp>()) {
42 TileOp
src = cascadeFlow.getSourceTileOp();
43 TileOp
dst = cascadeFlow.getDestTileOp();
44 tilesWithCascadeFlow.insert(
src);
45 tilesWithCascadeFlow.insert(
dst);
47 if (targetModel.isSouth(
src.getCol(),
src.getRow(),
dst.getCol(),
49 cascadeInputsPerTile[
dst] = WireBundle::North;
50 cascadeOutputsPerTile[
src] = WireBundle::South;
51 }
else if (targetModel.isEast(
src.getCol(),
src.getRow(),
dst.getCol(),
53 cascadeInputsPerTile[
dst] = WireBundle::West;
54 cascadeOutputsPerTile[
src] = WireBundle::East;
57 cascadeFlow.emitOpError(
58 "source tile must be to the North or West of the destination tile");
64 for (TileOp tile : tilesWithCascadeFlow) {
66 if (cascadeInputsPerTile.find(tile) != cascadeInputsPerTile.end()) {
67 inputDir = cascadeInputsPerTile[tile];
69 inputDir = WireBundle::North;
72 if (cascadeOutputsPerTile.find(tile) != cascadeOutputsPerTile.end()) {
73 outputDir = cascadeOutputsPerTile[tile];
75 outputDir = WireBundle::South;
77 builder.create<ConfigureCascadeOp>(builder.getUnknownLoc(), tile,
78 static_cast<CascadeDir
>(inputDir),
79 static_cast<CascadeDir
>(outputDir));
83 SetVector<Operation *> opsToErase;
84 device.walk([&](Operation *op) {
85 if (isa<CascadeFlowOp>(op))
86 opsToErase.insert(op);
88 IRRewriter rewriter(&getContext());
89 for (
auto it = opsToErase.rbegin(); it != opsToErase.rend(); ++it)