33  Side Effects

Side effects are observable behavior beyond an operation’s SSA results. Writing memory, allocating, freeing, performing I/O, synchronizing, and calling an unknown function can all be effects. Effects determine which operations may be deleted, duplicated, reordered, or merged.

33.1 Results Are Not The Whole Program

An operation with no results is not automatically dead. A store has no result but changes memory. An allocation may create a resource whose lifetime matters. A call may update global state even if it returns nothing. Conversely, a pure operation with an unused result can often be removed.

This is the proof behind dead-code elimination: no uses alone is insufficient; the operation must also have no observable effect. Common-subexpression elimination similarly requires both equivalent operands and compatible effects.

33.2 Effects Enable Conservative Generic Passes

MLIR operations can expose effects through interfaces. Generic code asks whether an operation reads, writes, allocates, frees, or has unknown behavior on a resource. If no trustworthy model is available, the pass must be conservative. Unknown does not mean no effect.

Effects are also ordered by control and data dependencies. Moving a store before a potentially aliasing load can change behavior even if neither operation’s SSA results are used. A pass needs memory-effect and alias information, not merely a walk over operation order.