From what I understand about MLIR, Pure ops can be freely reordered during the execution of a pass.But I have trouble drawing conclusions about the op who didn’t mark any side effects.
like this
class My_DialectOp<string mnemonic, list<Trait> traits = []> :
Op<My_Dialect, mnemonic, traits> {}
def My_Op : My_DialectOp<"my_op"> {
let assemblyFormat = "attr-dict";
let hasCanonicalizer = 1;
}
Furthermore, under what circumstances will they be reordered?(Because at present, I have not encountered such a situation where Op is reordered) If it is reordered, how can I ensure that it will not be reordered?
My understanding is that if an op isn’t side-effecting, the compiler can reordered it. However, SSA semantics must remain the same.
As a side note, side-effecting behavior isn’t clearly implemented for every op. For example, gpu.barrier isn’t marked as a side-effecting op, but it actually introduces a memory fence—at least on NVIDIA—so it is side-effecting.
A pass won’t arbitrarily reorder (and to Gray’s point, SSA dominance still restricts to what extend). But if pure op, a pass may within valid orders. The ones that come to mind is LICM and folding & constant hosting as part of greedy rewrite driver (which is used by canonicalization). There may be more examples in the RFC that introduced speculative bits.
One that I’d like but we don’t yet have: a pass that reorders to decrease diffs (if two ops can be ordered any way.wrt each other, choose one determistic order so that comparing two graphs have less unimportant differences).
An op that does not declare itself explicitly as “no side effect” is considered to have “unknown side effects” by default side effecting conservatively. This is what I commented on the review!
(that applies to the gpu.barrier that @grypp mentions above)