@@ -43,50 +43,34 @@ static bool overrideBuffer(Operation *op, Value buffer) {
43
43
// / propagate the type change and erase old subview ops.
44
44
static void replaceUsesAndPropagateType (RewriterBase &rewriter,
45
45
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);
56
67
continue ;
57
68
}
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);
75
73
}
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);
90
74
}
91
75
92
76
// Transformation to do multi-buffering/array expansion to remove dependencies
@@ -216,8 +200,8 @@ mlir::memref::multiBuffer(RewriterBase &rewriter, memref::AllocOp allocOp,
216
200
offsets, sizes, strides);
217
201
LLVM_DEBUG (DBGS () << " --multi-buffered slice: " << subview << " \n " );
218
202
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..
221
205
for (OpOperand &use : llvm::make_early_inc_range (allocOp->getUses ())) {
222
206
auto deallocOp = dyn_cast<memref::DeallocOp>(use.getOwner ());
223
207
if (!deallocOp)
0 commit comments