about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs4
-rw-r--r--src/librustc/middle/borrowck/move_data.rs8
-rw-r--r--src/librustc/middle/dataflow.rs84
3 files changed, 44 insertions, 52 deletions
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index cfec67bf3a3..285c5203af2 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -172,7 +172,7 @@ impl<'a> CheckLoanCtxt<'a> {
         //! are issued for future scopes and thus they may have been
         //! *issued* but not yet be in effect.
 
-        self.dfcx_loans.each_bit_on_entry_frozen(scope_id, |loan_index| {
+        self.dfcx_loans.each_bit_on_entry(scope_id, |loan_index| {
             let loan = &self.all_loans[loan_index];
             op(loan)
         })
@@ -271,7 +271,7 @@ impl<'a> CheckLoanCtxt<'a> {
         //! we encounter `scope_id`.
 
         let mut result = Vec::new();
-        self.dfcx_loans.each_gen_bit_frozen(scope_id, |loan_index| {
+        self.dfcx_loans.each_gen_bit(scope_id, |loan_index| {
             result.push(loan_index);
             true
         });
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index a9c312fc0a4..6ec3f82ad68 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -576,7 +576,7 @@ impl<'a> FlowedMoveData<'a> {
          * Iterates through each path moved by `id`
          */
 
-        self.dfcx_moves.each_gen_bit_frozen(id, |index| {
+        self.dfcx_moves.each_gen_bit(id, |index| {
             let move = self.move_data.moves.borrow();
             let move = move.get(index);
             let moved_path = move.path;
@@ -592,7 +592,7 @@ impl<'a> FlowedMoveData<'a> {
 
         let mut ret = None;
         for loan_path_index in self.move_data.path_map.borrow().find(&*loan_path).iter() {
-            self.dfcx_moves.each_gen_bit_frozen(id, |move_index| {
+            self.dfcx_moves.each_gen_bit(id, |move_index| {
                 let move = self.move_data.moves.borrow();
                 let move = move.get(move_index);
                 if move.path == **loan_path_index {
@@ -637,7 +637,7 @@ impl<'a> FlowedMoveData<'a> {
 
         let mut ret = true;
 
-        self.dfcx_moves.each_bit_on_entry_frozen(id, |index| {
+        self.dfcx_moves.each_bit_on_entry(id, |index| {
             let move = self.move_data.moves.borrow();
             let move = move.get(index);
             let moved_path = move.path;
@@ -693,7 +693,7 @@ impl<'a> FlowedMoveData<'a> {
             }
         };
 
-        self.dfcx_assign.each_bit_on_entry_frozen(id, |index| {
+        self.dfcx_assign.each_bit_on_entry(id, |index| {
             let assignment = self.move_data.var_assignments.borrow();
             let assignment = assignment.get(index);
             if assignment.path == loan_path_index && !f(assignment) {
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index fb3299013ef..7c5b001354d 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -97,15 +97,6 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
         assert!(n != ast::DUMMY_NODE_ID);
         self.nodeid_to_index.contains_key(&n)
     }
-    fn has_bitset_for_cfgidx(&self, _cfgidx: CFGIndex) -> bool {
-        true
-    }
-    fn get_bitset_index(&self, cfgidx: CFGIndex) -> uint {
-        cfgidx.node_id()
-    }
-    fn get_or_create_bitset_index(&mut self, cfgidx: CFGIndex) -> uint {
-        cfgidx.node_id()
-    }
 }
 
 impl<'a, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, O> {
@@ -120,8 +111,9 @@ impl<'a, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, O> {
         };
 
         if self.has_bitset_for_nodeid(id) {
+            assert!(self.bits_per_id > 0);
             let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
-            let (start, end) = self.compute_id_range_frozen(cfgidx);
+            let (start, end) = self.compute_id_range(cfgidx);
             let on_entry = self.on_entry.slice(start, end);
             let entry_str = bits_to_string(on_entry);
 
@@ -232,6 +224,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
         debug!("{:s} add_gen(id={:?}, bit={:?})",
                self.analysis_name, id, bit);
         assert!(self.nodeid_to_index.contains_key(&id));
+        assert!(self.bits_per_id > 0);
+
         let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
         let (start, end) = self.compute_id_range(cfgidx);
         let gens = self.gens.mut_slice(start, end);
@@ -243,32 +237,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
         debug!("{:s} add_kill(id={:?}, bit={:?})",
                self.analysis_name, id, bit);
         assert!(self.nodeid_to_index.contains_key(&id));
+        assert!(self.bits_per_id > 0);
+
         let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
         let (start, end) = self.compute_id_range(cfgidx);
         let kills = self.kills.mut_slice(start, end);
         set_bit(kills, bit);
     }
 
-    fn apply_gen_kill(&mut self, cfgidx: CFGIndex, bits: &mut [uint]) {
+    fn apply_gen_kill(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
         //! Applies the gen and kill sets for `cfgidx` to `bits`
         debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
                self.analysis_name, cfgidx, mut_bits_to_string(bits));
-        let (start, end) = self.compute_id_range(cfgidx);
-        let gens = self.gens.slice(start, end);
-        bitwise(bits, gens, &Union);
-        let kills = self.kills.slice(start, end);
-        bitwise(bits, kills, &Subtract);
-
-        debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [after]",
-               self.analysis_name, cfgidx, mut_bits_to_string(bits));
-    }
+        assert!(self.bits_per_id > 0);
 
-    fn apply_gen_kill_frozen(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
-        //! Applies the gen and kill sets for `cfgidx` to `bits`
-        //! Only useful after `propagate()` has been called.
-        debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
-               self.analysis_name, cfgidx, mut_bits_to_string(bits));
-        let (start, end) = self.compute_id_range_frozen(cfgidx);
+        let (start, end) = self.compute_id_range(cfgidx);
         let gens = self.gens.slice(start, end);
         bitwise(bits, gens, &Union);
         let kills = self.kills.slice(start, end);
@@ -278,15 +261,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
                self.analysis_name, cfgidx, mut_bits_to_string(bits));
     }
 
-    fn compute_id_range_frozen(&self, cfgidx: CFGIndex) -> (uint, uint) {
-        let n = self.get_bitset_index(cfgidx);
-        let start = n * self.words_per_id;
-        let end = start + self.words_per_id;
-        (start, end)
-    }
-
-    fn compute_id_range(&mut self, cfgidx: CFGIndex) -> (uint, uint) {
-        let n = self.get_or_create_bitset_index(cfgidx);
+    fn compute_id_range(&self, cfgidx: CFGIndex) -> (uint, uint) {
+        let n = cfgidx.node_id();
         let start = n * self.words_per_id;
         let end = start + self.words_per_id;
 
@@ -299,10 +275,10 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
     }
 
 
-    pub fn each_bit_on_entry_frozen(&self,
-                                    id: ast::NodeId,
-                                    f: |uint| -> bool)
-                                    -> bool {
+    pub fn each_bit_on_entry(&self,
+                             id: ast::NodeId,
+                             f: |uint| -> bool)
+                             -> bool {
         //! Iterates through each bit that is set on entry to `id`.
         //! Only useful after `propagate()` has been called.
         if !self.has_bitset_for_nodeid(id) {
@@ -319,17 +295,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
                              -> bool {
         //! Iterates through each bit that is set on entry/exit to `cfgidx`.
         //! Only useful after `propagate()` has been called.
-        if !self.has_bitset_for_cfgidx(cfgidx) {
+
+        if self.bits_per_id == 0 {
+            // Skip the surprisingly common degenerate case.  (Note
+            // compute_id_range requires self.words_per_id > 0.)
             return true;
         }
-        let (start, end) = self.compute_id_range_frozen(cfgidx);
+
+        let (start, end) = self.compute_id_range(cfgidx);
         let on_entry = self.on_entry.slice(start, end);
         let temp_bits;
         let slice = match e {
             Entry => on_entry,
             Exit => {
                 let mut t = on_entry.to_vec();
-                self.apply_gen_kill_frozen(cfgidx, t.as_mut_slice());
+                self.apply_gen_kill(cfgidx, t.as_mut_slice());
                 temp_bits = t;
                 temp_bits.as_slice()
             }
@@ -339,15 +319,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
         self.each_bit(slice, f)
     }
 
-    pub fn each_gen_bit_frozen(&self, id: ast::NodeId, f: |uint| -> bool)
-                               -> bool {
+    pub fn each_gen_bit(&self, id: ast::NodeId, f: |uint| -> bool)
+                        -> bool {
         //! Iterates through each bit in the gen set for `id`.
-        //! Only useful after `propagate()` has been called.
         if !self.has_bitset_for_nodeid(id) {
             return true;
         }
+
+        if self.bits_per_id == 0 {
+            // Skip the surprisingly common degenerate case.  (Note
+            // compute_id_range requires self.words_per_id > 0.)
+            return true;
+        }
+
         let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
-        let (start, end) = self.compute_id_range_frozen(cfgidx);
+        let (start, end) = self.compute_id_range(cfgidx);
         let gens = self.gens.slice(start, end);
         debug!("{:s} each_gen_bit(id={:?}, gens={})",
                self.analysis_name, id, bits_to_string(gens));
@@ -356,6 +342,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
 
     fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool {
         //! Helper for iterating over the bits in a bit set.
+        //! Returns false on the first call to `f` that returns false;
+        //! if all calls to `f` return true, then returns true.
 
         for (word_index, &word) in words.iter().enumerate() {
             if word != 0 {
@@ -486,6 +474,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
                 in_out: &mut [uint]) {
         debug!("DataFlowContext::walk_cfg(in_out={}) {:s}",
                bits_to_string(in_out), self.dfcx.analysis_name);
+        assert!(self.dfcx.bits_per_id > 0);
+
         cfg.graph.each_node(|node_index, node| {
             debug!("DataFlowContext::walk_cfg idx={} id={} begin in_out={}",
                    node_index, node.data.id, bits_to_string(in_out));
@@ -529,6 +519,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
         let cfgidx = edge.target();
         debug!("{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})",
                self.dfcx.analysis_name, bits_to_string(pred_bits), source, cfgidx);
+        assert!(self.dfcx.bits_per_id > 0);
+
         let (start, end) = self.dfcx.compute_id_range(cfgidx);
         let changed = {
             // (scoping mutable borrow of self.dfcx.on_entry)