postponeConditionallyUsedValues

Regenerate the edge-split SSA graph, postponing emission of side-effectless instructions until just before they're needed.

The L2ValueManifest maintains a map from L2SemanticValue to an L2Instruction that was translated from the original graph, but not yet emitted. When a register kind / semantic value pair is needed by an instruction being emitted, we emit a copy of the instruction to provide that value (recursively, as needed).

This maximally postpones construction of values, ensuring they're only constructed along paths where they're actually needed.

The astute reader will have noticed I haven't mentioned control flow merges. Normally a control flow merge produces phi instructions for any semantic values common to all incoming edges that aren't from a common register. When postponing instructions in this way, we want to avoid generating the same value multiple times along any path. Therefore, if we have a semantic value available in a register on at least one incoming path, and that semantic value is either available in the manifests or available as a postponed instruction in each of the incoming edges, we force the postponed instructions to be generated in the predecessor blocks, just prior to their final jump. This is safe, because we're at a merge point in an edge-split SSA graph, so none of the predecessors can have multiple successors.

This effects a complete redundancy elimination (other than for loops). The resulting graph is still in edge-split SSA form.