From a0da3e9f4fff6aae71f56ce3452b0e38f30de5c4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 17 Sep 2018 13:52:35 +1000 Subject: [PATCH] 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()`. --- src/librustc_data_structures/bit_set.rs | 35 +++++-------------- .../dataflow/impls/borrowed_locals.rs | 6 ++-- src/librustc_mir/dataflow/impls/borrows.rs | 10 +++--- src/librustc_mir/dataflow/impls/mod.rs | 26 +++++++------- .../dataflow/impls/storage_liveness.rs | 6 ++-- src/librustc_mir/dataflow/mod.rs | 10 +++--- 6 files changed, 37 insertions(+), 56 deletions(-) diff --git a/src/librustc_data_structures/bit_set.rs b/src/librustc_data_structures/bit_set.rs index 71cd4ba37ab..74f08205958 100644 --- a/src/librustc_data_structures/bit_set.rs +++ b/src/librustc_data_structures/bit_set.rs @@ -162,7 +162,7 @@ impl BitSet { /// Set `self = self & other` and return true if `self` changed. /// (i.e., if any bits were removed). pub fn intersect(&mut self, other: &BitSet) -> 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 { impl UnionIntoBitSet for BitSet { fn union_into(&self, other: &mut BitSet) -> bool { - bitwise(other.words_mut(), self.words(), &Union) + bitwise(other.words_mut(), self.words(), |a, b| { a | b }) } } impl SubtractFromBitSet for BitSet { fn subtract_from(&self, other: &mut BitSet) -> 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(&self, inout_set: &mut BitSet, in_set: &BitSet) -> bool; } #[inline] -pub fn bitwise(out_vec: &mut [Word], in_vec: &[Word], op: &Op) -> bool +fn bitwise(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 diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 266e8e2d949..8d186597b14 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -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(&self, inout_set: &mut BitSet, in_set: &BitSet) -> bool { + inout_set.union(in_set) // "maybe" means we union effects of both preds } } diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 541f4c7026c..22fb12152db 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -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(&self, inout_set: &mut BitSet, in_set: &BitSet) -> bool { + inout_set.union(in_set) // "maybe" means we union effects of both preds } } diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index 6088f85c3c8..984d1f686d9 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -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(&self, inout_set: &mut BitSet, in_set: &BitSet) -> 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(&self, inout_set: &mut BitSet, in_set: &BitSet) -> 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(&self, inout_set: &mut BitSet, in_set: &BitSet) -> 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(&self, inout_set: &mut BitSet, in_set: &BitSet) -> bool { + inout_set.union(in_set) // inits from both preds are in scope } } diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index e6229725fe8..ab03ace23d7 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -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(&self, inout_set: &mut BitSet, in_set: &BitSet) -> bool { + inout_set.union(in_set) // "maybe" means we union effects of both preds } } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index 42b3ac6c6d1..1e362e6f0dc 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -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, bb: mir::BasicBlock, dirty_queue: &mut WorkQueue) { - 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); }