Skip to content

Commit

Permalink
Introduce UnionIntoIdxSet and SubtractFromIdxSet traits.
Browse files Browse the repository at this point in the history
They let `union()`, `union_sparse()` and `union_hybrid()` be merged.
Likewise for subtract()`, `subtract_sparse()` and `subtract_hybrid()`.
  • Loading branch information
nnethercote committed Aug 24, 2018
1 parent 180052d commit 626b298
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 48 deletions.
106 changes: 68 additions & 38 deletions src/librustc_data_structures/indexed_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Idx> {
// Performs `other = other | self`.
fn union_into(&self, other: &mut IdxSet<T>) -> bool;
}

/// This is implemented by all the index sets so that IdxSet::subtract() can be
/// passed any type of index set.
pub trait SubtractFromIdxSet<T: Idx> {
// Performs `other = other - self`.
fn subtract_from(&self, other: &mut IdxSet<T>) -> bool;
}

/// Represents a set of some element type E, where each E is identified by some
/// unique index type `T`.
///
Expand Down Expand Up @@ -164,48 +178,14 @@ impl<T: Idx> IdxSet<T> {

/// Set `self = self | other` and return true if `self` changed
/// (i.e., if new bits were added).
pub fn union(&mut self, other: &IdxSet<T>) -> bool {
bitwise(self.words_mut(), other.words(), &Union)
}

/// Like `union()`, but takes a `SparseIdxSet` argument.
fn union_sparse(&mut self, other: &SparseIdxSet<T>) -> 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<T>) -> bool {
match other {
HybridIdxSet::Sparse(sparse, _) => self.union_sparse(sparse),
HybridIdxSet::Dense(dense, _) => self.union(dense),
}
pub fn union(&mut self, other: &impl UnionIntoIdxSet<T>) -> 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<T>) -> bool {
bitwise(self.words_mut(), other.words(), &Subtract)
}

/// Like `subtract()`, but takes a `SparseIdxSet` argument.
fn subtract_sparse(&mut self, other: &SparseIdxSet<T>) -> 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<T>) -> bool {
match other {
HybridIdxSet::Sparse(sparse, _) => self.subtract_sparse(sparse),
HybridIdxSet::Dense(dense, _) => self.subtract(dense),
}
pub fn subtract(&mut self, other: &impl SubtractFromIdxSet<T>) -> bool {
other.subtract_from(self)
}

/// Set `self = self & other` and return true if `self` changed.
Expand All @@ -223,6 +203,18 @@ impl<T: Idx> IdxSet<T> {
}
}

impl<T: Idx> UnionIntoIdxSet<T> for IdxSet<T> {
fn union_into(&self, other: &mut IdxSet<T>) -> bool {
bitwise(other.words_mut(), self.words(), &Union)
}
}

impl<T: Idx> SubtractFromIdxSet<T> for IdxSet<T> {
fn subtract_from(&self, other: &mut IdxSet<T>) -> bool {
bitwise(other.words_mut(), self.words(), &Subtract)
}
}

pub struct Iter<'a, T: Idx> {
cur: Option<(Word, usize)>,
iter: iter::Enumerate<slice::Iter<'a, Word>>,
Expand Down Expand Up @@ -308,6 +300,26 @@ impl<T: Idx> SparseIdxSet<T> {
}
}

impl<T: Idx> UnionIntoIdxSet<T> for SparseIdxSet<T> {
fn union_into(&self, other: &mut IdxSet<T>) -> bool {
let mut changed = false;
for elem in self.iter() {
changed |= other.add(&elem);
}
changed
}
}

impl<T: Idx> SubtractFromIdxSet<T> for SparseIdxSet<T> {
fn subtract_from(&self, other: &mut IdxSet<T>) -> 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>,
}
Expand Down Expand Up @@ -411,6 +423,24 @@ impl<T: Idx> HybridIdxSet<T> {
}
}

impl<T: Idx> UnionIntoIdxSet<T> for HybridIdxSet<T> {
fn union_into(&self, other: &mut IdxSet<T>) -> bool {
match self {
HybridIdxSet::Sparse(sparse, _) => sparse.union_into(other),
HybridIdxSet::Dense(dense, _) => dense.union_into(other),
}
}
}

impl<T: Idx> SubtractFromIdxSet<T> for HybridIdxSet<T> {
fn subtract_from(&self, other: &mut IdxSet<T>) -> 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>),
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_mir/dataflow/at_location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ where
F: FnOnce(Iter<BD::Idx>),
{
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());
}
}
Expand Down Expand Up @@ -193,8 +193,8 @@ impl<BD> FlowsAtLocation for FlowAtLocation<BD>
}

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);
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/librustc_mir/dataflow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/transform/rustc_peek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down

0 comments on commit 626b298

Please sign in to comment.