46 auto lowerBound = arith::ConstantOp::create(
47 builder, builder.getUnknownLoc(), builder.getIndexAttr(0));
48 auto upperBound = arith::ConstantOp::create(
49 builder, builder.getUnknownLoc(), builder.getIndexAttr(length));
50 auto step = arith::ConstantOp::create(builder, builder.getUnknownLoc(),
51 builder.getIndexAttr(1));
52 auto forLoop = scf::ForOp::create(builder, builder.getUnknownLoc(),
53 lowerBound, upperBound, step);
58 ObjectFifoRegisterProcessOp regOp, MemRefType elementType,
59 IntegerAttr acqNumber, IntegerAttr relNumber,
int length) {
60 auto ctx = device->getContext();
65 Region &forRegion = forLoop.getRegion();
66 builder.setInsertionPointToStart(&forRegion.back());
70 if (acqNumber.getInt() > 0) {
71 auto acqType = AIEObjectFifoSubviewType::get(elementType);
72 auto acqOp = ObjectFifoAcquireOp::create(
73 builder, builder.getUnknownLoc(), acqType, regOp.getPortAttr(),
74 SymbolRefAttr::get(ctx, regOp.getObjFifoName()), acqNumber);
77 for (
int i = 0; i < acqNumber.getInt(); i++)
78 (
void)ObjectFifoSubviewAccessOp::create(
79 builder, builder.getUnknownLoc(), elementType, acqOp.getSubview(),
80 builder.getIntegerAttr(builder.getI32Type(), i));
84 for (
auto funcOp : device.getOps<func::FuncOp>()) {
85 if (funcOp.getSymName() == regOp.getCallee()) {
90 func::CallOp::create(builder, builder.getUnknownLoc(),
95 if (relNumber.getInt() > 0) {
96 auto relOp = ObjectFifoReleaseOp::create(
97 builder, builder.getUnknownLoc(), regOp.getPortAttr(),
98 SymbolRefAttr::get(ctx, regOp.getObjFifoName()), relNumber);
99 builder.setInsertionPointAfter(relOp);
103 builder.setInsertionPointAfter(forLoop);
107 DeviceOp device = getOperation();
108 OpBuilder builder = OpBuilder::atBlockTerminator(device.getBody());
109 DenseMap<ObjectFifoCreateOp, std::queue<Value>> consumersPerFifo;
113 for (
auto registerOp : device.getOps<ObjectFifoRegisterProcessOp>()) {
114 builder.setInsertionPoint(device.getBody()->getTerminator());
115 ObjectFifoCreateOp objFifo = registerOp.getObjectFifo();
117 llvm::dyn_cast<AIEObjectFifoType>(objFifo.getElemType())
120 if (consumersPerFifo.find(objFifo) == consumersPerFifo.end()) {
121 std::queue<Value> consumers;
122 for (
auto consumerTile : objFifo.getConsumerTiles())
123 consumers.push(consumerTile);
124 consumersPerFifo[objFifo] = consumers;
129 if (registerOp.getPort() == ObjectFifoPort::Produce)
130 tile = objFifo.getProducerTile();
131 else if (registerOp.getPort() == ObjectFifoPort::Consume) {
132 assert(!consumersPerFifo[objFifo].empty() &&
133 "No more available consumer tiles for process.");
134 tile = consumersPerFifo[objFifo].front();
135 consumersPerFifo[objFifo].pop();
138 Operation *op = llvm::find_singleton<Operation>(
139 device.getOps<CoreOp>(),
140 [&tile](CoreOp coreOp,
bool) {
141 return coreOp.getTile() == tile ? coreOp.getOperation() : nullptr;
146 CoreOp coreOp = CoreOp::create(builder, builder.getUnknownLoc(),
147 builder.getIndexType(), tile);
148 Region &r = coreOp.getBody();
149 r.push_back(
new Block);
150 Block &block = r.back();
151 builder.setInsertionPointToStart(&block);
152 EndOp::create(builder, builder.getUnknownLoc());
153 builder.setInsertionPointToStart(&block);
155 CoreOp coreOp = llvm::dyn_cast<CoreOp>(op);
156 Region &r = coreOp.getBody();
157 Block &endBlock = r.back();
158 builder.setInsertionPointToStart(&endBlock);
162 auto acqSize = registerOp.getAcquirePattern().size();
164 if (
auto relSize = registerOp.getReleasePattern().size();
165 acqSize == 1 && relSize == 1) {
166 IntegerAttr acqNumber =
167 registerOp.getAcquirePattern().getValues<IntegerAttr>()[0];
168 IntegerAttr relNumber =
169 registerOp.getReleasePattern().getValues<IntegerAttr>()[0];
170 createPattern(builder, device, registerOp, elementType, acqNumber,
171 relNumber, registerOp.getProcessLength());
175 registerOp.getAcquirePattern().getValues<IntegerAttr>();
176 std::vector<IntegerAttr> acqVector;
177 for (
auto i = acqPattern.begin(); i != acqPattern.end(); ++i)
178 acqVector.push_back(*i);
181 registerOp.getReleasePattern().getValues<IntegerAttr>();
182 std::vector<IntegerAttr> relVector;
183 for (
auto i = relPattern.begin(); i != relPattern.end(); ++i)
184 relVector.push_back(*i);
188 IntegerAttr acqNumber =
189 registerOp.getAcquirePattern().getValues<IntegerAttr>()[0];
190 std::vector values(registerOp.getProcessLength(), acqNumber);
192 acqSize = registerOp.getProcessLength();
194 }
else if (relSize == 1) {
196 IntegerAttr relNumber =
197 registerOp.getReleasePattern().getValues<IntegerAttr>()[0];
198 std::vector values(registerOp.getProcessLength(), relNumber);
203 for (
int i = 0; i < acqSize; i++) {
204 auto currAcq = acqVector[i];
205 auto currRel = relVector[i];
206 if (i < acqSize - 1) {
207 auto nextAcq = acqVector[i + 1];
208 if (
auto nextRel = relVector[i + 1];
209 currAcq.getInt() == nextAcq.getInt() &&
210 currRel.getInt() == nextRel.getInt()) {
215 createPattern(builder, device, registerOp, elementType, currAcq,
225 SmallVector<Operation *> opsToErase;
226 device.walk([&](Operation *op) {
227 if (isa<ObjectFifoRegisterProcessOp>(op))
228 opsToErase.push_back(op);
230 for (
auto op : opsToErase)