Skip to content

Black box function #145

Open
Open
@kazimuth

Description

@kazimuth

It would be nice to have a function to disable dead-code elimination / constant propagation. Rust has this; it's implemented as the identity function, but with magic inside:

assert_eq!(100, std::hints::black_box(100));

Rust implementation:

/// 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`.
#[inline]
#[unstable(feature = "test", issue = "27812")]
#[allow(unreachable_code)] // this makes #[cfg] a bit easier below.
pub fn black_box<T>(dummy: T) -> T {
    // We need to "use" the argument in some way LLVM can't introspect, and on
    // targets that support it we can typically leverage inline assembly to do
    // this. LLVM's intepretation of inline assembly is that it's, well, a black
    // box. This isn't the greatest implementation since it probably deoptimizes
    // more than we want, but it's so far good enough.
    #[cfg(not(any(
        target_arch = "asmjs",
        all(
            target_arch = "wasm32",
            target_os = "emscripten"
        )
    )))]
    unsafe {
        asm!("" : : "r"(&dummy));
        return dummy;
    }

    // Not all platforms support inline assembly so try to do something without
    // inline assembly which in theory still hinders at least some optimizations
    // on those targets. This is the "best effort" scenario.
    unsafe {
        let ret = crate::ptr::read_volatile(&dummy);
        crate::mem::forget(dummy);
        ret
    }
}

I don't know how hard this would be to translate to Julia.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions