MLIR-AIE
AIETargetShared.cpp
Go to the documentation of this file.
1//===- AIETargetShared.cpp --------------------------------------*- C++ -*-===//
2//
3// Copyright (C) 2021 Xilinx Inc.
4// Copyright (C) 2021-2023, Advanced Micro Devices, Inc. All rights reserved.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//
8//===----------------------------------------------------------------------===//
9
11
15
16#include "mlir/Target/LLVMIR/Import.h"
17
18#include "llvm/ADT/StringExtras.h"
19
20using namespace mlir;
21using namespace xilinx;
22using namespace xilinx::AIE;
23using namespace xilinx::AIEX;
24
25namespace xilinx::AIE {
26
27std::string tileLocStr(StringRef col, StringRef row) {
28 std::string str;
29 llvm::raw_string_ostream rss(str);
30 rss << "XAie_TileLoc(" << col << "," << row << ")";
31 return str;
32}
33
34std::string tileLocStr(int col, int row) {
35 return tileLocStr(std::to_string(col), std::to_string(row));
36}
37
38std::string tileDMAInstStr(StringRef col, StringRef row, StringRef bdNum) {
39 std::string str;
40 llvm::raw_string_ostream rss(str);
41 rss << "dma_tile" << col << row << "_bd" << bdNum;
42 return str;
43}
44
45std::string tileDMAInstStr(int col, int row, int bdNum) {
46 return tileDMAInstStr(std::to_string(col), std::to_string(row),
47 std::to_string(bdNum));
48}
49
50std::string tileDMAInstRefStr(StringRef col, StringRef row, StringRef bdNum) {
51 std::string str;
52 llvm::raw_string_ostream rss(str);
53 rss << "&(" << tileDMAInstStr(col, row, bdNum) << ")";
54 return str;
55}
56
57std::string tileDMAInstRefStr(int col, int row, int bdNum) {
58 return tileDMAInstRefStr(std::to_string(col), std::to_string(row),
59 std::to_string(bdNum));
60}
61
62std::string packetStr(StringRef id, StringRef type) {
63 std::string str;
64 llvm::raw_string_ostream rss(str);
65 rss << "XAie_PacketInit(" << id << "," << type << ")";
66 return str;
67}
68
69std::string packetStr(int id, int type) {
70 return packetStr(std::to_string(id), std::to_string(type));
71}
72
73static std::string tileDMATensorStr(StringRef col, StringRef row,
74 StringRef bdNum) {
75 std::string str;
76 llvm::raw_string_ostream rss(str);
77 rss << "dma_tile_" << col << "_" << row << "_bd_" << bdNum << "_tensor";
78 return str;
79}
80
81static std::string tileDMATensorStr(int col, int row, int bdNum) {
82 return tileDMATensorStr(std::to_string(col), std::to_string(row),
83 std::to_string(bdNum));
84}
85
86void generateXAieDmaSetMultiDimAddr(raw_ostream &output, int ndims,
87 ArrayRef<BDDimLayoutAttr> dims, int col,
88 int row, int bdNum, int baseAddrA,
89 int offsetA, int lenA,
90 int elementWidthInBytes,
91 const char *errorRetval) {
92 // libxaie requires stride in multiples of 32b
93 double elementWidthIn32bWords =
94 static_cast<double>(elementWidthInBytes) / 4.0;
95 std::string tensor = tileDMATensorStr(col, row, bdNum);
96 output << "XAie_DmaTensor " << tensor << " = {};\n";
97 output << tensor << ".NumDim = " << std::to_string(ndims) << ";\n";
98 output << tensor
99 << ".Dim ="
100 "__mlir_aie_alloc_dim_desc("
101 << std::to_string(ndims) << ");\n";
102 output << "if(NULL == " << tensor << ".Dim){\n"
103 << " return " << errorRetval << ";\n"
104 << "}\n";
105 for (size_t i = 0; i < dims.size(); i++) {
106 uint16_t size;
107 uint32_t stride;
108 // Pass down dimensions in reverse order; in the MLIR, this allows us
109 // to specify strides/sizes in the same order as we would access a
110 // multi-dim C array, with the highest dimension first.
111 int j = dims.size() - i - 1;
112 if (j > 0) {
113 stride =
114 static_cast<uint32_t>(dims[i].getStride() * elementWidthIn32bWords);
115 size = dims[i].getSize();
116 } else {
117 stride = dims[i].getStride();
118 size = static_cast<uint16_t>(dims[i].getSize() * elementWidthIn32bWords);
119 }
120 stride = stride > 0 ? stride : 1;
121 // Assume AIE-ML architecture; we assert this above
122 output << tensor << ".Dim[" << std::to_string(j) << "].AieMlDimDesc"
123 << " = { /* Stride */ " << std::to_string(stride) << ", /* Size */ "
124 << std::to_string(size) << "};\n";
125 }
126 if ((baseAddrA + offsetA) % 4)
127 llvm::report_fatal_error("bd address must be 4B (32b) aligned");
128 output << "__mlir_aie_try(XAie_DmaSetMultiDimAddr("
129 << tileDMAInstRefStr(col, row, bdNum) << ", "
130 << "&" << tensor << ", "
131 << "0x" << llvm::utohexstr(baseAddrA + offsetA) << ", "
132 << " /* len */ " << lenA << "));\n";
133}
134
135// Traverse through a chain of blocks.
136llvm::SetVector<Block *> getOrderedChainOfBlocks(Region *region) {
137 // Get the region's entry block, then start traversing through the chain of
138 // blocks.
139 llvm::SetVector<Block *> blockVector;
140 SmallVector<Block *, 16> worklist;
141 Block *firstBD = &region->front();
142 blockVector.insert(firstBD);
143 worklist.push_back(firstBD);
144 while (!worklist.empty()) {
145 Block *block = worklist.pop_back_val();
146 if (block->empty())
147 continue;
148 auto successors = block->getTerminator()->getSuccessors();
149 for (auto *i : successors) {
150 if (!blockVector.contains(i)) {
151 blockVector.insert(i);
152 worklist.push_back(i);
153 }
154 }
155 }
156 return blockVector;
157}
158
159} // namespace xilinx::AIE
Include the generated interface declarations.
std::string tileDMAInstStr(llvm::StringRef col, llvm::StringRef row, llvm::StringRef bdNum)
void generateXAieDmaSetMultiDimAddr(llvm::raw_ostream &output, int ndims, llvm::ArrayRef< BDDimLayoutAttr > dims, int col, int row, int bdNum, int baseAddrA, int offsetA, int lenA, int elementWidthInBytes, const char *errorRet)
std::string tileDMAInstRefStr(llvm::StringRef col, llvm::StringRef row, llvm::StringRef bdNum)
llvm::SetVector< mlir::Block * > getOrderedChainOfBlocks(mlir::Region *region)
std::string tileLocStr(llvm::StringRef col, llvm::StringRef row)
std::string packetStr(llvm::StringRef id, llvm::StringRef type)