The `Operand` abstraction allows a def to be positioned at the "early" point of an instruction, before its effect and alongside its normal uses. This is intended to allow the embedder to express that a def may be written before all uses are read, so it should not conflict with the uses. It's also convenient to use early defs to express temporaries, which should be available throughout a regalloc-level instruction's emitted sequence. In such a case, the register should not be used again after the instruction, so it is dead following the instruction. Strictly speaking, and according to regalloc2 prior to this PR, then the temp will *only* conflict with the uses at the early-point, and not the defs at the late-point (after the instruction), because it's dead past its point of definition. But for a temp we really want it to register conflicts not just with the normal uses but with the normal defs as well. This PR changes the semantics so that an early def builds a liverange that spans the early- and late-point of an instruction when the vreg is dead flowing down from the instruction, giving the semantics we want for temps.
regalloc2: another register allocator
This is a register allocator that started life as, and is about 50% still, a port of IonMonkey's backtracking register allocator to Rust. In many regards, it has been generalized, optimized, and improved since the initial port, and now supports both SSA and non-SSA use-cases.
In addition, it contains substantial amounts of testing infrastructure (fuzzing harnesses and checkers) that does not exist in the original IonMonkey allocator.
See the design overview for (much!) more detail on how the allocator works.
License
This crate is licensed under the Apache 2.0 License with LLVM
Exception. This license text can be found in the file LICENSE.
Parts of the code are derived from regalloc.rs: in particular,
src/checker.rs and src/domtree.rs. This crate has the same license
as regalloc.rs, so the license on these files does not differ.