19#include "mlir/Dialect/Utils/StaticValueUtils.h"
20#include "mlir/Pass/Pass.h"
23#define GEN_PASS_DEF_AIESPLITLONGREPEATS
24#include "aie/Dialect/AIEX/Transforms/AIEXPasses.h.inc"
33struct AIESplitLongRepeatsPass
34 : xilinx::AIEX::impl::AIESplitLongRepeatsBase<AIESplitLongRepeatsPass> {
35 void runOnOperation()
override {
36 AIE::DeviceOp device = getOperation();
37 uint32_t maxRepeat = device.getTargetModel().getMaxRepeatCount();
38 int64_t queueDepth = device.getTargetModel().getDmaTaskQueueDepth();
43 SmallVector<DMAStartTaskOp> starts;
44 device.walk([&](DMAStartTaskOp start) { starts.push_back(start); });
45 for (DMAStartTaskOp start : starts) {
48 std::optional<int64_t> rc;
49 if (start.hasRepeatParameter()) {
52 DMAConfigureTaskOp cfg = start.getTaskOp();
53 if (cfg && cfg.getRepeatCount() > maxRepeat) {
54 start.emitOpError(
"takes its repeat count from a scratchpad "
55 "parameter, which reaches one queue push, but its "
56 "task's repeat count, the parameter's maximum, is ")
57 << cfg.getRepeatCount() <<
", past the target's " << maxRepeat;
58 return signalPassFailure();
62 if (std::optional<uint32_t> own = start.getRepeatCount()) {
64 }
else if (Value ownVal = start.getRepeatCountVal()) {
65 rc = getConstantIntValue(ownVal);
67 DMAConfigureTaskOp cfg = start.getTaskOp();
72 rc = getConstantIntValue(start.getPushRepeatCount(cfg));
74 if (!rc || *rc <= maxRepeat)
76 int64_t pushes = (*rc + maxRepeat + 1) / (maxRepeat + 1);
77 if (pushes >
static_cast<int64_t
>(maxPushes)) {
78 start.emitOpError(
"repeat count ")
79 << *rc <<
" needs " << pushes
80 <<
" queue pushes, more than max-pushes (" << maxPushes.getValue()
82 return signalPassFailure();
84 if (queueDepth > 0 && pushes > queueDepth)
85 start.emitWarning(
"repeat count ")
86 << *rc <<
" needs " << pushes <<
" queue pushes, more than the "
88 <<
" the channel's queue holds, so the sequence waits for this "
89 "channel to drain before going on. A transfer this one waits "
90 "on must be started before it, or the wait never ends.";
94 int64_t runs = *rc + 1;
95 for (; runs > maxRepeat + 1; runs -= maxRepeat + 1)
96 DMAStartTaskOp::create(b, start.getLoc(), start.getTask(),
97 b.getI32IntegerAttr(maxRepeat),
102 start.setRepeatCountAttr(b.getI32IntegerAttr(runs - 1));
103 start.getRepeatCountValMutable().clear();
110std::unique_ptr<mlir::OperationPass<AIE::DeviceOp>>
112 return std::make_unique<AIESplitLongRepeatsPass>();
DMAConfigureTaskOp getUniqueReachableConfigure(Value task)
std::unique_ptr< mlir::OperationPass< AIE::DeviceOp > > createAIESplitLongRepeatsPass()