37 DeviceOp device = getOperation();
38 OpBuilder rewriter = OpBuilder::atBlockTerminator(device.getBody());
43 DenseSet<int> assigned;
44 SmallVector<LockOp> unassigned;
47 DenseMap<TileOp, TileLockOps> tileToLocks;
50 device.walk<WalkOrder::PreOrder>([&](LockOp lockOp) {
51 TileOp tileOp = lockOp.getTileOp();
52 if (lockOp.getLockID().has_value()) {
53 auto lockID = lockOp.getLockID().value();
54 auto iter = tileToLocks.find(tileOp);
55 if (iter == tileToLocks.end())
56 tileToLocks.insert({tileOp, {{lockID}, {}}});
58 if (iter->second.assigned.find(lockID) !=
59 iter->second.assigned.end()) {
60 auto diag = lockOp->emitOpError(
"is assigned to the same lock (")
61 << lockID <<
") as another op.";
62 diag.attachNote(tileOp.getLoc())
63 <<
"tile has lock ops assigned to same lock.";
64 return signalPassFailure();
66 iter->second.assigned.insert(lockID);
69 auto iter = tileToLocks.find(tileOp);
70 if (iter == tileToLocks.end())
71 tileToLocks.insert({tileOp, { {}, {lockOp}}});
73 iter->second.unassigned.push_back(lockOp);
78 for (
auto [tileOp, locks] : tileToLocks) {
79 const auto locksPerTile =
82 for (
auto lockOp : locks.unassigned) {
83 while (nextID < locksPerTile &&
84 (locks.assigned.find(nextID) != locks.assigned.end())) {
87 if (nextID == locksPerTile) {
88 mlir::InFlightDiagnostic diag =
89 lockOp->emitOpError(
"not allocated a lock.");
90 diag.attachNote(tileOp.getLoc()) <<
"because only " << locksPerTile
91 <<
" locks available in this tile.";
92 return signalPassFailure();
94 lockOp.setLockIDAttr(rewriter.getI32IntegerAttr(nextID));