Fuzzbugfix: actually do need eager liveness computation; must uphold invariant that all earlier-in-postorder blocks have full livein sets.

This commit is contained in:
Chris Fallin
2021-05-06 23:29:59 -07:00
parent 2ff02b50a3
commit 2ba518517d
4 changed files with 26 additions and 17 deletions

View File

@@ -177,7 +177,7 @@ impl<'a> std::iter::Iterator for AdaptiveMapIter<'a> {
/// A conceptually infinite-length bitvector that allows bitwise operations and /// A conceptually infinite-length bitvector that allows bitwise operations and
/// iteration over set bits efficiently. /// iteration over set bits efficiently.
#[derive(Clone, Debug)] #[derive(Clone)]
pub struct BitVec { pub struct BitVec {
elems: AdaptiveMap, elems: AdaptiveMap,
} }
@@ -275,6 +275,13 @@ impl Iterator for SetBitsIter {
} }
} }
impl std::fmt::Debug for BitVec {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let vals = self.iter().collect::<Vec<_>>();
write!(f, "{:?}", vals)
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::BitVec; use super::BitVec;

View File

@@ -130,7 +130,7 @@ impl Function for Func {
&self.reftype_vregs[..] &self.reftype_vregs[..]
} }
fn is_move(&self, insn: Inst) -> Option<(VReg, VReg)> { fn is_move(&self, _: Inst) -> Option<(VReg, VReg)> {
None None
} }

View File

@@ -267,7 +267,6 @@ struct Env<'a, F: Function> {
env: &'a MachineEnv, env: &'a MachineEnv,
cfginfo: CFGInfo, cfginfo: CFGInfo,
liveins: Vec<BitVec>, liveins: Vec<BitVec>,
livein_parents: Vec<Vec<Block>>,
/// Blockparam outputs: from-vreg, (end of) from-block, (start of) /// Blockparam outputs: from-vreg, (end of) from-block, (start of)
/// to-block, to-vreg. The field order is significant: these are sorted so /// to-block, to-vreg. The field order is significant: these are sorted so
/// that a scan over vregs, then blocks in each range, can scan in /// that a scan over vregs, then blocks in each range, can scan in
@@ -664,7 +663,6 @@ impl<'a, F: Function> Env<'a, F> {
cfginfo, cfginfo,
liveins: vec![], liveins: vec![],
livein_parents: vec![],
blockparam_outs: vec![], blockparam_outs: vec![],
blockparam_ins: vec![], blockparam_ins: vec![],
blockparam_allocs: vec![], blockparam_allocs: vec![],
@@ -1016,23 +1014,13 @@ impl<'a, F: Function> Env<'a, F> {
} }
fn is_live_in(&mut self, block: Block, vreg: VRegIndex) -> bool { fn is_live_in(&mut self, block: Block, vreg: VRegIndex) -> bool {
if self.liveins[block.index()].get(vreg.index()) { self.liveins[block.index()].get(vreg.index())
return true;
}
for &parent in &self.livein_parents[block.index()] {
if self.liveins[parent.index()].get(vreg.index()) {
self.liveins[block.index()].set(vreg.index(), true);
return true;
}
}
false
} }
fn compute_liveness(&mut self) { fn compute_liveness(&mut self) {
// Create initial LiveIn bitsets. // Create initial LiveIn bitsets.
for _ in 0..self.func.blocks() { for _ in 0..self.func.blocks() {
self.liveins.push(BitVec::new()); self.liveins.push(BitVec::new());
self.livein_parents.push(vec![]);
} }
let mut num_ranges = 0; let mut num_ranges = 0;
@@ -1428,7 +1416,7 @@ impl<'a, F: Function> Env<'a, F> {
); );
log::debug!(" -> loop range {:?}", loop_range); log::debug!(" -> loop range {:?}", loop_range);
for &loopblock in loop_blocks { for &loopblock in loop_blocks {
self.livein_parents[loopblock.index()].push(block); self.liveins[loopblock.index()].or(&live);
} }
for vreg in live.iter() { for vreg in live.iter() {
log::debug!( log::debug!(

View File

@@ -779,11 +779,25 @@ pub enum InstPosition {
} }
/// A program point: a single point before or after a given instruction. /// A program point: a single point before or after a given instruction.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ProgPoint { pub struct ProgPoint {
bits: u32, bits: u32,
} }
impl std::fmt::Debug for ProgPoint {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"progpoint{}{}",
self.inst().index(),
match self.pos() {
InstPosition::Before => "-pre",
InstPosition::After => "-post",
}
)
}
}
impl ProgPoint { impl ProgPoint {
pub fn new(inst: Inst, pos: InstPosition) -> Self { pub fn new(inst: Inst, pos: InstPosition) -> Self {
let bits = ((inst.0 as u32) << 1) | (pos as u8 as u32); let bits = ((inst.0 as u32) << 1) | (pos as u8 as u32);