regalloc: Count excess callee registers once

625eabb9efb2e0b94045cd2a546ce66ee33ecbc4fa712501d12c7bf239f47309
Compute the excess callee-class count once and select all spills with
one iterator. This avoids repeated bitset scans while preserving the
ascending register order and the global callee-saved register limit.

Assisted-by: Codex:gpt-6-astra
Alexis Sellier committed ago 1 parent e0c7ad6c
lib/std/lang/gen/regalloc/spill.rad +9 -6
151 151
    // Phase 3: Enforce global callee-class limit.
152 152
    // The per-call-site limit may leave the callee-class set larger than
153 153
    // `numCalleeSaved` when different call sites keep different subsets.
154 154
    // Spill excess values to guarantee the assignment phase always finds
155 155
    // a callee-saved register for cross-call values.
156 -
    while bitset::count(&calleeClass) > numCalleeSaved {
156 +
    let calleeCount = bitset::count(&calleeClass);
157 +
    if calleeCount > numCalleeSaved {
157 158
        let mut it = bitset::iter(&calleeClass);
158 -
        if let reg = bitset::iterNext(&mut it) {
159 -
            bitset::clear(&mut calleeClass, reg);
160 -
            bitset::put(&mut spilled, reg);
161 -
        } else {
162 -
            panic "spill: count > 0 but no set bits found";
159 +
        for _ in 0..(calleeCount - numCalleeSaved) {
160 +
            if let reg = bitset::iterNext(&mut it) {
161 +
                bitset::clear(&mut calleeClass, reg);
162 +
                bitset::put(&mut spilled, reg);
163 +
            } else {
164 +
                panic "spill: count > 0 but no set bits found";
165 +
            }
163 166
        }
164 167
    }
165 168
166 169
    // Phase 4: Assign stack slots to spilled values.
167 170
    let mut frameSize: i32 = 0;