Skip to content

Commit

Permalink
Merge pull request #16 from Amanieu/misc
Browse files Browse the repository at this point in the history
Various fixes & minor improvements
  • Loading branch information
cfallin authored Nov 16, 2021
2 parents 4461269 + a516e6d commit 9774e97
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 46 deletions.
37 changes: 17 additions & 20 deletions src/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -143,11 +143,11 @@ pub enum CheckerError {
},
ConflictedValueInStackmap {
inst: Inst,
slot: SpillSlot,
alloc: Allocation,
},
NonRefValueInStackmap {
inst: Inst,
slot: SpillSlot,
alloc: Allocation,
vreg: VReg,
},
}
Expand Down Expand Up @@ -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)
Expand All @@ -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) => {}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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())
Expand All @@ -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);
}

Expand Down Expand Up @@ -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(", "));
Expand Down
1 change: 0 additions & 1 deletion src/fuzzing/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,6 @@ pub fn machine_env() -> MachineEnv {
[regs.iter().cloned().skip(24).collect(), vec![]];
let scratch_by_class: [PReg; 2] = [PReg::new(31, RegClass::Int), PReg::new(0, RegClass::Float)];
MachineEnv {
regs,
preferred_regs_by_class,
non_preferred_regs_by_class,
scratch_by_class,
Expand Down
5 changes: 2 additions & 3 deletions src/ion/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -293,7 +293,6 @@ pub struct Env<'a, F: Function> {
pub vreg_regs: Vec<VReg>,
pub pregs: Vec<PRegData>,
pub allocation_queue: PrioQueue,
pub clobbers: Vec<Inst>, // Sorted list of insts with clobbers.
pub safepoints: Vec<Inst>, // Sorted list of safepoint insts.
pub safepoints_per_vreg: HashMap<usize, HashSet<Inst>>,

Expand Down Expand Up @@ -337,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,

Expand Down
12 changes: 5 additions & 7 deletions src/ion/liveranges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,11 @@ impl<'a, F: Function> Env<'a, F> {
allocations: LiveRangeSet::new(),
},
);
for &preg in &self.env.regs {
self.pregs[preg.index()].reg = preg;
for i in 0..=PReg::MAX {
let preg_int = PReg::new(i, RegClass::Int);
self.pregs[preg_int.index()].reg = preg_int;
let preg_float = PReg::new(i, RegClass::Float);
self.pregs[preg_float.index()].reg = preg_float;
}
// Create VRegs from the vreg count.
for idx in 0..self.func.num_vregs() {
Expand Down Expand Up @@ -445,10 +448,6 @@ impl<'a, F: Function> Env<'a, F> {
// For each instruction, in reverse order, process
// operands and clobbers.
for inst in insns.rev().iter() {
if self.func.inst_clobbers(inst).len() > 0 {
self.clobbers.push(inst);
}

// Mark clobbers with CodeRanges on PRegs.
for i in 0..self.func.inst_clobbers(inst).len() {
// don't borrow `self`
Expand Down Expand Up @@ -1231,7 +1230,6 @@ impl<'a, F: Function> Env<'a, F> {
}
}

self.clobbers.sort_unstable();
self.blockparam_ins.sort_unstable();
self.blockparam_outs.sort_unstable();
self.prog_move_srcs.sort_unstable_by_key(|(pos, _)| *pos);
Expand Down
1 change: 0 additions & 1 deletion src/ion/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ impl<'a, F: Function> Env<'a, F> {
vreg_regs: Vec::with_capacity(n),
pregs: vec![],
allocation_queue: PrioQueue::new(),
clobbers: vec![],
safepoints: vec![],
safepoints_per_vreg: HashMap::new(),
spilled_bundles: vec![],
Expand Down
6 changes: 2 additions & 4 deletions src/ion/stackmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
17 changes: 7 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,13 @@ impl PReg {
/// all PRegs and index it efficiently.
#[inline(always)]
pub fn index(self) -> usize {
((self.class as u8 as usize) << 5) | (self.hw_enc as usize)
((self.class as u8 as usize) << Self::MAX_BITS) | (self.hw_enc as usize)
}

/// Construct a PReg from the value returned from `.index()`.
#[inline(always)]
pub fn from_index(index: usize) -> Self {
let class = (index >> 5) & 1;
let class = (index >> Self::MAX_BITS) & 1;
let class = match class {
0 => RegClass::Int,
1 => RegClass::Float,
Expand Down Expand Up @@ -1139,12 +1139,6 @@ pub enum Edit {
/// as well.
#[derive(Clone, Debug)]
pub struct MachineEnv {
/// Physical registers. Every register that might be mentioned in
/// any constraint must be listed here, even if it is not
/// allocatable (present in one of
/// `{preferred,non_preferred}_regs_by_class`).
pub regs: Vec<PReg>,

/// Preferred physical registers for each class. These are the
/// registers that will be allocated first, if free.
pub preferred_regs_by_class: [Vec<PReg>; 2],
Expand Down Expand Up @@ -1186,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
Expand Down

0 comments on commit 9774e97

Please sign in to comment.