@@ -43,50 +43,34 @@ static bool overrideBuffer(Operation *op, Value buffer) {
4343// / propagate the type change and erase old subview ops.
4444static  void  replaceUsesAndPropagateType (RewriterBase &rewriter,
4545                                        Operation *oldOp, Value val) {
46-   SmallVector<Operation *> opsToDelete;
47-   SmallVector<OpOperand *> operandsToReplace;
48- 
49-   //  Save the operand to replace / delete later (avoid iterator invalidation).
50-   //  TODO: can we use an early_inc iterator?
51-   for  (OpOperand &use : oldOp->getUses ()) {
52-     //  Non-subview ops will be replaced by `val`.
53-     auto  subviewUse = dyn_cast<memref::SubViewOp>(use.getOwner ());
54-     if  (!subviewUse) {
55-       operandsToReplace.push_back (&use);
46+   //  Iterate with early_inc to erase current user inside the loop.
47+   for  (OpOperand &use : llvm::make_early_inc_range (oldOp->getUses ())) {
48+     Operation *user = use.getOwner ();
49+     if  (auto  subviewUse = dyn_cast<memref::SubViewOp>(user)) {
50+       //  `subview(old_op)` is replaced by a new `subview(val)`.
51+       OpBuilder::InsertionGuard g (rewriter);
52+       rewriter.setInsertionPoint (subviewUse);
53+       MemRefType newType = memref::SubViewOp::inferRankReducedResultType (
54+           subviewUse.getType ().getShape (), cast<MemRefType>(val.getType ()),
55+           subviewUse.getStaticOffsets (), subviewUse.getStaticSizes (),
56+           subviewUse.getStaticStrides ());
57+       Value newSubview = memref::SubViewOp::create (
58+           rewriter, subviewUse->getLoc (), newType, val,
59+           subviewUse.getMixedOffsets (), subviewUse.getMixedSizes (),
60+           subviewUse.getMixedStrides ());
61+ 
62+       //  Ouch recursion ... is this really necessary?
63+       replaceUsesAndPropagateType (rewriter, subviewUse, newSubview);
64+ 
65+       //  Safe to erase.
66+       rewriter.eraseOp (subviewUse);
5667      continue ;
5768    }
58- 
59-     //  `subview(old_op)` is replaced by a new `subview(val)`.
60-     OpBuilder::InsertionGuard g (rewriter);
61-     rewriter.setInsertionPoint (subviewUse);
62-     MemRefType newType = memref::SubViewOp::inferRankReducedResultType (
63-         subviewUse.getType ().getShape (), cast<MemRefType>(val.getType ()),
64-         subviewUse.getStaticOffsets (), subviewUse.getStaticSizes (),
65-         subviewUse.getStaticStrides ());
66-     Value newSubview = memref::SubViewOp::create (
67-         rewriter, subviewUse->getLoc (), newType, val,
68-         subviewUse.getMixedOffsets (), subviewUse.getMixedSizes (),
69-         subviewUse.getMixedStrides ());
70- 
71-     //  Ouch recursion ... is this really necessary?
72-     replaceUsesAndPropagateType (rewriter, subviewUse, newSubview);
73- 
74-     opsToDelete.push_back (use.getOwner ());
69+     //  Non-subview: replace with new value.
70+     rewriter.startOpModification (user);
71+     use.set (val);
72+     rewriter.finalizeOpModification (user);
7573  }
76- 
77-   //  Perform late replacement.
78-   //  TODO: can we use an early_inc iterator?
79-   for  (OpOperand *operand : operandsToReplace) {
80-     Operation *op = operand->getOwner ();
81-     rewriter.startOpModification (op);
82-     operand->set (val);
83-     rewriter.finalizeOpModification (op);
84-   }
85- 
86-   //  Perform late op erasure.
87-   //  TODO: can we use an early_inc iterator?
88-   for  (Operation *op : opsToDelete)
89-     rewriter.eraseOp (op);
9074}
9175
9276//  Transformation to do multi-buffering/array expansion to remove dependencies
@@ -216,8 +200,8 @@ mlir::memref::multiBuffer(RewriterBase &rewriter, memref::AllocOp allocOp,
216200                                            offsets, sizes, strides);
217201  LLVM_DEBUG (DBGS () << " --multi-buffered slice: "   << subview << " \n "  );
218202
219-   //  5. Due to the recursive nature of replaceUsesAndPropagateType , we need to 
220-   //  handle dealloc uses separately..
203+   //  5. Due to the recursive nature of replaceUsesAndPropagateType , we need
204+   //  to  handle dealloc uses separately..
221205  for  (OpOperand &use : llvm::make_early_inc_range (allocOp->getUses ())) {
222206    auto  deallocOp = dyn_cast<memref::DeallocOp>(use.getOwner ());
223207    if  (!deallocOp)
0 commit comments