40 auto lowerBound = builder.create<arith::ConstantOp>(
41 builder.getUnknownLoc(), builder.getIndexAttr(0));
42 auto upperBound = builder.create<arith::ConstantOp>(
43 builder.getUnknownLoc(), builder.getIndexAttr(length));
44 auto step = builder.create<arith::ConstantOp>(builder.getUnknownLoc(),
45 builder.getIndexAttr(1));
46 auto forLoop = builder.create<scf::ForOp>(builder.getUnknownLoc(),
47 lowerBound, upperBound, step);
52 ObjectFifoRegisterProcessOp regOp, MemRefType elementType,
53 IntegerAttr acqNumber, IntegerAttr relNumber,
int length) {
54 auto ctx = device->getContext();
59 Region &forRegion = forLoop.getRegion();
60 builder.setInsertionPointToStart(&forRegion.back());
64 if (acqNumber.getInt() > 0) {
65 auto acqType = AIEObjectFifoSubviewType::get(elementType);
66 auto acqOp = builder.create<ObjectFifoAcquireOp>(
67 builder.getUnknownLoc(), acqType, regOp.getPortAttr(),
68 SymbolRefAttr::get(ctx, regOp.getObjFifoName()), acqNumber);
71 for (
int i = 0; i < acqNumber.getInt(); i++)
72 (
void)builder.create<ObjectFifoSubviewAccessOp>(
73 builder.getUnknownLoc(), elementType, acqOp.getSubview(),
74 builder.getIntegerAttr(builder.getI32Type(), i));
78 for (
auto funcOp : device.getOps<func::FuncOp>()) {
79 if (funcOp.getSymName() == regOp.getCallee()) {
84 builder.create<func::CallOp>(builder.getUnknownLoc(),
89 if (relNumber.getInt() > 0) {
90 auto relOp = builder.create<ObjectFifoReleaseOp>(
91 builder.getUnknownLoc(), regOp.getPortAttr(),
92 SymbolRefAttr::get(ctx, regOp.getObjFifoName()), relNumber);
93 builder.setInsertionPointAfter(relOp);
97 builder.setInsertionPointAfter(forLoop);
101 DeviceOp device = getOperation();
102 OpBuilder builder = OpBuilder::atBlockTerminator(device.getBody());
103 DenseMap<ObjectFifoCreateOp, std::queue<Value>> consumersPerFifo;
107 for (
auto registerOp : device.getOps<ObjectFifoRegisterProcessOp>()) {
108 builder.setInsertionPoint(device.getBody()->getTerminator());
109 ObjectFifoCreateOp objFifo = registerOp.getObjectFifo();
111 llvm::dyn_cast<AIEObjectFifoType>(objFifo.getElemType())
114 if (consumersPerFifo.find(objFifo) == consumersPerFifo.end()) {
115 std::queue<Value> consumers;
116 for (
auto consumerTile : objFifo.getConsumerTiles())
117 consumers.push(consumerTile);
118 consumersPerFifo[objFifo] = consumers;
123 if (registerOp.getPort() == ObjectFifoPort::Produce)
124 tile = objFifo.getProducerTile();
125 else if (registerOp.getPort() == ObjectFifoPort::Consume) {
126 assert(!consumersPerFifo[objFifo].empty() &&
127 "No more available consumer tiles for process.");
128 tile = consumersPerFifo[objFifo].front();
129 consumersPerFifo[objFifo].pop();
132 Operation *op = llvm::find_singleton<Operation>(
133 device.getOps<CoreOp>(),
134 [&tile](CoreOp coreOp,
bool) {
135 return coreOp.getTile() == tile ? coreOp.getOperation() : nullptr;
140 CoreOp coreOp = builder.create<CoreOp>(builder.getUnknownLoc(),
141 builder.getIndexType(), tile);
142 Region &r = coreOp.getBody();
143 r.push_back(
new Block);
144 Block &block = r.back();
145 builder.setInsertionPointToStart(&block);
146 builder.create<EndOp>(builder.getUnknownLoc());
147 builder.setInsertionPointToStart(&block);
149 CoreOp coreOp = llvm::dyn_cast<CoreOp>(op);
150 Region &r = coreOp.getBody();
151 Block &endBlock = r.back();
152 builder.setInsertionPointToStart(&endBlock);
156 auto acqSize = registerOp.getAcquirePattern().size();
158 if (
auto relSize = registerOp.getReleasePattern().size();
159 acqSize == 1 && relSize == 1) {
160 IntegerAttr acqNumber =
161 registerOp.getAcquirePattern().getValues<IntegerAttr>()[0];
162 IntegerAttr relNumber =
163 registerOp.getReleasePattern().getValues<IntegerAttr>()[0];
164 createPattern(builder, device, registerOp, elementType, acqNumber,
165 relNumber, registerOp.getProcessLength());
169 registerOp.getAcquirePattern().getValues<IntegerAttr>();
170 std::vector<IntegerAttr> acqVector;
171 for (
auto i = acqPattern.begin(); i != acqPattern.end(); ++i)
172 acqVector.push_back(*i);
175 registerOp.getReleasePattern().getValues<IntegerAttr>();
176 std::vector<IntegerAttr> relVector;
177 for (
auto i = relPattern.begin(); i != relPattern.end(); ++i)
178 relVector.push_back(*i);
182 IntegerAttr acqNumber =
183 registerOp.getAcquirePattern().getValues<IntegerAttr>()[0];
184 std::vector values(registerOp.getProcessLength(), acqNumber);
186 acqSize = registerOp.getProcessLength();
188 }
else if (relSize == 1) {
190 IntegerAttr relNumber =
191 registerOp.getReleasePattern().getValues<IntegerAttr>()[0];
192 std::vector values(registerOp.getProcessLength(), relNumber);
197 for (
int i = 0; i < acqSize; i++) {
198 auto currAcq = acqVector[i];
199 auto currRel = relVector[i];
200 if (i < acqSize - 1) {
201 auto nextAcq = acqVector[i + 1];
202 if (
auto nextRel = relVector[i + 1];
203 currAcq.getInt() == nextAcq.getInt() &&
204 currRel.getInt() == nextRel.getInt()) {
209 createPattern(builder, device, registerOp, elementType, currAcq,
219 SmallVector<Operation *> opsToErase;
220 device.walk([&](Operation *op) {
221 if (isa<ObjectFifoRegisterProcessOp>(op))
222 opsToErase.push_back(op);
224 for (
auto op : opsToErase)