]> git.lizzy.rs Git - rust.git/commitdiff
Fix major compile time regression
authorBjörn Steinbrink <bsteinbr@gmail.com>
Fri, 15 May 2015 01:14:16 +0000 (03:14 +0200)
committerBjörn Steinbrink <bsteinbr@gmail.com>
Fri, 15 May 2015 01:31:53 +0000 (03:31 +0200)
The assume intrinsic has a strong, negative impact on compile times, so
we're currently only using it in places where LLVM can simplify it to
nonnull metadata on a load intruction. Unfortunately a recent change
that fixed invalid assume calls introduce new assume calls for which
this simplification can not happen, leading to a massive regression in
compile times in certain cases.

Moving the assumptions from the middle of the function to the beginning
allows the simplification to happen again, bringing compile times back
to their old levels.

Fixes #25393

src/libcore/slice.rs

index 9db1ceddf0d752ae20df6770281667b841a63668..546e0bc806e12cab0f5376786782409b755152ff 100644 (file)
@@ -665,14 +665,14 @@ impl<'a, T> Iterator for $name<'a, T> {
             #[inline]
             fn next(&mut self) -> Option<$elem> {
                 // could be implemented with slices, but this avoids bounds checks
-                if self.ptr == self.end {
-                    None
-                } else {
-                    unsafe {
-                        if mem::size_of::<T>() != 0 {
-                            ::intrinsics::assume(!self.ptr.is_null());
-                            ::intrinsics::assume(!self.end.is_null());
-                        }
+                unsafe {
+                    if mem::size_of::<T>() != 0 {
+                        assume(!self.ptr.is_null());
+                        assume(!self.end.is_null());
+                    }
+                    if self.ptr == self.end {
+                        None
+                    } else {
                         let old = self.ptr;
                         self.ptr = slice_offset!(self.ptr, 1);
                         Some(slice_ref!(old))
@@ -710,15 +710,15 @@ impl<'a, T> DoubleEndedIterator for $name<'a, T> {
             #[inline]
             fn next_back(&mut self) -> Option<$elem> {
                 // could be implemented with slices, but this avoids bounds checks
-                if self.end == self.ptr {
-                    None
-                } else {
-                    unsafe {
+                unsafe {
+                    if mem::size_of::<T>() != 0 {
+                        assume(!self.ptr.is_null());
+                        assume(!self.end.is_null());
+                    }
+                    if self.end == self.ptr {
+                        None
+                    } else {
                         self.end = slice_offset!(self.end, -1);
-                        if mem::size_of::<T>() != 0 {
-                            ::intrinsics::assume(!self.ptr.is_null());
-                            ::intrinsics::assume(!self.end.is_null());
-                        }
                         Some(slice_ref!(self.end))
                     }
                 }