Return safepoint_slots as Allocations instead of SpillSlots
This enables us to support reftype vregs in register locations in the future.
This commit is contained in:
@@ -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<SpillSlot> },
|
||||
Safepoint { inst: Inst, allocs: Vec<Allocation> },
|
||||
}
|
||||
|
||||
#[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<Inst, Vec<SpillSlot>> = HashMap::new();
|
||||
let mut safepoint_slots: HashMap<Inst, Vec<Allocation>> = 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(", "));
|
||||
|
||||
@@ -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<Allocation>,
|
||||
pub inst_alloc_offsets: Vec<u32>,
|
||||
pub num_spillslots: u32,
|
||||
pub safepoint_slots: Vec<(ProgPoint, SpillSlot)>,
|
||||
pub safepoint_slots: Vec<(ProgPoint, Allocation)>,
|
||||
|
||||
pub allocated_bundle_count: usize,
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,8 +1180,11 @@ pub struct Output {
|
||||
/// Allocation offset in `allocs` for each instruction.
|
||||
pub inst_alloc_offsets: Vec<u32>,
|
||||
|
||||
/// 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
|
||||
|
||||
Reference in New Issue
Block a user