41 DeviceOp device = getOperation();
42 OpBuilder rewriter = OpBuilder::atBlockTerminator(device.getBody());
47 DenseSet<int> assigned;
48 SmallVector<LockOp> unassigned;
51 DenseMap<TileOp, TileLockOps> tileToLocks;
54 device.walk<WalkOrder::PreOrder>([&](LockOp lockOp) {
55 TileOp tileOp = lockOp.getTileOp();
56 if (lockOp.getLockID().has_value()) {
57 auto lockID = lockOp.getLockID().value();
58 auto iter = tileToLocks.find(tileOp);
59 if (iter == tileToLocks.end())
60 tileToLocks.insert({tileOp, {{lockID}, {}}});
62 if (iter->second.assigned.find(lockID) !=
63 iter->second.assigned.end()) {
64 auto diag = lockOp->emitOpError(
"is assigned to the same lock (")
65 << lockID <<
") as another op.";
66 diag.attachNote(tileOp.getLoc())
67 <<
"tile has lock ops assigned to same lock.";
68 return signalPassFailure();
70 iter->second.assigned.insert(lockID);
73 auto iter = tileToLocks.find(tileOp);
74 if (iter == tileToLocks.end())
75 tileToLocks.insert({tileOp, { {}, {lockOp}}});
77 iter->second.unassigned.push_back(lockOp);
82 for (
auto [tileOp, locks] : tileToLocks) {
83 const auto locksPerTile =
86 for (
auto lockOp : locks.unassigned) {
87 while (nextID < locksPerTile &&
88 (locks.assigned.find(nextID) != locks.assigned.end())) {
91 if (nextID == locksPerTile) {
92 mlir::InFlightDiagnostic diag =
93 lockOp->emitOpError(
"not allocated a lock.");
94 diag.attachNote(tileOp.getLoc()) <<
"because only " << locksPerTile
95 <<
" locks available in this tile.";
96 return signalPassFailure();
98 lockOp.setLockIDAttr(rewriter.getI32IntegerAttr(nextID));