From 80f7fc8a6c50ac077b8871be9ceea9471707def4 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Fri, 24 Dec 2021 11:42:02 -0800 Subject: [PATCH] fuzzbug fix --- src/backend/final.rs | 7 +--- src/backend/locations.rs | 74 +++++++++++----------------------------- src/backend/serialize.rs | 1 + src/backend/use_count.rs | 9 +++-- 4 files changed, 28 insertions(+), 63 deletions(-) diff --git a/src/backend/final.rs b/src/backend/final.rs index 5c6b780..18bac1e 100644 --- a/src/backend/final.rs +++ b/src/backend/final.rs @@ -155,12 +155,7 @@ pub fn produce_func_wasm(f: &FunctionBody, body: &SerializedBody, locations: &Lo wasm.locals .extend(locations.new_locals.iter().map(|ty| ty_to_valty(*ty))); - let mut next_delete = 0; - for (index, operator) in body.operators.iter().enumerate() { - if next_delete < locations.delete.len() && locations.delete[next_delete] == index { - next_delete += 1; - continue; - } + for operator in &body.operators { wasm.translate(operator, locations); } diff --git a/src/backend/locations.rs b/src/backend/locations.rs index 18cbf23..632aa04 100644 --- a/src/backend/locations.rs +++ b/src/backend/locations.rs @@ -9,7 +9,6 @@ use super::{SerializedBody, SerializedOperator}; #[derive(Debug)] pub struct Locations { pub locations: FxHashMap<(Value, usize), LocalId>, - pub delete: Vec, pub new_locals: Vec, } @@ -42,7 +41,6 @@ impl Locations { pub fn compute(f: &FunctionBody, body: &SerializedBody) -> Locations { let mut locations = Locations { locations: FxHashMap::default(), - delete: vec![], new_locals: vec![], }; let mut allocator = Allocator { @@ -54,7 +52,7 @@ impl Locations { ends: vec![], }; - allocator.compute_spans_and_deleted_ops(&body.operators[..]); + allocator.compute_spans(&body.operators[..]); locations } @@ -73,6 +71,14 @@ impl<'a> Allocator<'a> { }, ); + log::trace!( + "handle_op: at location {} op {:?} reads {:?} writes {:?}", + location, + op, + reads, + writes + ); + for (value, index) in reads { let span = match self.spans.get_mut(&(value, index)) { Some(span) => span, @@ -81,64 +87,24 @@ impl<'a> Allocator<'a> { } }; span.end = location + 1; + log::trace!(" -> span for {}: {:?}", value, span); } for (value, index) in writes { - self.spans - .entry((value, index)) - .or_insert(ValueSpan { - value, - multi_value_index: index, - start: location, - end: location + 1, - }) - .end = location + 1; + let span = self.spans.entry((value, index)).or_insert(ValueSpan { + value, + multi_value_index: index, + start: location, + end: location + 1, + }); + span.end = location + 1; + log::trace!(" -> span for {}: {:?}", value, span); } } - fn compute_spans_and_deleted_ops(&mut self, operators: &[SerializedOperator]) { - // Delete runs of Set(A), Set(B), Get(B), Get(A): these are - // stack-neutral sequences. - let mut start = None; - let mut current_run = vec![]; + fn compute_spans(&mut self, operators: &[SerializedOperator]) { + // For each operator, get the reads and writes and construct spans. for (index, operator) in operators.iter().enumerate() { - match operator { - &SerializedOperator::Set(..) if start.is_none() => { - start = Some(index); - current_run.push(operator.clone()); - } - &SerializedOperator::Set(..) => { - current_run.push(operator.clone()); - } - &SerializedOperator::Get(v, i) - if start.is_some() - && current_run.last() == Some(&SerializedOperator::Set(v, i)) => - { - current_run.pop(); - if current_run.is_empty() { - for i in start.unwrap()..=index { - self.locations.delete.push(i); - } - start = None; - } - } - _ => { - current_run.clear(); - start = None; - } - } - } - - // For each non-deleted operator, get the reads and writes and construct spans. - let mut next_delete = 0; - for (index, operator) in operators.iter().enumerate() { - if next_delete < self.locations.delete.len() - && self.locations.delete[next_delete] == index - { - next_delete += 1; - continue; - } - self.handle_op(index, operator); } diff --git a/src/backend/serialize.rs b/src/backend/serialize.rs index f9ba11e..7f1994e 100644 --- a/src/backend/serialize.rs +++ b/src/backend/serialize.rs @@ -400,6 +400,7 @@ impl<'a> SerializedBodyContext<'a> { // Now push the args in reverse order. for &arg in operands.iter().rev() { + let arg = self.f.resolve_alias(arg); match &self.f.values[arg.index()] { &ValueDef::Operator(op, ..) => { if op_rematerialize(&op) { diff --git a/src/backend/use_count.rs b/src/backend/use_count.rs index 832b21f..ed7fe09 100644 --- a/src/backend/use_count.rs +++ b/src/backend/use_count.rs @@ -25,6 +25,7 @@ impl UseCountAnalysis { for &value in &f.blocks[block].insts { if value != Value::undef() { let value = f.resolve_alias(value); + counts.add(value); if workqueue_set.insert(value) { workqueue.push_back(value); } @@ -34,6 +35,7 @@ impl UseCountAnalysis { f.blocks[block].terminator.visit_uses(|value| { if value != Value::undef() { let value = f.resolve_alias(value); + counts.add(value); if workqueue_set.insert(value) { workqueue.push_back(value); } @@ -42,7 +44,6 @@ impl UseCountAnalysis { while let Some(value) = workqueue.pop_front() { workqueue_set.remove(&value); - counts.add(value); match &f.values[value.index()] { &ValueDef::Alias(..) | &ValueDef::Arg(..) | &ValueDef::BlockParam(..) => {} &ValueDef::Operator(_op, ref args) => { @@ -51,7 +52,8 @@ impl UseCountAnalysis { continue; } let arg = f.resolve_alias(arg); - if counts.use_count[arg.index()] == 0 { + counts.add(arg); + if counts.use_count[arg.index()] == 1 { if workqueue_set.insert(arg) { workqueue.push_back(arg); } @@ -63,7 +65,8 @@ impl UseCountAnalysis { continue; } let value = f.resolve_alias(value); - if counts.use_count[value.index()] == 0 { + counts.add(value); + if counts.use_count[value.index()] == 1 { if workqueue_set.insert(value) { workqueue.push_back(value); }