9#ifndef MLIR_AIE_DIALECT_H
10#define MLIR_AIE_DIALECT_H
17#include "mlir/Dialect/DLTI/Traits.h"
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#include "mlir/IR/SymbolTable.h"
24#include "mlir/Interfaces/DataLayoutInterfaces.h"
26#include "llvm/ADT/ArrayRef.h"
27#include "llvm/ADT/STLExtras.h"
28#include "llvm/ADT/StringRef.h"
29#include "llvm/ADT/StringSwitch.h"
35template <
typename ConcreteType>
37 static mlir::LogicalResult
verifyTrait(mlir::Operation *op);
42template <
typename ConcreteType>
45 static mlir::LogicalResult
verifyTrait(mlir::Operation *op);
48template <
typename ConcreteType>
55template <
typename ConcreteType>
59 return "sym_visibility";
67 return mlir::success();
68 auto visStrAttr = llvm::dyn_cast<mlir::StringAttr>(vis);
70 return op->emitOpError()
72 <<
"' to be a string attribute, but got " << vis;
73 if (!llvm::is_contained(
74 llvm::ArrayRef<llvm::StringRef>{
"public",
"private",
"nested"},
75 visStrAttr.getValue()))
76 return op->emitOpError()
77 <<
"visibility expected to be one of [\"public\", \"private\", "
78 "\"nested\"], but got "
80 return mlir::success();
84 mlir::StringAttr vis =
85 this->getOperation()->template getAttrOfType<mlir::StringAttr>(
88 return mlir::SymbolTable::Visibility::Public;
89 return llvm::StringSwitch<mlir::SymbolTable::Visibility>(vis.getValue())
90 .Case(
"private", mlir::SymbolTable::Visibility::Private)
91 .Case(
"nested", mlir::SymbolTable::Visibility::Nested)
92 .Default(mlir::SymbolTable::Visibility::Public);
96 mlir::Operation *op = this->getOperation();
97 if (vis == mlir::SymbolTable::Visibility::Public) {
101 assert((vis == mlir::SymbolTable::Visibility::Private ||
102 vis == mlir::SymbolTable::Visibility::Nested) &&
103 "unknown symbol visibility kind");
104 llvm::StringRef visName =
105 vis == mlir::SymbolTable::Visibility::Private ?
"private" :
"nested";
107 mlir::StringAttr::get(op->getContext(), visName));
113template <
typename ConcreteType>
118class RouteEndpointOp;
121 uint32_t burstLength);
123 uint32_t burstLength);
130 mlir::StringAttr name);
132 llvm::StringRef name);
134mlir::Operation *
lookupNamedOp(mlir::Operation *from, mlir::StringAttr name);
137template <
typename OpTy,
typename NameT>
139 return llvm::dyn_cast_if_present<OpTy>(
lookupNamedOpIn(symbolTableOp, name));
142template <
typename OpTy,
typename NameT>
144 return llvm::dyn_cast_if_present<OpTy>(
lookupNamedOp(from, name));
153 mlir::Operation *
lookup(mlir::StringAttr name)
const {
154 return ops.lookup(name);
156 template <
typename OpTy>
157 OpTy
lookup(mlir::StringAttr name)
const {
158 return llvm::dyn_cast_if_present<OpTy>(
lookup(name));
164 std::string
uniqueName(llvm::StringRef prefix,
unsigned &counter)
const;
167 mlir::MLIRContext *context;
168 llvm::DenseMap<mlir::StringAttr, mlir::Operation *> ops;
176 return tables.try_emplace(symbolTableOp, symbolTableOp).first->second;
178 template <
typename OpTy>
179 OpTy
lookupIn(mlir::Operation *symbolTableOp, mlir::StringAttr name) {
184 llvm::DenseMap<mlir::Operation *, NamedOpTable> tables;
194 mlir::OpAsmParser &parser,
195 llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &values,
196 mlir::DenseI64ArrayAttr &integers,
197 llvm::SmallVectorImpl<mlir::Type> &types);
199 mlir::Operation *op, mlir::OperandRange values,
200 llvm::ArrayRef<int64_t> integers,
201 mlir::TypeRange types);
208template <
typename ConcreteOp>
213 ::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>(op));
218 : ::mlir::OffsetSizeAndStrideOpInterface {
219 template <
typename ConcreteOp>
225#include "aie/Dialect/AIE/IR/AIEDialect.h.inc"
237#define GET_TYPEDEF_CLASSES
238#include "aie/Dialect/AIE/IR/AIETypes.h.inc"
244#define GET_ATTRDEF_CLASSES
245#include "aie/Dialect/AIE/IR/AIEAttrs.h.inc"
248#include "aie/Dialect/AIE/IR/AIEInterfaces.h.inc"
258#define GENERATE_TO_STRING(TYPE_WITH_INSERTION_OP) \
259 friend std::string to_string(const TYPE_WITH_INSERTION_OP &s) { \
260 std::ostringstream ss; \
269 bool operator==(
const Port &rhs)
const {
270 return std::tie(bundle, channel) == std::tie(rhs.bundle, rhs.channel);
273 bool operator!=(
const Port &rhs)
const {
return !(*
this == rhs); }
275 bool operator<(
const Port &rhs)
const {
276 return std::tie(bundle, channel) < std::tie(rhs.bundle, rhs.channel);
279 friend std::ostream &
operator<<(std::ostream &os,
const Port &port) {
281 os << stringifyWireBundle(port.bundle).str();
282 os <<
": " << std::to_string(port.channel) <<
")";
288 friend llvm::raw_ostream &
operator<<(llvm::raw_ostream &os,
290 os << to_string(port);
295std::optional<std::pair<TileID, Port>>
303 bool operator==(
const Connect &rhs)
const {
304 return std::tie(src, dst) == std::tie(rhs.src, rhs.dst);
307 bool operator!=(
const Connect &rhs)
const {
return !(*
this == rhs); }
309 bool operator<(
const Connect &rhs)
const {
310 return std::tie(src, dst) < std::tie(rhs.src, rhs.dst);
315 DMAChannelDir direction;
318 bool operator==(
const DMAChannel &rhs)
const {
319 return std::tie(direction, channel) == std::tie(rhs.direction, rhs.channel);
331 mlir::OpAsmParser::UnresolvedOperand &operand,
332 BDDimLayoutArrayAttr &dimensions);
335 mlir::Operation *op, mlir::Value operand,
336 BDDimLayoutArrayAttr dimensions);
339 mlir::Attribute &channel);
342 mlir::Attribute channel);
346 ObjectFifoPortAttr &port,
347 llvm::SmallVectorImpl<mlir::Type> &objects);
350 mlir::Operation *op, ObjectFifoPortAttr port,
351 mlir::TypeRange objects);
354 ObjectFifoPortAttr &port,
355 mlir::IntegerAttr &size);
358 mlir::Operation *op, ObjectFifoPortAttr port,
359 mlir::IntegerAttr size);
362 mlir::OpAsmParser &parser,
363 llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &tiles,
364 BDDimLayoutArrayArrayAttr &dimensions);
367 mlir::Operation *op, mlir::OperandRange tiles,
368 BDDimLayoutArrayArrayAttr dimsPerTileAttr);
372 llvm::SmallVectorImpl<mlir::OpAsmParser::UnresolvedOperand> &vias,
373 mlir::DenseI32ArrayAttr &ingressBundles,
374 mlir::DenseI32ArrayAttr &ingressChannels,
375 mlir::DenseI32ArrayAttr &egressBundles,
376 mlir::DenseI32ArrayAttr &egressChannels);
379 mlir::OperandRange vias,
380 mlir::DenseI32ArrayAttr ingressBundles,
381 mlir::DenseI32ArrayAttr ingressChannels,
382 mlir::DenseI32ArrayAttr egressBundles,
383 mlir::DenseI32ArrayAttr egressChannels);
389 mlir::Attribute &result);
410 llvm::SmallVector<BDDimLayoutAttr>
inner;
427#define GET_OP_CLASSES
428#include "aie/Dialect/AIE/IR/AIEOps.h.inc"
434llvm::SmallVector<ObjectFifoDmaEndpointOp>
440int64_t
turnPasses(llvm::ArrayRef<std::pair<int64_t, int64_t>> ends);
448 return bundle == WireBundle::North || bundle == WireBundle::South ||
449 bundle == WireBundle::East || bundle == WireBundle::West;
453 llvm::DenseMap<TileID, mlir::Operation *> &tiles);
457 llvm::DenseMap<mlir::Operation *, llvm::SmallVector<BufferOp, 4>> &buffers);
468int64_t
paddedSize(llvm::ArrayRef<BDDimLayoutAttr> dims,
469 llvm::ArrayRef<BDPadLayoutAttr> pads, int64_t fallback);
476std::optional<llvm::SmallVector<BDDimLayoutAttr>>
483 mlir::BaseMemRefType buffer);
493 std::optional<int64_t> lengthUnit,
494 mlir::BaseMemRefType buffer,
495 std::optional<int64_t> lenElems,
497 llvm::ArrayRef<int64_t> innerSizes);
505 llvm::MutableArrayRef<int64_t> strides);
527 PacketInfoAttr packet,
528 llvm::StringRef what =
"packet");
533 llvm::ArrayRef<DMABDOp> bds,
534 bool packetEnabledByContext =
false);
541 UseLockOp &acquire, UseLockOp &release);
550 llvm::ArrayRef<BDPadLayoutAttr> pads, int64_t objectSize,
551 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
573struct DenseMapInfo<
xilinx::AIE::ObjectFifoAcquireOp> {
575 return hash_value(val.getAsOpaquePointer());
578 static bool isEqual(xilinx::AIE::ObjectFifoAcquireOp lhs,
579 xilinx::AIE::ObjectFifoAcquireOp rhs) {
588struct DenseMapInfo<
xilinx::AIE::ObjectFifoCreateOp> {
590 return hash_value(val.getAsOpaquePointer());
593 static bool isEqual(xilinx::AIE::ObjectFifoCreateOp lhs,
594 xilinx::AIE::ObjectFifoCreateOp rhs) {
600struct DenseMapInfo<
xilinx::AIE::DMAChannel> {
601 using FirstInfo = DenseMapInfo<xilinx::AIE::DMAChannelDir>;
605 return detail::combineHashValue(FirstInfo::getHashValue(d.direction),
606 SecondInfo::getHashValue(d.channel));
617 using FirstInfo = DenseMapInfo<xilinx::AIE::WireBundle>;
621 return detail::combineHashValue(FirstInfo::getHashValue(d.bundle),
622 SecondInfo::getHashValue(d.channel));
637 return a.bundle == b.bundle ? a.channel < b.channel : a.bundle < b.bundle;
644 std::size_t h1 = std::hash<xilinx::AIE::WireBundle>{}(p.bundle);
645 std::size_t h2 = std::hash<int>{}(p.channel);
#define GENERATE_TO_STRING(TYPE_WITH_INSERTION_OP)
SharedMemory
Which of two tiles' memory modules both of them can address.
OpTy lookupIn(mlir::Operation *symbolTableOp, mlir::StringAttr name)
NamedOpTable & getTable(mlir::Operation *symbolTableOp)
NamedOpTable(mlir::Operation *symbolTableOp)
std::string uniqueName(llvm::StringRef prefix, unsigned &counter) const
OpTy lookup(mlir::StringAttr name) const
mlir::Operation * lookup(mlir::StringAttr name) const
bool isContiguousBDTransfer(llvm::ArrayRef< BDDimLayoutAttr > dims)
mlir::ParseResult parseFlowVias(mlir::OpAsmParser &parser, llvm::SmallVectorImpl< mlir::OpAsmParser::UnresolvedOperand > &vias, mlir::DenseI32ArrayAttr &ingressBundles, mlir::DenseI32ArrayAttr &ingressChannels, mlir::DenseI32ArrayAttr &egressBundles, mlir::DenseI32ArrayAttr &egressChannels)
void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::Value operand, BDDimLayoutArrayAttr dimensions)
void printTypedDynamicIndexList(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRange values, llvm::ArrayRef< int64_t > integers, mlir::TypeRange types)
llvm::SmallVector< ObjectFifoDmaEndpointOp > turnEndpoints(ObjectFifoDmaEndpointOp end)
std::optional< llvm::SmallVector< BDDimLayoutAttr > > normalizedBDDims(llvm::ArrayRef< BDDimLayoutAttr > dims, int64_t len)
mlir::LogicalResult verifyLengthParameterTile(mlir::Operation *op, const AIETargetModel &targetModel, int col, int row)
uint32_t getShimBurstLengthBytes(const AIE::AIETargetModel &tm, uint32_t burstLength)
void collectTiles(DeviceOp &device, llvm::DenseMap< TileID, mlir::Operation * > &tiles)
void collectBuffers(DeviceOp &device, llvm::DenseMap< mlir::Operation *, llvm::SmallVector< BufferOp, 4 > > &buffers)
mlir::ParseResult parseTraceEvent(mlir::AsmParser &parser, mlir::Attribute &result)
mlir::LogicalResult verifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op)
void registerAIETranslations()
void printObjectFifoAcquireObjects(mlir::OpAsmPrinter &printer, mlir::Operation *op, ObjectFifoPortAttr port, mlir::TypeRange objects)
mlir::LogicalResult verifyBdLockPair(mlir::Block &block, bool outOfOrder, UseLockOp &acquire, UseLockOp &release)
mlir::LogicalResult verifyAssignedPacket(mlir::Operation *op, PacketInfoAttr packet, llvm::StringRef what="packet")
mlir::ParseResult parseTypedDynamicIndexList(mlir::OpAsmParser &parser, llvm::SmallVectorImpl< mlir::OpAsmParser::UnresolvedOperand > &values, mlir::DenseI64ArrayAttr &integers, llvm::SmallVectorImpl< mlir::Type > &types)
void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRange tiles, BDDimLayoutArrayArrayAttr dimsPerTileAttr)
mlir::Operation * lookupNamedOpIn(mlir::Operation *symbolTableOp, mlir::StringAttr name)
uint32_t getShimBurstLengthEncoding(const AIE::AIETargetModel &tm, uint32_t burstLength)
mlir::LogicalResult verifyDMABDOutOfOrderId(DMABDOp bd, bool packetEnabledByContext=false)
mlir::ParseResult parseObjectFifoAcquireObjects(mlir::OpAsmParser &parser, ObjectFifoPortAttr &port, llvm::SmallVectorImpl< mlir::Type > &objects)
mlir::LogicalResult verifyOutOfOrderChannel(mlir::Operation *op, DMAChannelDir dir, bool outOfOrder, llvm::ArrayRef< DMABDOp > bds, bool packetEnabledByContext=false)
struct Connect { Port src; Port dst; bool operator==(const Connect &rhs) const { return std::tie(src, dst)==std::tie(rhs.src, rhs.dst); } bool operator!=(const Connect &rhs) const { return !(*this==rhs);} bool operator<(const Connect &rhs) const { return std::tie(src, dst)< std::tie(rhs.src, rhs.dst); } } Connect
void printDMAStartChannel(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::Attribute channel)
mlir::LogicalResult verifyLengthParameter(mlir::Operation *op, std::optional< int64_t > lengthUnit, mlir::BaseMemRefType buffer, std::optional< int64_t > lenElems, bool contiguous, llvm::ArrayRef< int64_t > innerSizes)
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
int32_t getBufferBaseAddress(mlir::Operation *bufOp)
bool isDirectional(WireBundle bundle)
mlir::ParseResult parseDMAStartChannel(mlir::OpAsmParser &parser, mlir::Attribute &channel)
llvm::SmallVector< uint32_t > getAssignedBdIds(DmaBody program)
llvm::SmallVector< StreamWindowStep > streamWindowSteps(const StreamWindow &w)
int64_t turnPasses(llvm::ArrayRef< std::pair< int64_t, int64_t > > ends)
llvm::raw_ostream & operator<<(llvm::raw_ostream &os, const SwitchSettings &ss)
const AIETargetModel & getTargetModel(mlir::Operation *op)
bool keepsPktHeader(TileID tile, Port master, std::optional< bool > keep)
struct DMAChannel { DMAChannelDir direction; int channel; bool operator==(const DMAChannel &rhs) const { return std::tie(direction, channel)==std::tie(rhs.direction, rhs.channel); } } DMAChannel
mlir::LogicalResult verifyDMAChannelsResolved(DeviceOp device)
mlir::Operation * lookupNamedOp(mlir::Operation *from, mlir::StringAttr name)
mlir::ParseResult parseObjectFifoProducerTile(mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, BDDimLayoutArrayAttr &dimensions)
void printTraceEventEnum(mlir::AsmPrinter &printer, mlir::Attribute attr)
void placeRuntimeLengthDimension(llvm::MutableArrayRef< int64_t > sizes, llvm::MutableArrayRef< int64_t > strides)
mlir::LogicalResult myVerifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op)
mlir::LogicalResult inferStreamWindow(llvm::ArrayRef< BDDimLayoutAttr > dims, llvm::ArrayRef< BDPadLayoutAttr > pads, int64_t objectSize, llvm::function_ref< mlir::InFlightDiagnostic()> emitError, StreamWindow &window)
mlir::LogicalResult verifyDMABDIteration(DMABDOp bd, AIETileType tileType)
void printFlowVias(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRange vias, mlir::DenseI32ArrayAttr ingressBundles, mlir::DenseI32ArrayAttr ingressChannels, mlir::DenseI32ArrayAttr egressBundles, mlir::DenseI32ArrayAttr egressChannels)
struct Port { WireBundle bundle; int channel; bool operator==(const Port &rhs) const { return std::tie(bundle, channel)==std::tie(rhs.bundle, rhs.channel); } bool operator!=(const Port &rhs) const { return !(*this==rhs);} bool operator<(const Port &rhs) const { return std::tie(bundle, channel)< std::tie(rhs.bundle, rhs.channel); } friend std::ostream &operator<<(std::ostream &os, const Port &port) { os<< "("; os<< stringifyWireBundle(port.bundle).str(); os<< ": "<< std::to_string(port.channel)<< ")"; return os; } friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const Port &port) { os<< to_string(port); return os; } } Port
mlir::ParseResult parseObjectFifoReleaseCount(mlir::OpAsmParser &parser, ObjectFifoPortAttr &port, mlir::IntegerAttr &size)
AIETargetModel::SharedMemory sharedMemory(TileOp a, TileOp b)
Which of a's and b's memory modules both tiles can address.
std::optional< std::pair< TileID, Port > > getConnectingWireEndpoint(const AIETargetModel &targetModel, TileID tile, Port port)
mlir::FailureOr< int64_t > getLengthUnitBytes(mlir::Operation *op, int64_t lengthUnit, mlir::BaseMemRefType buffer)
int64_t paddedSize(llvm::ArrayRef< BDDimLayoutAttr > dims, llvm::ArrayRef< BDPadLayoutAttr > pads, int64_t fallback)
mlir::ParseResult parseObjectFifoConsumerTiles(mlir::OpAsmParser &parser, llvm::SmallVectorImpl< mlir::OpAsmParser::UnresolvedOperand > &tiles, BDDimLayoutArrayArrayAttr &dimensions)
void printObjectFifoReleaseCount(mlir::OpAsmPrinter &printer, mlir::Operation *op, ObjectFifoPortAttr port, mlir::IntegerAttr size)
WireBundle getConnectingBundle(WireBundle dir)
static bool isEqual(const xilinx::AIE::DMAChannel &lhs, const xilinx::AIE::DMAChannel &rhs)
DenseMapInfo< int > SecondInfo
DenseMapInfo< xilinx::AIE::DMAChannelDir > FirstInfo
static unsigned getHashValue(const xilinx::AIE::DMAChannel &d)
static bool isEqual(xilinx::AIE::ObjectFifoAcquireOp lhs, xilinx::AIE::ObjectFifoAcquireOp rhs)
static unsigned getHashValue(xilinx::AIE::ObjectFifoAcquireOp val)
static bool isEqual(xilinx::AIE::ObjectFifoCreateOp lhs, xilinx::AIE::ObjectFifoCreateOp rhs)
static unsigned getHashValue(xilinx::AIE::ObjectFifoCreateOp val)
static unsigned getHashValue(const xilinx::AIE::Port &d)
DenseMapInfo< int > SecondInfo
DenseMapInfo< xilinx::AIE::WireBundle > FirstInfo
static bool isEqual(const xilinx::AIE::Port &lhs, const xilinx::AIE::Port &rhs)
std::size_t operator()(const xilinx::AIE::Port &p) const noexcept
bool operator()(const xilinx::AIE::Port &a, const xilinx::AIE::Port &b) const
mlir::SymbolTable::Visibility getVisibility()
void setVisibility(mlir::SymbolTable::Visibility vis)
static mlir::LogicalResult verifyTrait(mlir::Operation *op)
static constexpr llvm::StringRef getVisibilityAttrName()
static mlir::LogicalResult verifyTrait(mlir::Operation *op)
static mlir::LogicalResult verifyTrait(mlir::Operation *op)
::mlir::LogicalResult verifyTrait(::mlir::Operation *op)
llvm::SmallVector< BDDimLayoutAttr > inner