Ghost instructions don't generate code, but they can keep registers
alive. The coloring pass needs to process values killed by ghost
instructions so it knows when the registers are freed up.
Also track register pressure changes from ghost kills in the spiller.
When the spiller decides to spill a value, bring along all of the values
in its virtual register. This ensures that we won't have problems with
computing register pressure around EBB arguments. They will always be
register-to-register or stack-to-stack with related values using the
same stack slot.
This also means that the reloading pass won't have to deal with spilled
EBB arguments.
* Replace a single-character string literal with a character literal.
* Use is_some() instead of comparing with Some(_).
* Add code-quotes around type names in comments.
* Use !...is_empty() instead of len() != 0.
* Tidy up redundant returns.
* Remove redundant .clone() calls.
* Remove unnecessary explicit lifetime parameters.
* Tidy up unnecessary '&'s.
* Add parens to make operator precedence explicit.
* Use debug_assert_eq instead of debug_assert with ==.
* Replace a &Vec argument with a &[...].
* Replace `a = a op b` with `a op= b`.
* Avoid unnecessary closures.
* Avoid .iter() and .iter_mut() for iterating over containers.
* Remove unneeded qualification.
As soon as a value is spilled, also assign it to a spill slot.
For now, create a new spill slot for each spilled value. In the future,
values will be sharing spill slots of they are phi-related.
An instruction may have fixed operand constraints that make it
impossibly to use a single register value to satisfy two at a time.
Detect when the same value is used for multiple fixed register operands
and insert copies during the spilling pass.
Add a spilling pass which lowers register pressure by assigning SSA
values to the stack. Important missing features:
- Resolve conflicts where an instruction uses the same value more than
once in incompatible ways.
- Deal with EBB arguments.
Fix bugs in the reload pass exposed by the first test case:
- Create live ranges for temporary registers.
- Set encodings on created spill and fill instructions.