about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBjörn Steinbrink <bsteinbr@gmail.com>2015-05-15 03:14:16 +0200
committerBjörn Steinbrink <bsteinbr@gmail.com>2015-05-15 03:31:53 +0200
commit02603334ae22971409c11e547a3568d70b9c60ac (patch)
tree7595b38d651dd83e41546ea28f1fa9fafee12281
parentb1bd3a3c5180b2d671e5810cb5211b2d2b456a71 (diff)
downloadrust-02603334ae22971409c11e547a3568d70b9c60ac.tar.gz
rust-02603334ae22971409c11e547a3568d70b9c60ac.zip
Fix major compile time regression
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
-rw-r--r--src/libcore/slice.rs32
1 files changed, 16 insertions, 16 deletions
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 9db1ceddf0d..546e0bc806e 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -665,14 +665,14 @@ macro_rules! iterator {
             #[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 @@ macro_rules! iterator {
             #[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))
                     }
                 }