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
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; |