pm_runtime iterates through the ops that make up the replacement part
of s///, to see whether the ops on the rhs can have side effects or
contain match vars (in which case they must only be evaluted after the
pattern). If they do not have side-effects, the rhs is presumed to be
constant and evaluated first, and then pp_subst hangs on to the return
value and reuses it in each iteration of s///g.

This iteration simply follows op_next pointers. Logops are not that
simple, so it is possible to hide match vars inside them, resulting in
incorrect optimisations: