Skip to content

Commit

Permalink
Auto merge of #31000 - bluss:efficient-clone-from-slice, r=dotdash
Browse files Browse the repository at this point in the history
Restore indexed formulation of clone_from_slice

For good codegen here, we need a lock step iteration where the loop
bound is only checked once per iteration; .zip() unfortunately does not
optimize this way.

If we use a counted loop, and make sure that llvm sees that the bounds
check condition is the same as the loop bound condition, the bounds
checks are optimized out. For this reason we need to slice `from`
(apparently) redundantly.

This commit restores the old formulation of clone_from_slice. In this
shape, clone_from_slice will again optimize into calling memcpy where possible
(for example for &[u8] or &[i32]).
  • Loading branch information
bors committed Jan 18, 2016
2 parents a09a604 + 6a7bc47 commit 0888649
Showing 1 changed file with 7 additions and 2 deletions.
9 changes: 7 additions & 2 deletions src/libcore/slice.rs
Expand Up @@ -478,8 +478,13 @@ impl<T> SliceExt for [T] {
fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
assert!(self.len() == src.len(),
"destination and source slices have different lengths");
for (dst, src) in self.iter_mut().zip(src) {
dst.clone_from(src);
// NOTE: We need to explicitly slice them to the same length
// for bounds checking to be elided, and the optimizer will
// generate memcpy for simple cases (for example T = u8).
let len = self.len();
let src = &src[..len];
for i in 0..len {
self[i].clone_from(&src[i]);
}
}
}
Expand Down

0 comments on commit 0888649

Please sign in to comment.