Skip to content

Commit 08683f0

Browse files
committed
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)`.
1 parent 99a9d68 commit 08683f0

File tree

4 files changed

+7
-5
lines changed

4 files changed

+7
-5
lines changed

src/librustc_data_structures/indexed_set.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,9 @@ impl<T: Idx> IdxSet<T> {
233233
&mut self.bits
234234
}
235235

236-
pub fn clone_from(&mut self, other: &IdxSet<T>) {
236+
/// Efficiently overwrite `self` with `other`. Panics if `self` and `other`
237+
/// don't have the same length.
238+
pub fn overwrite(&mut self, other: &IdxSet<T>) {
237239
self.words_mut().clone_from_slice(other.words());
238240
}
239241

src/librustc_mir/dataflow/at_location.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl<BD> FlowsAtLocation for FlowAtLocation<BD>
139139
where BD: BitDenotation
140140
{
141141
fn reset_to_entry_of(&mut self, bb: BasicBlock) {
142-
(*self.curr_state).clone_from(self.base_results.sets().on_entry_set_for(bb.index()));
142+
self.curr_state.overwrite(self.base_results.sets().on_entry_set_for(bb.index()));
143143
}
144144

145145
fn reconstruct_statement_effect(&mut self, loc: Location) {

src/librustc_mir/dataflow/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> where BD: Bi
242242
{
243243
let sets = builder.flow_state.sets.for_block(bb_idx);
244244
debug_assert!(in_out.words().len() == sets.on_entry.words().len());
245-
in_out.clone_from(sets.on_entry);
245+
in_out.overwrite(sets.on_entry);
246246
in_out.union(sets.gen_set);
247247
in_out.subtract(sets.kill_set);
248248
}

src/librustc_mir/util/liveness.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,14 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness
141141
for &successor in mir.basic_blocks()[b].terminator().successors() {
142142
bits.union(&ins[successor]);
143143
}
144-
outs[b].clone_from(&bits);
144+
outs[b].overwrite(&bits);
145145

146146
// bits = use ∪ (bits - def)
147147
def_use[b].apply(&mut bits);
148148

149149
// update bits on entry and flag if they have changed
150150
if ins[b] != bits {
151-
ins[b].clone_from(&bits);
151+
ins[b].overwrite(&bits);
152152
changed = true;
153153
}
154154
}

0 commit comments

Comments
 (0)