43 DeviceOp device = getOperation();
44 OpBuilder rewriter = OpBuilder::atBlockTerminator(device.getBody());
49 DenseSet<int> assigned;
50 SmallVector<LockOp> unassigned;
53 DenseMap<TileOp, TileLockOps> tileToLocks;
56 device.walk<WalkOrder::PreOrder>([&](LockOp lockOp) {
57 TileOp tileOp = lockOp.getTileOp();
58 if (lockOp.getLockID().has_value()) {
59 auto lockID = lockOp.getLockID().value();
60 auto iter = tileToLocks.find(tileOp);
61 if (iter == tileToLocks.end())
62 tileToLocks.insert({tileOp, {{lockID}, {}}});
64 if (iter->second.assigned.find(lockID) !=
65 iter->second.assigned.end()) {
66 auto diag = lockOp->emitOpError(
"is assigned to the same lock (")
67 << lockID <<
") as another op.";
68 diag.attachNote(tileOp.getLoc())
69 <<
"tile has lock ops assigned to same lock.";
70 return signalPassFailure();
72 iter->second.assigned.insert(lockID);
75 auto iter = tileToLocks.find(tileOp);
76 if (iter == tileToLocks.end())
77 tileToLocks.insert({tileOp, { {}, {lockOp}}});
79 iter->second.unassigned.push_back(lockOp);
84 for (
auto [tileOp, locks] : tileToLocks) {
85 const auto locksPerTile =
88 for (
auto lockOp : locks.unassigned) {
89 while (nextID < locksPerTile &&
90 (locks.assigned.find(nextID) != locks.assigned.end())) {
93 if (nextID == locksPerTile) {
94 mlir::InFlightDiagnostic diag =
95 lockOp->emitOpError(
"not allocated a lock.");
96 diag.attachNote(tileOp.getLoc()) <<
"because only " << locksPerTile
97 <<
" locks available in this tile.";
98 return signalPassFailure();
100 lockOp.setLockIDAttr(rewriter.getI32IntegerAttr(nextID));