Skip to content

Commit

Permalink
Rollup merge of rust-lang#59336 - gnzlbg:hint_black_box, r=alexcrichton
Browse files Browse the repository at this point in the history
Moves test::black_box to core::hint and fix black_box on wasm32 and asm.js

This changes removes a cyclic dependency between the "test" and "libtest"
crates, where "libtest" depends on "test" for "black_box", but "test" depends on
"libtest" for everything else.

I've chosen the "hint" module because there seems to be enough consensus in the
discussion of RFC2360 that this module is where such an intrinsic would belong,
but this PR does not implement that RFC! If that RFC ever gets merged, the API, docs,
etc. of this API will need to change. This PR just move the implementation of the
already existing API.

For backwards compatibility reasons I've chosen to also keep the "test" feature
gate for these instead of adding a new feature gate. If we change the feature
gate, we'll potentially all benchmarks, and while that's something that we could
do, it seems unnecessary to do that now - if RFC2360 gets merged, we'll need to
do that anyways. Backwards compatibility is also why we continue to re-export
"black_box" from the "test" crate.

This PR also fixes black_box on the wasm32 target, which now supports inline assembly, and uses volatile loads on the asm.js target.

r? @Amanieu (cc @rust-lang/libs)
  • Loading branch information
Centril committed Mar 26, 2019
2 parents 48c22d9 + 24db517 commit cad3e4c
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 17 deletions.
22 changes: 22 additions & 0 deletions src/libcore/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,25 @@ pub fn spin_loop() {
}
}
}

/// A function that is opaque to the optimizer, to allow benchmarks to
/// pretend to use outputs to assist in avoiding dead-code
/// elimination.
///
/// This function is a no-op, and does not even read from `dummy`.
#[unstable(feature = "test", issue = "27812")]
pub fn black_box<T>(dummy: T) -> T {
#[cfg(not(target_arch = "asmjs"))] {
// we need to "use" the argument in some way LLVM can't
// introspect.
unsafe { asm!("" : : "r"(&dummy)) }
dummy
}
#[cfg(target_arch = "asmjs")] {
unsafe {
let ret = crate::ptr::read_volatile(&dummy);
crate::mem::forget(dummy);
ret
}
}
}
18 changes: 1 addition & 17 deletions src/libtest/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,7 @@ pub use libtest::{
TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk, stats::Summary
};

/// A function that is opaque to the optimizer, to allow benchmarks to
/// pretend to use outputs to assist in avoiding dead-code
/// elimination.
///
/// This function is a no-op, and does not even read from `dummy`.
#[cfg(not(any(target_arch = "asmjs", target_arch = "wasm32")))]
pub fn black_box<T>(dummy: T) -> T {
// we need to "use" the argument in some way LLVM can't
// introspect.
unsafe { asm!("" : : "r"(&dummy)) }
dummy
}
#[cfg(any(target_arch = "asmjs", target_arch = "wasm32"))]
#[inline(never)]
pub fn black_box<T>(dummy: T) -> T {
dummy
}
pub use std::hint::black_box;

#[cfg(test)]
mod tests {
Expand Down

0 comments on commit cad3e4c

Please sign in to comment.