about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <nnethercote@mozilla.com>2018-08-17 10:41:14 +1000
committerNicholas Nethercote <nnethercote@mozilla.com>2018-08-20 14:00:51 +1000
commit04b50e22bb978f10d90df78a377f23fd122a8d83 (patch)
treee6c7531c2c56c52d6d2e168158c8954778c51045
parent3ac79c718475fd29b8be34dde667b683390c2aee (diff)
Convert `AllSets::on_entry_sets` to a `Vec<IdxSetBuf<E>>`.
This makes it more like `AllSets::{gen,kill}_set`, removes the need for
a bunch of bitset range computations, and removes the need for `Bits`.

It's marginally less efficient, because we have to allocate one bitset
per basic block instead of one large shared bitset, but the difference
is negligible in practice.
-rw-r--r--src/librustc_mir/dataflow/mod.rs54
1 files changed, 14 insertions, 40 deletions
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 56c4dac19e5..0881b66e550 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::bitslice::{bitwise, BitwiseOperator, Word};
+use rustc_data_structures::bitslice::{bitwise, BitwiseOperator};
 use rustc_data_structures::indexed_set::{HybridIdxSetBuf, IdxSet, IdxSetBuf};
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::work_queue::WorkQueue;
@@ -23,7 +23,6 @@ use rustc::session::Session;
 use std::borrow::Borrow;
 use std::fmt;
 use std::io;
-use std::mem;
 use std::path::PathBuf;
 use std::usize;
 
@@ -287,18 +286,6 @@ impl<'a, 'tcx: 'a, BD> DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation
     }
 }
 
-/// Maps each block to a set of bits
-#[derive(Clone, Debug)]
-pub(crate) struct Bits<E:Idx> {
-    bits: IdxSetBuf<E>,
-}
-
-impl<E:Idx> Bits<E> {
-    fn new(bits: IdxSetBuf<E>) -> Self {
-        Bits { bits: bits }
-    }
-}
-
 /// DataflowResultsConsumer abstracts over walking the MIR with some
 /// already constructed dataflow results.
 ///
@@ -464,12 +451,8 @@ pub struct AllSets<E: Idx> {
     /// Analysis bitwidth for each block.
     bits_per_block: usize,
 
-    /// Number of words associated with each block entry
-    /// equal to bits_per_block / (mem::size_of::<Word> * 8), rounded up.
-    words_per_block: usize,
-
     /// For each block, bits valid on entry to the block.
-    on_entry_sets: Bits<E>,
+    on_entry_sets: Vec<IdxSetBuf<E>>,
 
     /// For each block, bits generated by executing the statements in
     /// the block. (For comparison, the Terminator for each block is
@@ -559,19 +542,15 @@ impl<'a, E:Idx> BlockSets<'a, E> {
 impl<E:Idx> AllSets<E> {
     pub fn bits_per_block(&self) -> usize { self.bits_per_block }
     pub fn for_block(&mut self, block_idx: usize) -> BlockSets<E> {
-        let offset = self.words_per_block * block_idx;
-        let range = E::new(offset)..E::new(offset + self.words_per_block);
         BlockSets {
-            on_entry: self.on_entry_sets.bits.range_mut(&range),
+            on_entry: &mut self.on_entry_sets[block_idx],
             gen_set: &mut self.gen_sets[block_idx],
             kill_set: &mut self.kill_sets[block_idx],
         }
     }
 
-    pub fn on_entry_set_for(&self, block_idx: usize) -> &IdxSet<E> {
-        let offset = self.words_per_block * block_idx;
-        let range = E::new(offset)..E::new(offset + self.words_per_block);
-        self.on_entry_sets.bits.range(&range)
+    pub fn on_entry_set_for(&self, block_idx: usize) -> &IdxSetBuf<E> {
+        &self.on_entry_sets[block_idx]
     }
     pub fn gen_set_for(&self, block_idx: usize) -> &HybridIdxSetBuf<E> {
         &self.gen_sets[block_idx]
@@ -731,18 +710,15 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
                dead_unwinds: &'a IdxSet<mir::BasicBlock>,
                denotation: D) -> Self where D: InitialFlow {
         let bits_per_block = denotation.bits_per_block();
-        let bits_per_word = mem::size_of::<Word>() * 8;
-        let words_per_block = (bits_per_block + bits_per_word - 1) / bits_per_word;
-        let bits_per_block_rounded_up = words_per_block * bits_per_word; // a multiple of word size
         let num_blocks = mir.basic_blocks().len();
-        let num_overall = num_blocks * bits_per_block_rounded_up;
 
-        let on_entry = Bits::new(if D::bottom_value() {
-            IdxSetBuf::new_filled(num_overall)
+        let on_entry_sets = if D::bottom_value() {
+            vec![IdxSetBuf::new_filled(bits_per_block); num_blocks]
         } else {
-            IdxSetBuf::new_empty(num_overall)
-        });
-        let empties = vec![HybridIdxSetBuf::new_empty(bits_per_block); num_blocks];
+            vec![IdxSetBuf::new_empty(bits_per_block); num_blocks]
+        };
+        let gen_sets = vec![HybridIdxSetBuf::new_empty(bits_per_block); num_blocks];
+        let kill_sets = gen_sets.clone();
 
         DataflowAnalysis {
             mir,
@@ -750,10 +726,9 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
             flow_state: DataflowState {
                 sets: AllSets {
                     bits_per_block,
-                    words_per_block,
-                    on_entry_sets: on_entry,
-                    gen_sets: empties.clone(),
-                    kill_sets: empties,
+                    on_entry_sets,
+                    gen_sets,
+                    kill_sets,
                 },
                 operator: denotation,
             }
@@ -873,5 +848,4 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
             dirty_queue.insert(bb);
         }
     }
-
 }