37 for (
auto op : device.getOps<TokenOp>()) {
39 op->getAttrOfType<StringAttr>(::mlir::SymbolTable::getSymbolAttrName())
41 int value = op.getTokenValue();
42 tokenSymbols[tokenName] = value;
46 std::map<StringRef, SmallVector<UseTokenOp, 4>> visitors;
47 device.getBodyRegion().walk([&](Operation *Op) {
48 if (
auto op = dyn_cast<UseTokenOp>(Op)) {
49 StringRef tokenName = op.getTokenName();
50 assert(tokenSymbols.find(tokenName) != tokenSymbols.end() &&
53 tokenMapPushBack(tokenAcqMap, tokenName, op.getOperation());
54 visitors[tokenName].push_back(op);
56 tokenMapPushBack(tokenRelMap, tokenName, op.getOperation());
57 if (!visitors[tokenName].empty()) {
58 Operation *Op = visitors[tokenName].pop_back_val();
59 tokenPairs.push_back({Op, op.getOperation()});
62 }
else if (
auto op = dyn_cast<MemcpyOp>(Op)) {
63 StringRef tokenName = op.getTokenName();
64 assert(tokenSymbols.find(tokenName) != tokenSymbols.end() &&
66 Operation *Op = op.getOperation();
67 tokenMapPushBack(tokenAcqMap, tokenName, op.getOperation());
68 tokenMapPushBack(tokenRelMap, tokenName, op.getOperation());
69 tokenPairs.push_back({Op, Op});
75 for (
const auto &map : tokenAcqMap) {
76 StringRef tokenName = map.first;
77 for (
auto *Op : map.second) {
78 [[maybe_unused]]
bool isReleased =
false;
79 if (
auto op = dyn_cast<MemcpyOp>(Op))
82 for (
auto pair : tokenPairs) {
83 if (UseTokenOp aop = dyn_cast<UseTokenOp>(pair.first)) {
84 if (tokenName == aop.getTokenName() && Op == aop.getOperation()) {
91 assert(isReleased &&
"No release found for acquire!"
92 "This might potentially lead to deadlock");
102 for (
const auto &map : tokenRelMap) {
103 StringRef tokenName = map.first;
104 auto tokenRels = map.second;
105 auto tokenAcqs = [&]() {
106 for (
auto &pair : tokenAcqMap)
107 if (pair.first == tokenName)
109 return std::vector<Operation *>();
111 for (
auto *ROp : tokenRels) {
113 if (
auto op = dyn_cast<UseTokenOp>(ROp))
114 releaseValue = op.getTokenValue();
115 else if (
auto op = dyn_cast<MemcpyOp>(ROp))
116 releaseValue = op.getReleaseTokenValue();
118 for (
auto *AOp : tokenAcqs) {
120 if (
auto op = dyn_cast<UseTokenOp>(AOp))
121 acquireValue = op.getTokenValue();
122 else if (
auto op = dyn_cast<MemcpyOp>(AOp))
123 acquireValue = op.getAcquireTokenValue();
129 if (releaseValue != acquireValue)
132 tokenChains.push_back({ROp, AOp});
137 for (
auto tile : device.getOps<TileOp>()) {
138 int colIndex = tile.colIndex();
139 int rowIndex = tile.rowIndex();
140 tiles[{colIndex, rowIndex}] = tile;
161 if (CoreOp core = dyn_cast<CoreOp>(Op)) {
162 colIndex = core.colIndex();
163 rowIndex = core.rowIndex();
164 }
else if (MemOp mem = dyn_cast<MemOp>(Op)) {
165 colIndex = mem.colIndex();
166 rowIndex = mem.rowIndex();
167 }
else if (ShimDMAOp shimDma = dyn_cast<ShimDMAOp>(Op)) {
168 colIndex = shimDma.colIndex();
169 rowIndex = shimDma.rowIndex();
172 return {colIndex, rowIndex};
177 bool IsOp1Mem = isa<MemOp>(Op1) || isa<ShimDMAOp>(Op1);
178 bool IsOp2Mem = isa<MemOp>(Op2) || isa<ShimDMAOp>(Op2);
180 assert((!IsOp1Mem || !IsOp2Mem) &&
181 "Op1 and Op2 cannot be both Mem operation!");
186 int col1 = coord1.col;
187 int row1 = coord1.row;
188 int col2 = coord2.col;
189 int row2 = coord2.row;
193 bool IsOp1ShareableMem =
194 IsOp1Mem && targetModel.isLegalMemAffinity(col2, row2, col1, row1);
195 bool IsOp2ShareableMem =
196 IsOp2Mem && targetModel.isLegalMemAffinity(col1, row1, col2, row2);
198 if (IsOp1ShareableMem)
199 return tiles[coord1];
200 if (IsOp2ShareableMem)
201 return tiles[coord2];
204 if (!IsOp1Mem && !IsOp2Mem) {
205 bool IsS = targetModel.isSouth(col1, row1, col2, row2);
206 bool IsW = targetModel.isWest(col1, row1, col2, row2);
207 bool IsN = targetModel.isNorth(col1, row1, col2, row2);
208 bool IsE = targetModel.isEast(col1, row1, col2, row2);
209 bool IsInternal = targetModel.isInternal(col1, row1, col2, row2);
210 bool IsEvenRow = ((row1 % 2) == 0);
213 if (IsS || IsN || (IsW && !IsEvenRow) || (IsE && IsEvenRow))
214 return tiles[coord2];
215 if ((IsW && IsEvenRow) || (IsE && !IsEvenRow) || IsInternal)
216 return tiles[coord1];
struct TileID { friend std::ostream &operator<<(std::ostream &os, const TileID &s) { os<< "TileID("<< s.col<< ", "<< s.row<< ")"; return os; } friend std::string to_string(const TileID &s) { std::ostringstream ss; ss<< s; return ss.str(); } friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const TileID &s) { os<< to_string(s); return os; } inline bool operator<(const TileID &rhs) const { return std::tie(col, row)< std::tie(rhs.col, rhs.row); } bool operator==(const TileID &rhs) const { return std::tie(col, row)==std::tie(rhs.col, rhs.row); } bool operator!=(const TileID &rhs) const { return !(*this==rhs);} int col, row;} TileID