mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-01 01:23:26 +00:00
Specialize array cloning for Copy types
Because after PR 86041, the optimizer no longer load-merges at the LLVM IR level, which might be part of the perf loss. (I'll run perf and see if this makes a difference.) Also I added a codegen test so this hopefully won't regress in future -- it passes on stable and with my change here, but not on the 2021-11-09 nightly.
This commit is contained in:
parent
8b09ba6a5d
commit
cc7d8014d7
@ -339,9 +339,7 @@ impl<T: Copy, const N: usize> Copy for [T; N] {}
|
||||
impl<T: Clone, const N: usize> Clone for [T; N] {
|
||||
#[inline]
|
||||
fn clone(&self) -> Self {
|
||||
// SAFETY: we know for certain that this iterator will yield exactly `N`
|
||||
// items.
|
||||
unsafe { collect_into_array_unchecked(&mut self.iter().cloned()) }
|
||||
SpecArrayClone::clone(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@ -350,6 +348,27 @@ impl<T: Clone, const N: usize> Clone for [T; N] {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
trait SpecArrayClone: Clone {
|
||||
fn clone<const N: usize>(array: &[Self; N]) -> [Self; N];
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
impl<T: Clone> SpecArrayClone for T {
|
||||
default fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
|
||||
// SAFETY: we know for certain that this iterator will yield exactly `N`
|
||||
// items.
|
||||
unsafe { collect_into_array_unchecked(&mut array.iter().cloned()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
impl<T: Copy> SpecArrayClone for T {
|
||||
fn clone<const N: usize>(array: &[T; N]) -> [T; N] {
|
||||
*array
|
||||
}
|
||||
}
|
||||
|
||||
// The Default impls cannot be done with const generics because `[T; 0]` doesn't
|
||||
// require Default to be implemented, and having different impl blocks for
|
||||
// different numbers isn't supported yet.
|
||||
|
15
src/test/codegen/array-clone.rs
Normal file
15
src/test/codegen/array-clone.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// compile-flags: -O
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// CHECK-LABEL: @array_clone
|
||||
#[no_mangle]
|
||||
pub fn array_clone(a: &[u8; 2]) -> [u8; 2] {
|
||||
// CHECK-NOT: getelementptr
|
||||
// CHECK-NOT: load i8
|
||||
// CHECK-NOT: zext
|
||||
// CHECK-NOT: shl
|
||||
// CHECK: load i16
|
||||
// CHECK-NEXT: ret i16
|
||||
a.clone()
|
||||
}
|
Loading…
Reference in New Issue
Block a user