MLIR-AIE
AIEDialect.h
Go to the documentation of this file.
1//===- AIEDialect.h ---------------------------------------------*- C++ -*-===//
2//
3// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7// (c) Copyright 2019 Xilinx Inc.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef MLIR_AIE_DIALECT_H
12#define MLIR_AIE_DIALECT_H
13
14#include "AIEEnums.h"
15
17
18#include "mlir/Dialect/Func/IR/FuncOps.h"
19#include "mlir/Dialect/MemRef/IR/MemRef.h"
20#include "mlir/IR/BuiltinAttributes.h"
21#include "mlir/IR/OpDefinition.h"
22#include "mlir/IR/OpImplementation.h"
23
24namespace xilinx::AIE {
25
26// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp)
27// has valid BDs.
28template <typename ConcreteType>
29struct HasValidBDs : mlir::OpTrait::TraitBase<ConcreteType, HasValidBDs> {
30 static mlir::LogicalResult verifyTrait(mlir::Operation *op);
31};
32
33// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp)
34// has valid channels.
35template <typename ConcreteType>
37 : mlir::OpTrait::TraitBase<ConcreteType, HasValidBDs> {
38 static mlir::LogicalResult verifyTrait(mlir::Operation *op);
39};
40
41template <typename ConcreteType>
43 : mlir::OpTrait::TraitBase<ConcreteType, SkipAccessibilityCheckTrait> {};
44
45class TileOp;
46
48 uint32_t burstLength);
50 uint32_t burstLength);
51
52mlir::LogicalResult
53verifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op);
54
55} // namespace xilinx::AIE
56
57/// Include the generated interface declarations.
58#include "aie/Dialect/AIE/IR/AIEInterfaces.h.inc"
59
60namespace xilinx::AIE {
61mlir::LogicalResult
62myVerifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op);
63template <typename ConcreteOp>
66 static ::mlir::LogicalResult verifyTrait(::mlir::Operation *op) {
68 ::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>(op));
69 }
70};
71
73 : ::mlir::OffsetSizeAndStrideOpInterface {
74 template <typename ConcreteOp>
75 struct Trait : public MyOffsetSizeAndStrideOpInterfaceTrait<ConcreteOp> {};
76};
77} // namespace xilinx::AIE
78
79// Include dialect declarations such as parseAttributes, parseType
80#include "aie/Dialect/AIE/IR/AIEDialect.h.inc"
81
82namespace xilinx::AIE {
83
85
86} // namespace xilinx::AIE
87
88////////////////////////////////////////////////////////////////////////////////
89/////////////////////// Custom Types for the Dialect ///////////////////////////
90////////////////////////////////////////////////////////////////////////////////
91
92#define GET_TYPEDEF_CLASSES
93#include "aie/Dialect/AIE/IR/AIETypes.h.inc"
94
95////////////////////////////////////////////////////////////////////////////////
96// Custom Attributes ///////////////////////////////////////////////////////////
97////////////////////////////////////////////////////////////////////////////////
98
99#define GET_ATTRDEF_CLASSES
100#include "aie/Dialect/AIE/IR/AIEAttrs.h.inc"
101
102////////////////////////////////////////////////////////////////////////////////
103//////////////////// Custom Operations for the Dialect /////////////////////////
104////////////////////////////////////////////////////////////////////////////////
105
106namespace xilinx::AIE {
107
108WireBundle getConnectingBundle(WireBundle dir);
109
110#define GENERATE_TO_STRING(TYPE_WITH_INSERTION_OP) \
111 friend std::string to_string(const TYPE_WITH_INSERTION_OP &s) { \
112 std::ostringstream ss; \
113 ss << s; \
114 return ss.str(); \
115 }
116
117using Port = struct Port {
118 WireBundle bundle;
120
121 bool operator==(const Port &rhs) const {
122 return std::tie(bundle, channel) == std::tie(rhs.bundle, rhs.channel);
123 }
124
125 bool operator!=(const Port &rhs) const { return !(*this == rhs); }
126
127 bool operator<(const Port &rhs) const {
128 return std::tie(bundle, channel) < std::tie(rhs.bundle, rhs.channel);
129 }
130
131 friend std::ostream &operator<<(std::ostream &os, const Port &port) {
132 os << "(";
133 switch (port.bundle) {
134 case WireBundle::Core:
135 os << "Core";
136 break;
137 case WireBundle::DMA:
138 os << "DMA";
139 break;
140 case WireBundle::North:
141 os << "N";
142 break;
143 case WireBundle::East:
144 os << "E";
145 break;
146 case WireBundle::South:
147 os << "S";
148 break;
149 case WireBundle::West:
150 os << "W";
151 break;
152 default:
153 os << "X";
154 break;
155 }
156 os << ": " << std::to_string(port.channel) << ")";
157 return os;
158 }
159
161
162 friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os,
163 const Port &port) {
164 os << to_string(port);
165 return os;
166 }
167
168};
169
170using Connect = struct Connect {
171 Port src;
173
174 bool operator==(const Connect &rhs) const {
175 return std::tie(src, dst) == std::tie(rhs.src, rhs.dst);
176 }
177};
178
179using DMAChannel = struct DMAChannel {
180 DMAChannelDir direction;
181 int channel;
182
183 bool operator==(const DMAChannel &rhs) const {
184 return std::tie(direction, channel) == std::tie(rhs.direction, rhs.channel);
185 }
186};
187
188const AIETargetModel &getTargetModel(mlir::Operation *op);
189const AIETargetModel &getTargetModel(AIEDevice device);
190
191mlir::ParseResult
192parseObjectFifoProducerTile(mlir::OpAsmParser &parser,
193 mlir::OpAsmParser::UnresolvedOperand &operand,
194 BDDimLayoutArrayAttr &dimensions);
195
196void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer,
197 mlir::Operation *op, mlir::Value tile,
198 BDDimLayoutArrayAttr dimensions);
199
201 mlir::OpAsmParser &parser,
202 llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &tiles,
203 BDDimLayoutArrayArrayAttr &dimensions);
204
205void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer,
206 mlir::Operation *op, mlir::OperandRange tiles,
207 BDDimLayoutArrayArrayAttr dimensions);
208
209int32_t getBufferBaseAddress(mlir::Operation *bufOp);
210
211} // namespace xilinx::AIE
212
213// include TableGen generated Op definitions
214#define GET_OP_CLASSES
215#include "aie/Dialect/AIE/IR/AIEOps.h.inc"
216
217namespace xilinx::AIE {
218class DeviceOp;
219class ShimDMAAllocationOp;
221public:
222 std::optional<AIE::ShimDMAAllocationOp> get(DeviceOp dev,
223 mlir::StringRef sym_name);
224
225private:
226 llvm::DenseMap<std::pair<DeviceOp, mlir::StringRef>,
227 std::optional<AIE::ShimDMAAllocationOp>>
228 allocGetter;
229 std::optional<AIE::ShimDMAAllocationOp>
230 cachelessGet(DeviceOp dev, mlir::StringRef sym_name);
231};
232} // namespace xilinx::AIE
233
234namespace xilinx::AIE {
235
236void collectTiles(DeviceOp &device,
237 llvm::DenseMap<TileID, mlir::Operation *> &tiles);
238
239void collectBuffers(
240 DeviceOp &device,
241 llvm::DenseMap<mlir::Operation *, llvm::SmallVector<BufferOp, 4>> &buffers);
242} // namespace xilinx::AIE
243
244namespace llvm {
245// Functions hash just like pointers.
246template <>
247struct DenseMapInfo<xilinx::AIE::ObjectFifoAcquireOp> {
248 static xilinx::AIE::ObjectFifoAcquireOp getEmptyKey() {
249 auto *pointer = DenseMapInfo<void *>::getEmptyKey();
250 return xilinx::AIE::ObjectFifoAcquireOp::getFromOpaquePointer(pointer);
251 }
252
253 static xilinx::AIE::ObjectFifoAcquireOp getTombstoneKey() {
254 auto *pointer = DenseMapInfo<void *>::getTombstoneKey();
255 return xilinx::AIE::ObjectFifoAcquireOp::getFromOpaquePointer(pointer);
256 }
257
258 static unsigned getHashValue(xilinx::AIE::ObjectFifoAcquireOp val) {
259 return hash_value(val.getAsOpaquePointer());
260 }
261
262 static bool isEqual(xilinx::AIE::ObjectFifoAcquireOp lhs,
263 xilinx::AIE::ObjectFifoAcquireOp rhs) {
264 return lhs == rhs;
265 }
266};
267} // namespace llvm
268
269namespace llvm {
270// Functions hash just like pointers.
271template <>
272struct DenseMapInfo<xilinx::AIE::ObjectFifoCreateOp> {
273 static xilinx::AIE::ObjectFifoCreateOp getEmptyKey() {
274 auto *pointer = DenseMapInfo<void *>::getEmptyKey();
275 return xilinx::AIE::ObjectFifoCreateOp::getFromOpaquePointer(pointer);
276 }
277
278 static xilinx::AIE::ObjectFifoCreateOp getTombstoneKey() {
279 auto *pointer = DenseMapInfo<void *>::getTombstoneKey();
280 return xilinx::AIE::ObjectFifoCreateOp::getFromOpaquePointer(pointer);
281 }
282
283 static unsigned getHashValue(xilinx::AIE::ObjectFifoCreateOp val) {
284 return hash_value(val.getAsOpaquePointer());
285 }
286
287 static bool isEqual(xilinx::AIE::ObjectFifoCreateOp lhs,
288 xilinx::AIE::ObjectFifoCreateOp rhs) {
289 return lhs == rhs;
290 }
291};
292
293template <>
294struct DenseMapInfo<xilinx::AIE::DMAChannel> {
295 using FirstInfo = DenseMapInfo<xilinx::AIE::DMAChannelDir>;
296 using SecondInfo = DenseMapInfo<int>;
297
299 return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()};
300 }
301
303 return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()};
304 }
305
306 static unsigned getHashValue(const xilinx::AIE::DMAChannel &d) {
307 return detail::combineHashValue(FirstInfo::getHashValue(d.direction),
308 SecondInfo::getHashValue(d.channel));
309 }
310
311 static bool isEqual(const xilinx::AIE::DMAChannel &lhs,
312 const xilinx::AIE::DMAChannel &rhs) {
313 return lhs == rhs;
314 }
315};
316
317template <>
318struct DenseMapInfo<xilinx::AIE::Port> {
319 using FirstInfo = DenseMapInfo<xilinx::AIE::WireBundle>;
320 using SecondInfo = DenseMapInfo<int>;
321
323 return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()};
324 }
325
327 return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()};
328 }
329
330 static unsigned getHashValue(const xilinx::AIE::Port &d) {
331 return detail::combineHashValue(FirstInfo::getHashValue(d.bundle),
332 SecondInfo::getHashValue(d.channel));
333 }
334
335 static bool isEqual(const xilinx::AIE::Port &lhs,
336 const xilinx::AIE::Port &rhs) {
337 return lhs == rhs;
338 }
339};
340
341} // namespace llvm
342
343template <>
344struct std::less<xilinx::AIE::Port> {
346 const xilinx::AIE::Port &b) const {
347 return a.bundle == b.bundle ? a.channel < b.channel : a.bundle < b.bundle;
348 }
349};
350
351template <>
352struct std::hash<xilinx::AIE::Port> {
353 std::size_t operator()(const xilinx::AIE::Port &p) const noexcept {
354 std::size_t h1 = std::hash<xilinx::AIE::WireBundle>{}(p.bundle);
355 std::size_t h2 = std::hash<int>{}(p.channel);
356 return h1 ^ h2 << 1;
357 }
358};
359
360#endif
#define GENERATE_TO_STRING(TYPE_WITH_INSERTION_OP)
Definition AIEDialect.h:110
Include the generated interface declarations.
void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRange tiles, BDDimLayoutArrayArrayAttr dimensions)
Connect { Port src Connect
Definition AIEDialect.h:171
uint32_t getShimBurstLengthBytes(const AIE::AIETargetModel &tm, uint32_t burstLength)
mlir::LogicalResult verifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op)
void registerAIETranslations()
friend std::ostream & operator<<(std::ostream &os, const Port &port)
Definition AIEDialect.h:131
friend std::string to_string(const TileID &s)
DMAChannel { DMAChannelDir direction DMAChannel
Definition AIEDialect.h:180
uint32_t getShimBurstLengthEncoding(const AIE::AIETargetModel &tm, uint32_t burstLength)
int32_t getBufferBaseAddress(mlir::Operation *bufOp)
bool operator!=(const Port &rhs) const
Definition AIEDialect.h:125
Port { WireBundle bundle Port
Definition AIEDialect.h:118
const AIETargetModel & getTargetModel(mlir::Operation *op)
PathEndPoint src
mlir::ParseResult parseObjectFifoProducerTile(mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, BDDimLayoutArrayAttr &dimensions)
bool operator==(const Port &rhs) const
Definition AIEDialect.h:121
mlir::LogicalResult myVerifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op)
void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::Value tile, BDDimLayoutArrayAttr dimensions)
bool operator<(const Port &rhs) const
Definition AIEDialect.h:127
mlir::ParseResult parseObjectFifoConsumerTiles(mlir::OpAsmParser &parser, llvm::SmallVectorImpl< mlir::OpAsmParser::UnresolvedOperand > &tiles, BDDimLayoutArrayArrayAttr &dimensions)
WireBundle getConnectingBundle(WireBundle dir)
static bool isEqual(const xilinx::AIE::DMAChannel &lhs, const xilinx::AIE::DMAChannel &rhs)
Definition AIEDialect.h:311
DenseMapInfo< xilinx::AIE::DMAChannelDir > FirstInfo
Definition AIEDialect.h:295
static unsigned getHashValue(const xilinx::AIE::DMAChannel &d)
Definition AIEDialect.h:306
static xilinx::AIE::DMAChannel getTombstoneKey()
Definition AIEDialect.h:302
static xilinx::AIE::DMAChannel getEmptyKey()
Definition AIEDialect.h:298
static bool isEqual(xilinx::AIE::ObjectFifoCreateOp lhs, xilinx::AIE::ObjectFifoCreateOp rhs)
Definition AIEDialect.h:287
static unsigned getHashValue(xilinx::AIE::ObjectFifoCreateOp val)
Definition AIEDialect.h:283
static xilinx::AIE::ObjectFifoCreateOp getTombstoneKey()
Definition AIEDialect.h:278
static xilinx::AIE::ObjectFifoCreateOp getEmptyKey()
Definition AIEDialect.h:273
static xilinx::AIE::Port getTombstoneKey()
Definition AIEDialect.h:326
static unsigned getHashValue(const xilinx::AIE::Port &d)
Definition AIEDialect.h:330
DenseMapInfo< xilinx::AIE::WireBundle > FirstInfo
Definition AIEDialect.h:319
static xilinx::AIE::Port getEmptyKey()
Definition AIEDialect.h:322
static bool isEqual(const xilinx::AIE::Port &lhs, const xilinx::AIE::Port &rhs)
Definition AIEDialect.h:335
std::size_t operator()(const xilinx::AIE::Port &p) const noexcept
Definition AIEDialect.h:353
bool operator()(const xilinx::AIE::Port &a, const xilinx::AIE::Port &b) const
Definition AIEDialect.h:345
static mlir::LogicalResult verifyTrait(mlir::Operation *op)
static mlir::LogicalResult verifyTrait(mlir::Operation *op)
::mlir::LogicalResult verifyTrait(::mlir::Operation *op)
Definition AIEDialect.h:66
std::optional< AIE::ShimDMAAllocationOp > get(DeviceOp dev, mlir::StringRef sym_name)