Skip to content

Commit

Permalink
Reexport likely/unlikely in std::hint
Browse files Browse the repository at this point in the history
  • Loading branch information
x17jiri committed Dec 1, 2024
1 parent 4af7fa7 commit 2130bbb
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 2 deletions.
62 changes: 62 additions & 0 deletions library/core/src/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,3 +511,65 @@ pub const fn black_box<T>(dummy: T) -> T {
pub const fn must_use<T>(value: T) -> T {
value
}

/// Hints to the compiler that branch condition is likely to be true.
/// Returns the value passed to it.
///
/// It can be used with `if` or boolean `match` expressions.
///
/// # Examples
///
/// ```
/// #![feature(likely_unlikely)]
/// use core::hint::likely;
///
/// fn foo(x: i32) {
/// if likely(x > 0) {
/// println!("this branch is likely to be taken");
/// } else {
/// println!("this branch is unlikely to be taken");
/// }
///
/// match likely(x > 0) {
/// true => println!("this branch is likely to be taken"),
/// false => println!("this branch is unlikely to be taken"),
/// }
/// }
/// ```
#[unstable(feature = "likely_unlikely", issue = "26179")]
#[rustc_nounwind]
#[inline(always)]
pub const fn likely(b: bool) -> bool {
crate::intrinsics::likely(b)
}

/// Hints to the compiler that the branch condition is unlikely to be true.
/// Returns the value passed to it.
///
/// It can be used with `if` or boolean `match` expressions.
///
/// # Examples
///
/// ```
/// #![feature(likely_unlikely)]
/// use core::hint::unlikely;
///
/// fn foo(x: i32) {
/// if unlikely(x > 0) {
/// println!("this branch is unlikely to be taken");
/// } else {
/// println!("this branch is likely to be taken");
/// }
///
/// match unlikely(x > 0) {
/// true => println!("this branch is unlikely to be taken"),
/// false => println!("this branch is likely to be taken"),
/// }
/// }
/// ```
#[unstable(feature = "likely_unlikely", issue = "26179")]
#[rustc_nounwind]
#[inline(always)]
pub const fn unlikely(b: bool) -> bool {
crate::intrinsics::unlikely(b)
}
81 changes: 81 additions & 0 deletions tests/codegen/hint/likely.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//@ compile-flags: -O
#![crate_type = "lib"]
#![feature(likely_unlikely)]

use std::hint::likely;

#[inline(never)]
#[no_mangle]
pub fn path_a() {
println!("path a");
}

#[inline(never)]
#[no_mangle]
pub fn path_b() {
println!("path b");
}

#[no_mangle]
pub fn test1(x: bool) {
if likely(x) {
path_a();
} else {
path_b();
}
}

#[no_mangle]
pub fn test2(x: i32) {
match likely(x > 0) {
true => path_a(),
false => path_b(),
}
}

#[no_mangle]
pub fn test3(x: i8) {
match likely(x < 7) {
true => path_a(),
_ => path_b(),
}
}

#[no_mangle]
pub fn test4(x: u64) {
match likely(x != 33) {
false => path_a(),
_ => path_b(),
}
}

// CHECK-LABEL: @test1(
// CHECK: br i1 %x, label %bb2, label %bb3, !prof ![[NUM:[0-9]+]]
// CHECK: bb3:
// CHECK: path_b
// CHECK: bb2:
// CHECK: path_a

// CHECK-LABEL: @test2(
// CHECK: br i1 %_2, label %bb2, label %bb3, !prof ![[NUM]]
// CHECK: bb3:
// CHECK: path_b
// CHECK: bb2:
// CHECK: path_a

// CHECK-LABEL: @test3(
// CHECK: br i1 %_2, label %bb2, label %bb3, !prof ![[NUM]]
// CHECK: bb3:
// CHECK: path_b
// CHECK: bb2:
// CHECK: path_a

// CHECK-LABEL: @test4(
// CHECK: br i1 %0, label %bb3, label %bb2, !prof ![[NUM2:[0-9]+]]
// CHECK: bb3:
// CHECK: path_a
// CHECK: bb2:
// CHECK: path_b

// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 2000, i32 1}
// CHECK: ![[NUM2]] = !{!"branch_weights", {{(!"expected", )?}}i32 1, i32 2000}
80 changes: 80 additions & 0 deletions tests/codegen/hint/unlikely.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//@ compile-flags: -O
#![crate_type = "lib"]
#![feature(likely_unlikely)]

use std::hint::unlikely;

#[inline(never)]
#[no_mangle]
pub fn path_a() {
println!("path a");
}

#[inline(never)]
#[no_mangle]
pub fn path_b() {
println!("path b");
}

#[no_mangle]
pub fn test1(x: bool) {
if unlikely(x) {
path_a();
} else {
path_b();
}
}

#[no_mangle]
pub fn test2(x: i32) {
match unlikely(x > 0) {
true => path_a(),
false => path_b(),
}
}

#[no_mangle]
pub fn test3(x: i8) {
match unlikely(x < 7) {
true => path_a(),
_ => path_b(),
}
}

#[no_mangle]
pub fn test4(x: u64) {
match unlikely(x != 33) {
false => path_a(),
_ => path_b(),
}
}

// CHECK-LABEL: @test1(
// CHECK: br i1 %x, label %bb2, label %bb4, !prof ![[NUM:[0-9]+]]
// CHECK: bb4:
// CHECK: path_b
// CHECK: bb2:
// CHECK: path_a

// CHECK-LABEL: @test2(
// CHECK: br i1 %_2, label %bb2, label %bb4, !prof ![[NUM]]
// CHECK: bb4:
// CHECK: path_b
// CHECK: bb2:
// CHECK: path_a

// CHECK-LABEL: @test3(
// CHECK: br i1 %_2, label %bb2, label %bb4, !prof ![[NUM]]
// CHECK: bb4:
// CHECK: path_b
// CHECK: bb2:
// CHECK: path_a

// CHECK-LABEL: @test4(
// CHECK: br i1 %0, label %bb4, label %bb2, !prof ![[NUM2:[0-9]+]]
// CHECK: bb4:
// CHECK: path_a
// CHECK: bb2:
// CHECK: path_b

// CHECK: ![[NUM]] = !{!"branch_weights", {{(!"expected", )?}}i32 1, i32 2000}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
scope 6 (inlined core::num::<impl u16>::checked_add) {
let mut _5: (u16, bool);
let mut _6: bool;
scope 7 (inlined unlikely) {
scope 7 (inlined std::intrinsics::unlikely) {
let _7: ();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn step_forward(_1: u16, _2: usize) -> u16 {
scope 6 (inlined core::num::<impl u16>::checked_add) {
let mut _5: (u16, bool);
let mut _6: bool;
scope 7 (inlined unlikely) {
scope 7 (inlined std::intrinsics::unlikely) {
let _7: ();
}
}
Expand Down

0 comments on commit 2130bbb

Please sign in to comment.