about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-17 23:57:53 +0000
committerbors <bors@rust-lang.org>2024-11-17 23:57:53 +0000
commit3fb7e441aecc3c054d71eb4d752d06e7776e8888 (patch)
treebba0b25b682b37f1b6040aa63949559619666e9d /library/core/src
parent5ec7d6eee7e0f5236ec1559499070eaf836bc608 (diff)
parent777003ae9fd4d81ada91f67f388d4f12c9ca220a (diff)
downloadrust-3fb7e441aecc3c054d71eb4d752d06e7776e8888.tar.gz
rust-3fb7e441aecc3c054d71eb4d752d06e7776e8888.zip
Auto merge of #120370 - x17jiri:likely_unlikely_fix, r=saethlin
Likely unlikely fix

RFC 1131 ( https://github.com/rust-lang/rust/issues/26179 ) added likely/unlikely intrinsics, but they have been broken for a while: https://github.com/rust-lang/rust/issues/96276 , https://github.com/rust-lang/rust/issues/96275 , https://github.com/rust-lang/rust/issues/88767 . This PR tries to fix them.

Changes:
- added a new `cold_path()` intrinsic
- `likely()` and `unlikely()` changed to regular functions implemented using `cold_path()`
Diffstat (limited to 'library/core/src')
-rw-r--r--library/core/src/intrinsics/mod.rs48
1 files changed, 40 insertions, 8 deletions
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 6a37c60d9c9..8a986337aa1 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -1465,6 +1465,22 @@ pub const unsafe fn assume(b: bool) {
     }
 }
 
+/// Hints to the compiler that current code path is cold.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+///
+/// This intrinsic does not have a stable counterpart.
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[cfg_attr(not(bootstrap), rustc_intrinsic)]
+#[cfg(not(bootstrap))]
+#[rustc_nounwind]
+#[miri::intrinsic_fallback_is_spec]
+#[cold]
+pub const fn cold_path() {}
+
 /// Hints to the compiler that branch condition is likely to be true.
 /// Returns the value passed to it.
 ///
@@ -1480,13 +1496,21 @@ pub const unsafe fn assume(b: bool) {
     bootstrap,
     rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION")
 )]
-#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_intrinsic]
 #[rustc_nounwind]
-#[miri::intrinsic_fallback_is_spec]
+#[inline(always)]
 pub const fn likely(b: bool) -> bool {
-    b
+    #[cfg(bootstrap)]
+    {
+        b
+    }
+    #[cfg(not(bootstrap))]
+    if b {
+        true
+    } else {
+        cold_path();
+        false
+    }
 }
 
 /// Hints to the compiler that branch condition is likely to be false.
@@ -1504,13 +1528,21 @@ pub const fn likely(b: bool) -> bool {
     bootstrap,
     rustc_const_stable(feature = "const_likely", since = "CURRENT_RUSTC_VERSION")
 )]
-#[cfg_attr(not(bootstrap), rustc_const_stable_intrinsic)]
 #[unstable(feature = "core_intrinsics", issue = "none")]
-#[rustc_intrinsic]
 #[rustc_nounwind]
-#[miri::intrinsic_fallback_is_spec]
+#[inline(always)]
 pub const fn unlikely(b: bool) -> bool {
-    b
+    #[cfg(bootstrap)]
+    {
+        b
+    }
+    #[cfg(not(bootstrap))]
+    if b {
+        cold_path();
+        true
+    } else {
+        false
+    }
 }
 
 /// Returns either `true_val` or `false_val` depending on condition `b` with a