diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp index 5a268a204..bcc5db0a8 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp @@ -235,43 +235,60 @@ LogicalResult distributeLocalMemory(ModuleOp moduleOp) { return success(); }) .Case( - [&rewriter, &newAlloc]( + [&rewriter, &newAlloc, &toBeErased]( AMDAIE::LogicalObjectFifoFromMemrefOp logicalObjectFifo) { auto type = llvm::cast(newAlloc.getType()); + + // Collect all DmaCpyNdOps which have 'logicalObjectFifo' as + // a source. Currently not handling the case of multiple. + SmallVector dmaOps; for (Operation *objFifoUserOp : logicalObjectFifo->getUsers()) { if (auto dmaOp = dyn_cast(objFifoUserOp); dmaOp.getSourceObjectFifo() == logicalObjectFifo) { - SmallVector empty; - rewriter.setInsertionPoint(dmaOp.getSourceObjectFifo()); - auto source = - rewriter - .create( - rewriter.getUnknownLoc(), - LogicalObjectFifoType::get(type), - newAlloc.getResult()); - rewriter.replaceOp(dmaOp.getSourceObjectFifo(), source); - rewriter.setInsertionPoint(dmaOp); - auto newDmaOp = rewriter.create( - dmaOp.getLoc(), dmaOp.getTarget(), - dmaOp.getTargetMixedOffsets(), - dmaOp.getTargetMixedSizes(), - dmaOp.getTargetMixedStrides(), source, - dmaOp.getSourceMixedOffsets(), - dmaOp.getSourceMixedSizes(), - dmaOp.getSourceMixedStrides()); - rewriter.replaceOp(dmaOp, newDmaOp); - // We have to discard non-zero offsets as subview has - // been replaced by a dedicated allocated memref. - SmallVector allocShape(type.getShape()); - (void)discardAllNonZeroOffsets( - rewriter, - cast( - newDmaOp.getOperation()), - allocShape); + dmaOps.push_back(dmaOp); } } + if (dmaOps.size() == 0) return success(); + if (dmaOps.size() > 1) { + logicalObjectFifo->emitOpError( + "Case of multiple DMA ops not handled yet (easy " + "extension to logic here)"); + return failure(); + } + AMDAIE::DmaCpyNdOp dmaOp = dmaOps[0]; + + SmallVector empty; + rewriter.setInsertionPoint(logicalObjectFifo); + auto source = + rewriter.create( + rewriter.getUnknownLoc(), + LogicalObjectFifoType::get(type), + newAlloc.getResult()); + rewriter.replaceAllUsesWith(logicalObjectFifo, source); + toBeErased.push_back(logicalObjectFifo); + rewriter.setInsertionPoint(dmaOp); + auto newDmaOp = rewriter.create( + dmaOp.getLoc(), dmaOp.getTarget(), + dmaOp.getTargetMixedOffsets(), + dmaOp.getTargetMixedSizes(), + dmaOp.getTargetMixedStrides(), source, + dmaOp.getSourceMixedOffsets(), + dmaOp.getSourceMixedSizes(), + dmaOp.getSourceMixedStrides()); + rewriter.replaceAllUsesWith(dmaOp, newDmaOp); + // TODO: maybe this should be left to a DCE somewhere, + // instead of manually erasing unused ops? + toBeErased.push_back(dmaOp); + // We have to discard non-zero offsets as subview has + // been replaced by a dedicated allocated memref. + SmallVector allocShape(type.getShape()); + (void)discardAllNonZeroOffsets( + rewriter, + cast( + newDmaOp.getOperation()), + allocShape); return success(); }) .Default([&](Operation *userOp) {