* Limit split count per original bundle with fallback 1-to-N split. Right now, splitting a bundle produces two halves. Furthermore, it has cost linear in the length of the bundle, because the resulting half-bundles have their requirements recomputed with a new scan, and because we copy half the use-list over to the tail end sub-bundle. This works fine when a bundle has a handful of splits overall, but not when an input has a systematic pattern of conflicts that will require O(|bundle|) splits (e.g., every Use is constrained to a different fixed register than the last one). In such a case, we get quadratic behavior. This PR adds a per-spillset (so, per-original-bundle) counter for splits, and when it reaches a preset threshold (10 for now), we instead split directly into minimal bundles along the whole length of the bundle, putting the regions without uses in the spill bundle. This basically approximates what a non-splitting allocator would do: it "spills" the whole bundle to possibly a stackslot, or a second-chance register allocation at best, via the spill bundle; and then does minimal reservations of registers just at uses/defs and moves the "spilled" value into/out of them immediately. Together with another small optimization, this PR results in a 4x compilation speedup and 24x memory use reduction on one particularly bad case with alternating conflicting requirements on a vreg (see bytecodealliance/wasmtime#4291 for details). * Review comments.
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.