Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Unify different code paths via macro #217

Closed
Lokathor opened this issue Aug 9, 2019 · 1 comment
Closed

Unify different code paths via macro #217

Lokathor opened this issue Aug 9, 2019 · 1 comment
Labels
enhancement New feature or request

Comments

@Lokathor
Copy link
Contributor

Lokathor commented Aug 9, 2019

Per #216 (review):

  • We want a macro that allows us to cleanly implement various hardware optimized code paths depending on what intrinsics are available at compile time, while also having fallbacks for any platforms without the same hardware abilities.
  • There's various code branches that could be involved here, so "something like" the cfg_if! macro is appropriate here. A macro that's general to several possible situations.
  • That macro could literally be cfg_if!, but that adds in a dependency to a very low level crate. If we can come up with something focused to our particular case that's kept here in this tree that would probably be preferred.
  • There is also the llvm_intrinisically_optimized! macro, which perhaps we could just extend some more, depending on how folks feel about that.
@tgross35
Copy link
Contributor

We have a macro for this now

/// Choose among using an intrinsic, an arch-specific implementation, and the function body.
/// Returns directly if the intrinsic or arch is used, otherwise continue with the rest of the
/// function.
///
/// Specify a `use_intrinsic` meta field if the intrinsic is (1) available on the platforms (i.e.
/// LLVM lowers it without libcalls that may recurse), (2) it is likely to be more performant.
/// Intrinsics require wrappers in the `math::arch::intrinsics` module.
///
/// Specify a `use_arch` meta field if an architecture-specific implementation is provided.
/// These live in the `math::arch::some_target_arch` module.
///
/// Specify a `use_arch_required` meta field if something architecture-specific must be used
/// regardless of feature configuration (`force-soft-floats`).
///
/// The passed meta options do not need to account for relevant Cargo features
/// (`unstable-intrinsics`, `arch`, `force-soft-floats`), this macro handles that part.
macro_rules! select_implementation {
(
name: $fname:ident,
// Configuration meta for when to use arch-specific implementation that requires hard
// float ops
$( use_arch: $use_arch:meta, )?
// Configuration meta for when to use the arch module regardless of whether softfloats
// have been requested.
$( use_arch_required: $use_arch_required:meta, )?
// Configuration meta for when to call intrinsics and let LLVM figure it out
$( use_intrinsic: $use_intrinsic:meta, )?
args: $($arg:ident),+ ,
) => {
. Architecture-specific functions and intrinsics go in https://github.com/rust-lang/libm/tree/d9bfeca91b8aebc628b0e5108ce31b3809014b7f/src/math/arch, you just tell the macro when you want to use them

libm/src/math/sqrt.rs

Lines 84 to 89 in d9bfeca

select_implementation! {
name: sqrt,
use_arch: target_feature = "sse2",
use_intrinsic: target_arch = "wasm32",
args: x,
}
.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants