There isn’t such a pass since an op with side effects isn’t strictly dead and a generic pass can’t delete it without knowing something more about the op. Ops like these are currently erased via a canonicalization pattern - eg. for AllocOp. We’d need to add another trait to create such a pass (like ErasableIfNoUses). But that still won’t help with erasing the iree.list.set in your snippet. That will still need a separate pattern.
The effect of memwrite here being removable is due to unread list if I’m following, but not true in general. E.g., I could have a create.space.on.bus op which creates a resource, the alloc would initialize allocate space in transfer bus [is MemAlloc sufficient for this? One could consider this a visible mutation but doc for MemAlloc says it makes no visible mutation] and the write’s value would be visible across the bus without any use of the create space op (as it’s return is only a resource handle used to compute dependencies).
So seems like pattern rooted on list create and one where one can delete all unless there is some observable use (e.g., a read whose value was used further). To delete one would need a trait like “CanDeleteIfNoUseHasTrait<[MemRead]>” on the list create op, then a general pass could work.
If I follow correctly, you’re trying to point at what is in C/C++ the difference between a volatile and non-volatile memory effect.
We haven’t got into specifying this in MLIR, I believe we consider the memory effects non-volatile ; so we could treat the snippet above in two steps:
dead-store elimination: the writes are “dead”. This is tricky as we haven’t invested in specifying any “escape analysis” either. Aliasing questions can also be raised here to show that a store is really dead.
unused alloc elimination: after removing the writes, the resource is unused and should be able to be eliminated.
Didn’t think about aliasing & escape here, good point. So currently these two steps could be done but would have to conservatively assume more alias and/or escape.
This sounds about right to me. The DSE case is also related to the liveness questions by @jurahul in Liveness broken with regions? – without that, it seems hard to write a DSE pass that supports region-based control flow with reasonable precision.