summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorUlrik Sverdrup <bluss@users.noreply.github.com>2016-01-18 14:51:56 +0100
committerUlrik Sverdrup <bluss@users.noreply.github.com>2016-01-18 15:28:00 +0100
commit6a7bc47a8f1bf4441ca55e42aa50db6dda28181f (patch)
treea2f45c09ea9a4436399ba306f62b1cf40eb8db2c /src/libcore
parent9d21acaf9b41ea2529b15d5efd06266e924c0496 (diff)
downloadrust-6a7bc47a8f1bf4441ca55e42aa50db6dda28181f.tar.gz
rust-6a7bc47a8f1bf4441ca55e42aa50db6dda28181f.zip
core: 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]).
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/slice.rs9
1 files changed, 7 insertions, 2 deletions
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 583bb57a4a6..6107564b4ae 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -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]);
         }
     }
 }