optimizer: fix reordering in `let+values`+`values` splitting

While the commit comment in 3150b31eb7 still seems right, the changed
overlooked the fact that the arguments to a split `values` might get
reordered (due to the way binding positions are calculated). Fix the
optimizer to make sure that reordering is allowed.

The change touches a lot of code, because we want to use
"omittable" to implement "movable", and it's not ok to
reorder access of mutable variables (in case some other thread is
mutating them). We have to fix all the calls to "omittable"
to support the slight generalization.
optimizer: improvements mostly for splitting of multiple-value bindings

Convert

 (let-values ([(<id> ...) (if <id-t>
                              (values <e1> ...)
                              (values <e2> ...))])
    ....)

to

 (let ([<id> (if <id-t> <e1> <e2>)]
       ...)
    ....)

which duplicates the `(if <id-t> ....)` test, but that's likely to
be worthwhile to avoid multiple-values shuffling and enable more
constant and copy propagation.

A related improvement is to more eagerly discard `let` wrappers
with unused bindings during optimization, which could enable
further optimization, and allow moving conditionals relative
to other expressions to avoid intermediate binding.

Eagerly discarding `let` wrappers exposed a bug in the optimizer's
shifting of variable locations by exercising the relavant shifting
operation in shift_closure_compilation().

Closes PR 14588