diff --git a/src/checker.rs b/src/checker.rs index 146dbee..55f4860 100644 --- a/src/checker.rs +++ b/src/checker.rs @@ -78,7 +78,7 @@ use crate::{ Allocation, AllocationKind, Block, Edit, Function, Inst, InstPosition, Operand, - OperandConstraint, OperandKind, OperandPos, Output, PReg, ProgPoint, SpillSlot, VReg, + OperandConstraint, OperandKind, OperandPos, Output, PReg, ProgPoint, RegClass, VReg, }; use std::collections::{HashMap, HashSet, VecDeque}; @@ -143,11 +143,11 @@ pub enum CheckerError { }, ConflictedValueInStackmap { inst: Inst, - slot: SpillSlot, + alloc: Allocation, }, NonRefValueInStackmap { inst: Inst, - slot: SpillSlot, + alloc: Allocation, vreg: VReg, }, } @@ -332,9 +332,8 @@ impl CheckerState { self.check_val(inst, *op, *alloc, val, allocs)?; } } - &CheckerInst::Safepoint { inst, ref slots } => { - for &slot in slots { - let alloc = Allocation::stack(slot); + &CheckerInst::Safepoint { inst, ref allocs } => { + for &alloc in allocs { let val = self .allocations .get(&alloc) @@ -343,17 +342,17 @@ impl CheckerState { log::trace!( "checker: checkinst {:?}: safepoint slot {}, checker value {:?}", checkinst, - slot, + alloc, val ); match val { CheckerValue::Unknown => {} CheckerValue::Conflicted => { - return Err(CheckerError::ConflictedValueInStackmap { inst, slot }); + return Err(CheckerError::ConflictedValueInStackmap { inst, alloc }); } CheckerValue::Reg(vreg, false) => { - return Err(CheckerError::NonRefValueInStackmap { inst, slot, vreg }); + return Err(CheckerError::NonRefValueInStackmap { inst, alloc, vreg }); } CheckerValue::Reg(_, true) => {} } @@ -405,12 +404,10 @@ impl CheckerState { self.allocations .insert(alloc, CheckerValue::Reg(vreg, reftyped)); } - &CheckerInst::Safepoint { ref slots, .. } => { + &CheckerInst::Safepoint { ref allocs, .. } => { for (alloc, value) in &mut self.allocations { if let CheckerValue::Reg(_, true) = *value { - if alloc.is_reg() { - *value = CheckerValue::Conflicted; - } else if alloc.is_stack() && !slots.contains(&alloc.as_stack().unwrap()) { + if !allocs.contains(&alloc) { *value = CheckerValue::Conflicted; } } @@ -483,9 +480,9 @@ pub(crate) enum CheckerInst { /// of a value is logically transferred to a new vreg. DefAlloc { alloc: Allocation, vreg: VReg }, - /// A safepoint, with the given SpillSlots specified as containing + /// A safepoint, with the given Allocations specified as containing /// reftyped values. All other reftyped values become invalid. - Safepoint { inst: Inst, slots: Vec }, + Safepoint { inst: Inst, allocs: Vec }, } #[derive(Debug)] @@ -529,7 +526,7 @@ impl<'a, F: Function> Checker<'a, F> { pub fn prepare(&mut self, out: &Output) { log::trace!("checker: out = {:?}", out); // Preprocess safepoint stack-maps into per-inst vecs. - let mut safepoint_slots: HashMap> = HashMap::new(); + let mut safepoint_slots: HashMap> = HashMap::new(); for &(progpoint, slot) in &out.safepoint_slots { safepoint_slots .entry(progpoint.inst()) @@ -551,9 +548,9 @@ impl<'a, F: Function> Checker<'a, F> { // If this is a safepoint, then check the spillslots at this point. if self.f.requires_refs_on_stack(inst) { - let slots = safepoint_slots.remove(&inst).unwrap_or_else(|| vec![]); + let allocs = safepoint_slots.remove(&inst).unwrap_or_else(|| vec![]); - let checkinst = CheckerInst::Safepoint { inst, slots }; + let checkinst = CheckerInst::Safepoint { inst, allocs }; self.bb_insts.get_mut(&block).unwrap().push(checkinst); } @@ -727,9 +724,9 @@ impl<'a, F: Function> Checker<'a, F> { &CheckerInst::DefAlloc { alloc, vreg } => { log::trace!(" defalloc: {}:{}", vreg, alloc); } - &CheckerInst::Safepoint { ref slots, .. } => { + &CheckerInst::Safepoint { ref allocs, .. } => { let mut slotargs = vec![]; - for &slot in slots { + for &slot in allocs { slotargs.push(format!("{}", slot)); } log::trace!(" safepoint: {}", slotargs.join(", ")); diff --git a/src/ion/data_structures.rs b/src/ion/data_structures.rs index 2c8e616..635ac26 100644 --- a/src/ion/data_structures.rs +++ b/src/ion/data_structures.rs @@ -19,7 +19,7 @@ use crate::index::ContainerComparator; use crate::indexset::IndexSet; use crate::{ define_index, Allocation, Block, Edit, Function, Inst, MachineEnv, Operand, PReg, ProgPoint, - RegClass, SpillSlot, VReg, + RegClass, VReg, }; use smallvec::SmallVec; use std::cmp::Ordering; @@ -336,7 +336,7 @@ pub struct Env<'a, F: Function> { pub allocs: Vec, pub inst_alloc_offsets: Vec, pub num_spillslots: u32, - pub safepoint_slots: Vec<(ProgPoint, SpillSlot)>, + pub safepoint_slots: Vec<(ProgPoint, Allocation)>, pub allocated_bundle_count: usize, diff --git a/src/ion/stackmap.rs b/src/ion/stackmap.rs index c48475c..f9c534a 100644 --- a/src/ion/stackmap.rs +++ b/src/ion/stackmap.rs @@ -58,10 +58,8 @@ impl<'a, F: Function> Env<'a, F> { } log::trace!(" -> covers safepoint {:?}", safepoints[safepoint_idx]); - let slot = alloc - .as_stack() - .expect("Reference-typed value not in spillslot at safepoint"); - self.safepoint_slots.push((safepoints[safepoint_idx], slot)); + self.safepoint_slots + .push((safepoints[safepoint_idx], alloc)); safepoint_idx += 1; } } diff --git a/src/lib.rs b/src/lib.rs index 2c56d5a..d91bf97 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1180,8 +1180,11 @@ pub struct Output { /// Allocation offset in `allocs` for each instruction. pub inst_alloc_offsets: Vec, - /// Safepoint records: at a given program point, a reference-typed value lives in the given SpillSlot. - pub safepoint_slots: Vec<(ProgPoint, SpillSlot)>, + /// Safepoint records: at a given program point, a reference-typed value + /// lives in the given Allocation. Currently these are guaranteed to be + /// stack slots, but in the future an option may be added to allow + /// reftype value to be kept in registers at safepoints. + pub safepoint_slots: Vec<(ProgPoint, Allocation)>, /// Debug info: a labeled value (as applied to vregs by /// `Function::debug_value_labels()` on the input side) is located