diff --git a/src/ion/fast_alloc2.rs b/src/ion/fast_alloc2.rs index 294eca0..5374b48 100644 --- a/src/ion/fast_alloc2.rs +++ b/src/ion/fast_alloc2.rs @@ -1396,7 +1396,52 @@ impl<'a, F: Function> FastAlloc<'a, F> { block: Block, block_after_pos: usize, ) -> Result { - todo!("") + let reg_list = if reg_class == RegClass::Int { + &self.reg_order_int + } else { + &self.reg_order_float + }; + + let mut ffu_reg = None; + for &preg in reg_list { + if reg_blacklist.contains(preg) { + continue; + } + + match self.pregs[preg.index()].vreg() { + None => return Ok(preg), + Some(vreg) => { + if self.vreg_killed(vreg.vreg(), inst, block, block_last_inst, true) { + self.clear_preg(preg.index()); + return Ok(preg); + } + + // TODO: prefer regs that are already spilled? + let next_use = self.next_use(vreg.vreg()); + if let Some((use_pos, vreg)) = ffu_reg { + if use_pos < next_use { + ffu_reg = Some((next_use, vreg)); + } + } else { + ffu_reg = Some((next_use, vreg)); + } + } + } + } + + if ffu_reg.is_none() { + panic!("No available register found!"); + } + + let (_, vreg) = ffu_reg.unwrap(); + if self.vregs[vreg.vreg()].stack_slot().is_none() { + // TODO: do we need to specify the progpoint? + self.alloc_and_move_to_stack(vreg, ProgPoint::before(inst)); + } + + let preg = self.vregs[vreg.vreg()].preg().unwrap(); + self.clear_preg(preg.index()); + return Ok(preg); } // Moving @@ -1601,6 +1646,14 @@ impl<'a, F: Function> FastAlloc<'a, F> { return false; } + fn next_use(&self, vreg: usize) -> u32 { + let data = &self.vregs[vreg]; + if data.cur_use_idx as usize >= data.uses.len() { + panic!("next_use called on {} which does not have one", vreg); + } + return data.uses[data.cur_use_idx as usize]; + } + // Misc /// Make sure all reftype vregs currently in pregs have a stack slot