Eliminate BitwiseOperator.

`BitwiseOperator` is an unnecessarily low-level thing. This commit
replaces it with `BitSetOperator`, which works on `BitSet`s instead of
words. Within `bit_set.rs`, the commit eliminates `Intersect`, `Union`,
and `Subtract` by instead passing a function to `bitwise()`.
This commit is contained in:
Nicholas Nethercote 2018-09-17 13:52:35 +10:00
parent 266e2d3d69
commit a0da3e9f4f
6 changed files with 37 additions and 56 deletions

View File

@ -162,7 +162,7 @@ impl<T: Idx> BitSet<T> {
/// Set `self = self & other` and return true if `self` changed.
/// (i.e., if any bits were removed).
pub fn intersect(&mut self, other: &BitSet<T>) -> bool {
bitwise(self.words_mut(), other.words(), &Intersect)
bitwise(self.words_mut(), other.words(), |a, b| { a & b })
}
/// Get a slice of the underlying words.
@ -243,13 +243,13 @@ pub trait SubtractFromBitSet<T: Idx> {
impl<T: Idx> UnionIntoBitSet<T> for BitSet<T> {
fn union_into(&self, other: &mut BitSet<T>) -> bool {
bitwise(other.words_mut(), self.words(), &Union)
bitwise(other.words_mut(), self.words(), |a, b| { a | b })
}
}
impl<T: Idx> SubtractFromBitSet<T> for BitSet<T> {
fn subtract_from(&self, other: &mut BitSet<T>) -> bool {
bitwise(other.words_mut(), self.words(), &Subtract)
bitwise(other.words_mut(), self.words(), |a, b| { a & !b })
}
}
@ -302,43 +302,26 @@ impl<'a, T: Idx> Iterator for BitIter<'a, T> {
}
}
pub trait BitwiseOperator {
/// Applies some bit-operation pointwise to each of the bits in the two inputs.
fn join(&self, pred1: Word, pred2: Word) -> Word;
pub trait BitSetOperator {
/// Combine one bitset into another.
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool;
}
#[inline]
pub fn bitwise<Op: BitwiseOperator>(out_vec: &mut [Word], in_vec: &[Word], op: &Op) -> bool
fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
where Op: Fn(Word, Word) -> Word
{
assert_eq!(out_vec.len(), in_vec.len());
let mut changed = false;
for (out_elem, in_elem) in out_vec.iter_mut().zip(in_vec.iter()) {
let old_val = *out_elem;
let new_val = op.join(old_val, *in_elem);
let new_val = op(old_val, *in_elem);
*out_elem = new_val;
changed |= old_val != new_val;
}
changed
}
pub struct Intersect;
impl BitwiseOperator for Intersect {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & b }
}
pub struct Union;
impl BitwiseOperator for Union {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a | b }
}
pub struct Subtract;
impl BitwiseOperator for Subtract {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & !b }
}
const SPARSE_MAX: usize = 8;
/// A fixed-size bitset type with a sparse representation and a maximum of

View File

@ -80,10 +80,10 @@ impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> {
}
}
impl<'a, 'tcx> BitwiseOperator for HaveBeenBorrowedLocals<'a, 'tcx> {
impl<'a, 'tcx> BitSetOperator for HaveBeenBorrowedLocals<'a, 'tcx> {
#[inline]
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // "maybe" means we union effects of both preds
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
inout_set.union(in_set) // "maybe" means we union effects of both preds
}
}

View File

@ -20,9 +20,9 @@ use rustc::ty::TyCtxt;
use rustc::ty::{RegionKind, RegionVid};
use rustc::ty::RegionKind::ReScope;
use rustc_data_structures::bit_set::{BitSet, BitwiseOperator, Word};
use rustc_data_structures::bit_set::{BitSet, BitSetOperator};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::IndexVec;
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
use rustc_data_structures::sync::Lrc;
use dataflow::{BitDenotation, BlockSets, InitialFlow};
@ -410,10 +410,10 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
}
}
impl<'a, 'gcx, 'tcx> BitwiseOperator for Borrows<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> BitSetOperator for Borrows<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // union effects of preds when computing reservations
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
inout_set.union(in_set) // "maybe" means we union effects of both preds
}
}

View File

@ -14,7 +14,7 @@
use rustc::ty::TyCtxt;
use rustc::mir::{self, Mir, Location};
use rustc_data_structures::bit_set::{BitSet, BitwiseOperator, Word};
use rustc_data_structures::bit_set::{BitSet, BitSetOperator};
use rustc_data_structures::indexed_vec::Idx;
use super::MoveDataParamEnv;
@ -549,31 +549,31 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedPlaces<'a, 'gcx, 'tcx> {
}
}
impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> BitSetOperator for MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // "maybe" means we union effects of both preds
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
inout_set.union(in_set) // "maybe" means we union effects of both preds
}
}
impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> BitSetOperator for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // "maybe" means we union effects of both preds
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
inout_set.union(in_set) // "maybe" means we union effects of both preds
}
}
impl<'a, 'gcx, 'tcx> BitwiseOperator for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> BitSetOperator for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 & pred2 // "definitely" means we intersect effects of both preds
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
inout_set.intersect(in_set) // "definitely" means we intersect effects of both preds
}
}
impl<'a, 'gcx, 'tcx> BitwiseOperator for EverInitializedPlaces<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> BitSetOperator for EverInitializedPlaces<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // inits from both preds are in scope
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
inout_set.union(in_set) // inits from both preds are in scope
}
}

View File

@ -67,10 +67,10 @@ impl<'a, 'tcx> BitDenotation for MaybeStorageLive<'a, 'tcx> {
}
}
impl<'a, 'tcx> BitwiseOperator for MaybeStorageLive<'a, 'tcx> {
impl<'a, 'tcx> BitSetOperator for MaybeStorageLive<'a, 'tcx> {
#[inline]
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // "maybe" means we union effects of both preds
fn join<T: Idx>(&self, inout_set: &mut BitSet<T>, in_set: &BitSet<T>) -> bool {
inout_set.union(in_set) // "maybe" means we union effects of both preds
}
}

View File

@ -10,7 +10,7 @@
use syntax::ast::{self, MetaItem};
use rustc_data_structures::bit_set::{bitwise, BitwiseOperator, BitSet, HybridBitSet};
use rustc_data_structures::bit_set::{BitSet, BitSetOperator, HybridBitSet};
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::work_queue::WorkQueue;
@ -561,7 +561,7 @@ pub trait InitialFlow {
fn bottom_value() -> bool;
}
pub trait BitDenotation: BitwiseOperator {
pub trait BitDenotation: BitSetOperator {
/// Specifies what index type is used to access the bitvector.
type Idx: Idx;
@ -830,10 +830,8 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
in_out: &BitSet<D::Idx>,
bb: mir::BasicBlock,
dirty_queue: &mut WorkQueue<mir::BasicBlock>) {
let entry_set = self.flow_state.sets.for_block(bb.index()).on_entry;
let set_changed = bitwise(entry_set.words_mut(),
in_out.words(),
&self.flow_state.operator);
let entry_set = &mut self.flow_state.sets.for_block(bb.index()).on_entry;
let set_changed = self.flow_state.operator.join(entry_set, &in_out);
if set_changed {
dirty_queue.insert(bb);
}