189 DeviceOp device = getOperation();
190 OpBuilder builder(device.getBody()->getTerminator());
192 SmallVector<HerdOp, 4> herds;
193 SmallVector<Operation *, 4> placeOps;
194 SmallVector<Operation *, 4> routeOps;
195 DenseMap<std::pair<Operation *, Operation *>, std::pair<int, int>>
197 SmallVector<std::pair<std::pair<int, int>, std::pair<int, int>>, 4> routes;
198 DenseMap<std::pair<Operation *, TileID>, SmallVector<Connect, 8>>
201 for (
auto herd : device.getOps<HerdOp>())
202 herds.push_back(herd);
204 for (
auto placeOp : device.getOps<PlaceOp>()) {
205 placeOps.push_back(placeOp);
206 Operation *sourceHerd = placeOp.getSourceHerd().getDefiningOp();
207 Operation *destHerd = placeOp.getDestHerd().getDefiningOp();
208 int distX = placeOp.getDistXValue();
209 int distY = placeOp.getDistYValue();
210 distances[std::make_pair(sourceHerd, destHerd)] =
211 std::make_pair(distX, distY);
216 for (
auto routeOp : device.getOps<RouteOp>()) {
217 routeOps.push_back(routeOp);
220 dyn_cast<SelectOp>(routeOp.getSourceHerds().getDefiningOp());
222 dyn_cast<SelectOp>(routeOp.getDestHerds().getDefiningOp());
223 WireBundle sourceBundle = routeOp.getSourceBundle();
224 WireBundle destBundle = routeOp.getDestBundle();
225 int sourceChannel = routeOp.getSourceChannelValue();
226 int destChannel = routeOp.getDestChannelValue();
229 dyn_cast<HerdOp>(sourceHerds.getStartHerd().getDefiningOp());
231 dyn_cast<IterOp>(sourceHerds.getIterX().getDefiningOp());
233 dyn_cast<IterOp>(sourceHerds.getIterY().getDefiningOp());
236 dyn_cast<HerdOp>(destHerds.getStartHerd().getDefiningOp());
237 IterOp destIterX = dyn_cast<IterOp>(destHerds.getIterX().getDefiningOp());
238 IterOp destIterY = dyn_cast<IterOp>(destHerds.getIterY().getDefiningOp());
240 int sourceStartX = sourceIterX.getStartValue();
241 int sourceEndX = sourceIterX.getEndValue();
242 int sourceStrideX = sourceIterX.getStrideValue();
243 int sourceStartY = sourceIterY.getStartValue();
244 int sourceEndY = sourceIterY.getEndValue();
245 int sourceStrideY = sourceIterY.getStrideValue();
247 int destStartX = destIterX.getStartValue();
248 int destEndX = destIterX.getEndValue();
249 int destStrideX = destIterX.getStrideValue();
250 int destStartY = destIterY.getStartValue();
251 int destEndY = destIterY.getEndValue();
252 int destStrideY = destIterY.getStrideValue();
254 assert(distances.count(std::make_pair(sourceHerd, destHerd)) == 1);
256 auto [distX, distY] = distances[std::make_pair(sourceHerd, destHerd)];
258 for (
int xSrc = sourceStartX; xSrc < sourceEndX; xSrc += sourceStrideX)
259 for (
int ySrc = sourceStartY; ySrc < sourceEndY; ySrc += sourceStrideY)
260 for (
int xDst = destStartX; xDst < destEndX; xDst += destStrideX)
261 for (
int yDst = destStartY; yDst < destEndY; yDst += destStrideY) {
267 if (destIterX == sourceIterX)
269 if (destIterY == sourceIterX)
271 if (destIterX == sourceIterY)
273 if (destIterY == sourceIterY)
276 auto route = std::make_pair(
277 std::make_pair(x0, y0),
278 std::make_pair(distX + x1 - x0, distY + y1 - y0));
279 if (std::find(routes.begin(), routes.end(), route) !=
283 buildRoute(x0, y0, x1 + distX, y1 + distY, sourceBundle,
284 sourceChannel, destBundle, destChannel, sourceHerd,
287 routes.push_back(route);
291 for (
const auto &swboxCfg : switchboxes) {
292 Operation *herdOp = swboxCfg.first.first;
293 int x = swboxCfg.first.second.col;
294 int y = swboxCfg.first.second.row;
295 auto connects = swboxCfg.second;
296 HerdOp herd = dyn_cast<HerdOp>(herdOp);
298 builder.setInsertionPoint(device.getBody()->getTerminator());
300 auto iterx = builder.create<IterOp>(builder.getUnknownLoc(), x, x + 1, 1);
301 auto itery = builder.create<IterOp>(builder.getUnknownLoc(), y, y + 1, 1);
303 builder.create<SelectOp>(builder.getUnknownLoc(), herd, iterx, itery);
304 auto swbox = builder.create<SwitchboxOp>(builder.getUnknownLoc(), sel);
305 SwitchboxOp::ensureTerminator(swbox.getConnections(), builder,
306 builder.getUnknownLoc());
307 Block &b = swbox.getConnections().front();
308 builder.setInsertionPoint(b.getTerminator());
310 for (
auto [sourcePort, destPort] : connects) {
311 WireBundle sourceBundle = sourcePort.bundle;
312 int sourceChannel = sourcePort.channel;
313 WireBundle destBundle = destPort.bundle;
314 int destChannel = destPort.channel;
316 builder.create<ConnectOp>(builder.getUnknownLoc(), sourceBundle,
317 sourceChannel, destBundle, destChannel);
321 ConversionTarget target(getContext());
323 RewritePatternSet patterns(&getContext());
325 device.getContext());
327 if (failed(applyPartialConversion(device, target, std::move(patterns))))