13#include "mlir/Pass/Pass.h"
20#define GEN_PASS_DEF_AIEASSIGNPACKETIDS
21#include "aie/Dialect/AIE/Transforms/AIEPasses.h.inc"
26struct AIEAssignPacketIdsPass
27 :
public xilinx::AIE::impl::AIEAssignPacketIdsBase<AIEAssignPacketIdsPass> {
30 void runOnOperation()
override {
31 DeviceOp device = getOperation();
32 if (clReserveControllerPacketIds)
33 AIEDialect::ReserveControllerPacketIdsAttrHelper(device.getContext())
34 .setAttr(device, UnitAttr::get(device.getContext()));
35 PacketIdSpace space(device);
39 for (
auto route : device.getOps<RouteOp>()) {
40 std::optional<PacketInfoAttr> packet = route.getPacket();
41 if (packet && packet->isAssigned() &&
42 packet->assignedId() > space.
maxId()) {
43 route.emitOpError(
"pkt_id ")
44 << packet->assignedId() <<
" is out of range (max " << space.
maxId()
46 return signalPassFailure();
54 SmallVector<RouteOp> unpinned;
55 for (
auto route : device.getOps<RouteOp>()) {
56 std::optional<PacketInfoAttr> packet = route.getPacket();
57 if ((packet || clPacketSwObjectFifos) &&
58 !(packet && packet->isAssigned()))
59 unpinned.push_back(route);
61 if (unpinned.size() > 1) {
63 llvm::stable_sort(unpinned, [&](RouteOp a, RouteOp b) {
64 return rank.lookup(a) < rank.lookup(b);
72 DenseMap<StringRef, DMAStartOp> dmaStartByEndpoint;
73 device.walk([&](DMAStartOp start) {
74 if (FlatSymbolRefAttr name = start.getEndpoint())
75 dmaStartByEndpoint.try_emplace(name.getValue(), start);
78 for (
auto route : unpinned) {
79 std::optional<PacketInfoAttr> packet = route.getPacket();
80 for (StringRef source : route.getSourceNames()) {
81 auto it = dmaStartByEndpoint.find(source);
82 if (it == dmaStartByEndpoint.end())
84 it->second.emitOpError(
"names @")
86 <<
", the source of a packet-switched route without a pinned "
87 "pkt_id; pin pkt_id on each route it sources and state that "
88 "header in each of the program's BDs";
89 return signalPassFailure();
93 route.emitOpError(
"max number of packet IDs reached");
94 return signalPassFailure();
96 uint16_t type = packet ? packet->getPktType() : 0;
97 route.setPacketAttr(PacketInfoAttr::get(device.getContext(), type, *
id));
104std::unique_ptr<OperationPass<DeviceOp>>
106 return std::make_unique<AIEAssignPacketIdsPass>();
109std::unique_ptr<OperationPass<DeviceOp>>
111 bool reserveControllerPacketIds) {
112 AIEAssignPacketIdsOptions options;
113 options.clPacketSwObjectFifos = packetSwitched;
114 options.clReserveControllerPacketIds = reserveControllerPacketIds;
115 return std::make_unique<AIEAssignPacketIdsPass>(options);
std::optional< int > takeLowestFrom(int from=0)
Takes and returns the lowest free id at or above from, or nothing when the field is exhausted.
int maxId() const
The largest id the target's header field holds.
std::unique_ptr< mlir::OperationPass< DeviceOp > > createAIEAssignPacketIdsPass()
llvm::DenseMap< mlir::Operation *, unsigned > rank() const
Rank the nodes by their features and then, a round at a time until no class splits,...
static StructuralGraph of(DeviceOp device)
The ops directly in device but its runtime sequences, each with the ops nested in it,...