1 use crate::{isa::reg::Reg, regset::RegSet}; 2 3 /// The register allocator. 4 /// 5 /// The register allocator uses a single-pass algorithm; 6 /// its implementation uses a bitset as a freelist 7 /// to track per-class register availability. 8 /// 9 /// If a particular register is not available upon request 10 /// the register allocation will perform a "spill", essentially 11 /// moving Local and Register values in the stack to memory. 12 /// This processs ensures that whenever a register is requested, 13 /// it is going to be available. 14 pub(crate) struct RegAlloc { 15 pub scratch: Reg, 16 regset: RegSet, 17 } 18 19 impl RegAlloc { 20 /// Create a new register allocator 21 /// from a register set. 22 pub fn new(regset: RegSet, scratch: Reg) -> Self { 23 Self { regset, scratch } 24 } 25 26 /// Allocate the next available general purpose register, 27 /// spilling if none available. 28 pub fn any_gpr<F>(&mut self, spill: &mut F) -> Reg 29 where 30 F: FnMut(&mut RegAlloc), 31 { 32 self.regset.any_gpr().unwrap_or_else(|| { 33 spill(self); 34 self.regset.any_gpr().expect("any gpr to be available") 35 }) 36 } 37 38 /// Checks if a general purpose register is avaiable. 39 pub fn gpr_available(&self, reg: Reg) -> bool { 40 self.regset.named_gpr_available(reg.hw_enc() as u32) 41 } 42 43 /// Request a specific general purpose register, 44 /// spilling if not available. 45 pub fn gpr<F>(&mut self, named: Reg, spill: &mut F) -> Reg 46 where 47 F: FnMut(&mut RegAlloc), 48 { 49 // If the scratch register is explicitly requested 50 // just return it, it's usage should never cause spills. 51 if named == self.scratch { 52 return named; 53 } 54 55 self.regset.gpr(named).unwrap_or_else(|| { 56 spill(self); 57 self.regset 58 .gpr(named) 59 .expect(&format!("gpr {:?} to be available", named)) 60 }) 61 } 62 63 /// Mark a particular general purpose register as available. 64 pub fn free_gpr(&mut self, reg: Reg) { 65 // Never mark the designated scratch register as allocatable. 66 if reg != self.scratch { 67 self.regset.free_gpr(reg); 68 } 69 } 70 } 71