about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicholas Nethercote <nnethercote@mozilla.com>2018-06-28 16:20:32 +1000
committerNicholas Nethercote <nnethercote@mozilla.com>2018-06-29 09:57:19 +1000
commit08683f003cab472efc0481c349cb69dfb137c4c1 (patch)
tree097f92369e0b42064adef34924d2485e59a022aa /src
parent99a9d6806d355b69fa66621df5208342de823aea (diff)
downloadrust-08683f003cab472efc0481c349cb69dfb137c4c1.tar.gz
rust-08683f003cab472efc0481c349cb69dfb137c4c1.zip
Rename `IdxSet::clone_from`.
The current situation is something of a mess.

- `IdxSetBuf` derefs to `IdxSet`.
- `IdxSetBuf` implements `Clone`, and therefore has a provided `clone_from`
  method, which does allocation and so is expensive.
- `IdxSet` has a `clone_from` method that is non-allocating and therefore
  cheap, but this method is not from the `Clone` trait.

As a result, if you have an `IdxSetBuf` called `b`, if you call
`b.clone_from(b2)` you'll get the expensive `IdxSetBuf` method, but if you call
`(*b).clone_from(b2)` you'll get the cheap `IdxSetBuf` method.
`liveness_of_locals()` does the former, presumably unintentionally, and
therefore does lots of unnecessary allocations.

Having a `clone_from` method that isn't from the `Clone` trait is a bad idea in
general, so this patch renames it as `overwrite`. This avoids the unnecessary
allocations in `liveness_of_locals()`, speeding up most NLL benchmarks, the
best by 1.5%. It also means that calls of the form `(*b).clone_from(b2)` can be
rewritten as `b.overwrite(b2)`.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_data_structures/indexed_set.rs4
-rw-r--r--src/librustc_mir/dataflow/at_location.rs2
-rw-r--r--src/librustc_mir/dataflow/mod.rs2
-rw-r--r--src/librustc_mir/util/liveness.rs4
4 files changed, 7 insertions, 5 deletions
diff --git a/src/librustc_data_structures/indexed_set.rs b/src/librustc_data_structures/indexed_set.rs
index c9495587c46..30b87c0390a 100644
--- a/src/librustc_data_structures/indexed_set.rs
+++ b/src/librustc_data_structures/indexed_set.rs
@@ -233,7 +233,9 @@ impl<T: Idx> IdxSet<T> {
         &mut self.bits
     }
 
-    pub fn clone_from(&mut self, other: &IdxSet<T>) {
+    /// Efficiently overwrite `self` with `other`. Panics if `self` and `other`
+    /// don't have the same length.
+    pub fn overwrite(&mut self, other: &IdxSet<T>) {
         self.words_mut().clone_from_slice(other.words());
     }
 
diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs
index a89d1afae86..05453bd58c4 100644
--- a/src/librustc_mir/dataflow/at_location.rs
+++ b/src/librustc_mir/dataflow/at_location.rs
@@ -139,7 +139,7 @@ impl<BD> FlowsAtLocation for FlowAtLocation<BD>
     where BD: BitDenotation
 {
     fn reset_to_entry_of(&mut self, bb: BasicBlock) {
-        (*self.curr_state).clone_from(self.base_results.sets().on_entry_set_for(bb.index()));
+        self.curr_state.overwrite(self.base_results.sets().on_entry_set_for(bb.index()));
     }
 
     fn reconstruct_statement_effect(&mut self, loc: Location) {
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 85458c7d684..98cd9c35d88 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -242,7 +242,7 @@ impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> where BD: Bi
             {
                 let sets = builder.flow_state.sets.for_block(bb_idx);
                 debug_assert!(in_out.words().len() == sets.on_entry.words().len());
-                in_out.clone_from(sets.on_entry);
+                in_out.overwrite(sets.on_entry);
                 in_out.union(sets.gen_set);
                 in_out.subtract(sets.kill_set);
             }
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index cfb1a2cd28b..34f8141141d 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -141,14 +141,14 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness
             for &successor in mir.basic_blocks()[b].terminator().successors() {
                 bits.union(&ins[successor]);
             }
-            outs[b].clone_from(&bits);
+            outs[b].overwrite(&bits);
 
             // bits = use ∪ (bits - def)
             def_use[b].apply(&mut bits);
 
             // update bits on entry and flag if they have changed
             if ins[b] != bits {
-                ins[b].clone_from(&bits);
+                ins[b].overwrite(&bits);
                 changed = true;
             }
         }