about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2024-02-16 19:43:50 +0100
committerNilstrieb <48135649+Nilstrieb@users.noreply.github.com>2024-02-19 17:28:49 +0100
commit03d03c666c337acdaeb8911deaade55366bf8959 (patch)
tree8fedd68f446047ed4f6b4e02d0c497600af31a0b
parent8a497723e311a62fccb1f0bf40e79c6519744a12 (diff)
downloadrust-03d03c666c337acdaeb8911deaade55366bf8959.tar.gz
rust-03d03c666c337acdaeb8911deaade55366bf8959.zip
Always inline check in `assert_unsafe_precondition` with cfg(debug_assertions)
The current complexities in `assert_unsafe_precondition` are delicately
balancing several concerns, among them compile times for the cases where
there are no debug assertions. This comes at a large runtime cost when
the assertions are enabled, making the debug assertion compiler a lot
slower, which is very annoying.

To avoid this, we always inline the check when building with debug
assertions.

Numbers (compiling stage1 library after touching core):
- master: 80s
- just adding `#[inline(always)]` to the `cfg(bootstrap)`
  `debug_assertions`: 67s
- this: 54s

So this seems like a good solution. I think we can still get
the same run-time perf improvements for other users too by
massaging this code further (see my other PR about adding
`#[rustc_no_mir_inline]`) but this is a simpler step that
solves the imminent problem of "holy shit my rustc is sooo slow".

Funny consequence: This now means compiling the standard library with
dbeug assertions makes it faster (than without, when using debug
assertions downstream)!
-rw-r--r--library/core/src/intrinsics.rs9
1 files changed, 8 insertions, 1 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index ce1876d5a2f..d1ffc39ecbf 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2575,6 +2575,7 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
 /// assertions disabled. This intrinsic is primarily used by [`assert_unsafe_precondition`].
 #[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
 #[unstable(feature = "core_intrinsics", issue = "none")]
+#[inline(always)]
 #[cfg_attr(not(bootstrap), rustc_intrinsic)]
 pub(crate) const fn debug_assertions() -> bool {
     cfg!(debug_assertions)
@@ -2659,7 +2660,13 @@ pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize)
 macro_rules! assert_unsafe_precondition {
     ($message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => {
         {
-            #[inline(never)]
+            // When the standard library is compiled with debug assertions, we want the check to inline for better performance.
+            // This is important when working on the compiler, which is compiled with debug assertions locally.
+            // When not compiled with debug assertions (so the precompiled std) we outline the check to minimize the compile
+            // time impact when debug assertions are disabled.
+            // It is not clear whether that is the best solution, see #120848.
+            #[cfg_attr(debug_assertions, inline(always))]
+            #[cfg_attr(not(debug_assertions), inline(never))]
             #[rustc_nounwind]
             fn precondition_check($($name:$ty),*) {
                 if !$e {