diff --git a/src/librustc_data_structures/indexed_set.rs b/src/librustc_data_structures/indexed_set.rs index d4da1bb3601df..65fdf10a86d13 100644 --- a/src/librustc_data_structures/indexed_set.rs +++ b/src/librustc_data_structures/indexed_set.rs @@ -19,6 +19,20 @@ use bitslice::{bitwise, Union, Subtract, Intersect}; use indexed_vec::Idx; use rustc_serialize; +/// This is implemented by all the index sets so that IdxSet::union() can be +/// passed any type of index set. +pub trait UnionIntoIdxSet { + // Performs `other = other | self`. + fn union_into(&self, other: &mut IdxSet) -> bool; +} + +/// This is implemented by all the index sets so that IdxSet::subtract() can be +/// passed any type of index set. +pub trait SubtractFromIdxSet { + // Performs `other = other - self`. + fn subtract_from(&self, other: &mut IdxSet) -> bool; +} + /// Represents a set of some element type E, where each E is identified by some /// unique index type `T`. /// @@ -164,48 +178,14 @@ impl IdxSet { /// Set `self = self | other` and return true if `self` changed /// (i.e., if new bits were added). - pub fn union(&mut self, other: &IdxSet) -> bool { - bitwise(self.words_mut(), other.words(), &Union) - } - - /// Like `union()`, but takes a `SparseIdxSet` argument. - fn union_sparse(&mut self, other: &SparseIdxSet) -> bool { - let mut changed = false; - for elem in other.iter() { - changed |= self.add(&elem); - } - changed - } - - /// Like `union()`, but takes a `HybridIdxSet` argument. - pub fn union_hybrid(&mut self, other: &HybridIdxSet) -> bool { - match other { - HybridIdxSet::Sparse(sparse, _) => self.union_sparse(sparse), - HybridIdxSet::Dense(dense, _) => self.union(dense), - } + pub fn union(&mut self, other: &impl UnionIntoIdxSet) -> bool { + other.union_into(self) } /// Set `self = self - other` and return true if `self` changed. /// (i.e., if any bits were removed). - pub fn subtract(&mut self, other: &IdxSet) -> bool { - bitwise(self.words_mut(), other.words(), &Subtract) - } - - /// Like `subtract()`, but takes a `SparseIdxSet` argument. - fn subtract_sparse(&mut self, other: &SparseIdxSet) -> bool { - let mut changed = false; - for elem in other.iter() { - changed |= self.remove(&elem); - } - changed - } - - /// Like `subtract()`, but takes a `HybridIdxSet` argument. - pub fn subtract_hybrid(&mut self, other: &HybridIdxSet) -> bool { - match other { - HybridIdxSet::Sparse(sparse, _) => self.subtract_sparse(sparse), - HybridIdxSet::Dense(dense, _) => self.subtract(dense), - } + pub fn subtract(&mut self, other: &impl SubtractFromIdxSet) -> bool { + other.subtract_from(self) } /// Set `self = self & other` and return true if `self` changed. @@ -223,6 +203,18 @@ impl IdxSet { } } +impl UnionIntoIdxSet for IdxSet { + fn union_into(&self, other: &mut IdxSet) -> bool { + bitwise(other.words_mut(), self.words(), &Union) + } +} + +impl SubtractFromIdxSet for IdxSet { + fn subtract_from(&self, other: &mut IdxSet) -> bool { + bitwise(other.words_mut(), self.words(), &Subtract) + } +} + pub struct Iter<'a, T: Idx> { cur: Option<(Word, usize)>, iter: iter::Enumerate>, @@ -308,6 +300,26 @@ impl SparseIdxSet { } } +impl UnionIntoIdxSet for SparseIdxSet { + fn union_into(&self, other: &mut IdxSet) -> bool { + let mut changed = false; + for elem in self.iter() { + changed |= other.add(&elem); + } + changed + } +} + +impl SubtractFromIdxSet for SparseIdxSet { + fn subtract_from(&self, other: &mut IdxSet) -> bool { + let mut changed = false; + for elem in self.iter() { + changed |= other.remove(&elem); + } + changed + } +} + pub struct SparseIter<'a, T: Idx> { iter: slice::Iter<'a, T>, } @@ -411,6 +423,24 @@ impl HybridIdxSet { } } +impl UnionIntoIdxSet for HybridIdxSet { + fn union_into(&self, other: &mut IdxSet) -> bool { + match self { + HybridIdxSet::Sparse(sparse, _) => sparse.union_into(other), + HybridIdxSet::Dense(dense, _) => dense.union_into(other), + } + } +} + +impl SubtractFromIdxSet for HybridIdxSet { + fn subtract_from(&self, other: &mut IdxSet) -> bool { + match self { + HybridIdxSet::Sparse(sparse, _) => sparse.subtract_from(other), + HybridIdxSet::Dense(dense, _) => dense.subtract_from(other), + } + } +} + pub enum HybridIter<'a, T: Idx> { Sparse(SparseIter<'a, T>), Dense(Iter<'a, T>), diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index 0dfc5b5b4b7e0..1f7faa21a12c0 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -129,8 +129,8 @@ where F: FnOnce(Iter), { let mut curr_state = self.curr_state.clone(); - curr_state.union_hybrid(&self.stmt_gen); - curr_state.subtract_hybrid(&self.stmt_kill); + curr_state.union(&self.stmt_gen); + curr_state.subtract(&self.stmt_kill); f(curr_state.iter()); } } @@ -193,8 +193,8 @@ impl FlowsAtLocation for FlowAtLocation } fn apply_local_effect(&mut self, _loc: Location) { - self.curr_state.union_hybrid(&self.stmt_gen); - self.curr_state.subtract_hybrid(&self.stmt_kill); + self.curr_state.union(&self.stmt_gen); + self.curr_state.subtract(&self.stmt_kill); } } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 598e827b2564e..48d349978686d 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -241,8 +241,8 @@ impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> where BD: Bi let sets = self.builder.flow_state.sets.for_block(bb.index()); debug_assert!(in_out.words().len() == sets.on_entry.words().len()); in_out.overwrite(sets.on_entry); - in_out.union_hybrid(sets.gen_set); - in_out.subtract_hybrid(sets.kill_set); + in_out.union(sets.gen_set); + in_out.subtract(sets.kill_set); } self.builder.propagate_bits_into_graph_successors_of( in_out, (bb, bb_data), &mut dirty_queue); @@ -534,8 +534,8 @@ impl<'a, E:Idx> BlockSets<'a, E> { } fn apply_local_effect(&mut self) { - self.on_entry.union_hybrid(&self.gen_set); - self.on_entry.subtract_hybrid(&self.kill_set); + self.on_entry.union(self.gen_set); + self.on_entry.subtract(self.kill_set); } } diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index 63675f056ab78..eda7de0fd79d4 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -209,8 +209,8 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, &mut sets, Location { block: bb, statement_index: j }); results.0.operator.statement_effect( &mut sets, Location { block: bb, statement_index: j }); - sets.on_entry.union_hybrid(sets.gen_set); - sets.on_entry.subtract_hybrid(sets.kill_set); + sets.on_entry.union(sets.gen_set); + sets.on_entry.subtract(sets.kill_set); } results.0.operator.before_terminator_effect(