CSE won’t get rid of side-effecting ops, but if the side-effecting ops look the same, it won’t matter anyways (from a matching perspective).
You will also need to account for ops’s attributes (e.g. cmpi sle
vs cmpi sgt
).
I’m not 100% behind the idea of a pass. Some commutative ops prefer a particular form. E.g. arith.addi/f
will always move constants to the RHS. We wouldn’t want to indiscriminately run this sorting pass. It sounds more useful as a utility: sortCommutativeOperands(Operation *)
which can be called by either C++ or PDL patterns.
The tricky part (especially for hand-written C++ patterns) is that the pattern will need to be aware of the sorting order and order its operand constraints accordingly. I would imagine a commutative pattern comprised of two parts:
- Sort the commutative operands of an op. If the order has changed, update the op in-place and return success. Otherwise return failure.
- Match the commutative op with the operand constraints sorted the same way as the operands would be.
E.g.
%a = a
%b = b
%0 = add %b, %a // add is commutative
%1 = sub %a, %b
%2 = foo %1, %0 // foo is commutative
And the pattern is meant to match foo(sub(a, b), add(b, a))
. The pattern will need to be sorted to become foo(add(a, b), sub(a, b))
as well as the IR.