TODO-list update: braindump of next ideas to work on.

This commit is contained in:
Chris Fallin
2021-05-23 20:04:28 -07:00
parent 107c09181f
commit 59967ff756

View File

@@ -20,17 +20,45 @@
*/ */
/* /*
Performance ideas: Performance and code-quality ideas:
- conflict hints? (note on one bundle that it definitely conflicts - Split heuristics:
with another, so avoid probing the other's alloc) - Loop depth at split point? Split before entering more nested loop
- Split at earliest vs latest conflict -- study more
- partial allocation -- place one LR, split rest off into separate - Reduced spilling when spillslot is still "clean":
bundle, in one pass? - When we allocate spillsets, use the whole bundle of a given
spillset to check for fit. Add all bundles to spillset as we
split; then SpillSet::bundles always corresponds to original
merged bundle.
- Then a single bundle will never move between spillslots, so we
know that when we reload from the one single spillslot, it is
the last value that we spilled.
- So we can track 'dirty' status of reg and elide spill when not
dirty.
- This is slightly tricky: fixpoint problem, across edges.
- We can simplify by assuming spillslot is dirty if value came
in on BB edge; only clean if we reload in same block we spill
in.
- As a slightly better variation on this, track dirty during
scan in a single range while resolving moves; in-edge makes
dirty.
- coarse-grained "register contention" counters per fixed region; - Add weight to bundles according to progmoves
randomly sample these, adding up a vector of them, to choose
register probe order? - Efficiency improvements:
- Record 'cheapest evict bundle so far' and stop scanning if
total evict cost exceeds that
- Avoid requiring two scratch regs:
- Require machine impl to be able to (i) push a reg, (ii) pop a
reg; then generate a balanced pair of push/pop, using the stack
slot as the scratch.
- on Cranelift side, take care to generate virtual-SP
adjustments!
- For a spillslot->spillslot move, push a fixed reg (say the
first preferred one), reload into it, spill out of it, and then
pop old val
*/ */
#![allow(dead_code, unused_imports)] #![allow(dead_code, unused_imports)]
@@ -2410,9 +2438,10 @@ impl<'a, F: Function> Env<'a, F> {
// O(b * n log n) with the simple probe-for-each-bundle-range // O(b * n log n) with the simple probe-for-each-bundle-range
// approach. // approach.
// //
// Note that the comparator function on a CodeRange tests for *overlap*, so we // Note that the comparator function on a CodeRange tests for
// are checking whether the BTree contains any preg range that // *overlap*, so we are checking whether the BTree contains
// *overlaps* with range `range`, not literally the range `range`. // any preg range that *overlaps* with range `range`, not
// literally the range `range`.
let bundle_ranges = &self.bundles[bundle.index()].ranges; let bundle_ranges = &self.bundles[bundle.index()].ranges;
let from_key = LiveRangeKey::from_range(&bundle_ranges.first().unwrap().range); let from_key = LiveRangeKey::from_range(&bundle_ranges.first().unwrap().range);
let to_key = LiveRangeKey::from_range(&bundle_ranges.last().unwrap().range); let to_key = LiveRangeKey::from_range(&bundle_ranges.last().unwrap().range);