Introduce a select_implementation macro
Currently there is a macro called `llvm_intrinsically_optimized` that uses an intrinsic rather than the function implementation if the configuration is correct. Add a new macro `select_implementation` that is somewhat cleaner to use. In the future, we can update this macro with more fields to specify other implementations that may be selected, such as something architecture-specific or e.g. using a generic implementation for `f32` routines, rather than those that convert to `f64`. This introduces a `macros` module within `math/support`. We will be able to move more things here later.
This commit is contained in:
parent
1b7346bf5f
commit
d54896343c
3 changed files with 69 additions and 30 deletions
|
|
@ -74,6 +74,7 @@ macro_rules! div {
|
|||
};
|
||||
}
|
||||
|
||||
// FIXME: phase this out, to be replaced by the more flexible `select_implementation`
|
||||
macro_rules! llvm_intrinsically_optimized {
|
||||
(#[cfg($($clause:tt)*)] $e:expr) => {
|
||||
#[cfg(all(intrinsics_enabled, not(feature = "force-soft-floats"), $($clause)*))]
|
||||
|
|
@ -85,6 +86,38 @@ macro_rules! llvm_intrinsically_optimized {
|
|||
};
|
||||
}
|
||||
|
||||
// Private modules
|
||||
#[macro_use]
|
||||
mod support;
|
||||
mod arch;
|
||||
mod expo2;
|
||||
mod fenv;
|
||||
mod k_cos;
|
||||
mod k_cosf;
|
||||
mod k_expo2;
|
||||
mod k_expo2f;
|
||||
mod k_sin;
|
||||
mod k_sinf;
|
||||
mod k_tan;
|
||||
mod k_tanf;
|
||||
mod rem_pio2;
|
||||
mod rem_pio2_large;
|
||||
mod rem_pio2f;
|
||||
|
||||
// Private re-imports
|
||||
use self::expo2::expo2;
|
||||
use self::k_cos::k_cos;
|
||||
use self::k_cosf::k_cosf;
|
||||
use self::k_expo2::k_expo2;
|
||||
use self::k_expo2f::k_expo2f;
|
||||
use self::k_sin::k_sin;
|
||||
use self::k_sinf::k_sinf;
|
||||
use self::k_tan::k_tan;
|
||||
use self::k_tanf::k_tanf;
|
||||
use self::rem_pio2::rem_pio2;
|
||||
use self::rem_pio2_large::rem_pio2_large;
|
||||
use self::rem_pio2f::rem_pio2f;
|
||||
|
||||
// Public modules
|
||||
mod acos;
|
||||
mod acosf;
|
||||
|
|
@ -301,36 +334,6 @@ pub use self::tgammaf::tgammaf;
|
|||
pub use self::trunc::trunc;
|
||||
pub use self::truncf::truncf;
|
||||
|
||||
// Private modules
|
||||
mod arch;
|
||||
mod expo2;
|
||||
mod fenv;
|
||||
mod k_cos;
|
||||
mod k_cosf;
|
||||
mod k_expo2;
|
||||
mod k_expo2f;
|
||||
mod k_sin;
|
||||
mod k_sinf;
|
||||
mod k_tan;
|
||||
mod k_tanf;
|
||||
mod rem_pio2;
|
||||
mod rem_pio2_large;
|
||||
mod rem_pio2f;
|
||||
|
||||
// Private re-imports
|
||||
use self::expo2::expo2;
|
||||
use self::k_cos::k_cos;
|
||||
use self::k_cosf::k_cosf;
|
||||
use self::k_expo2::k_expo2;
|
||||
use self::k_expo2f::k_expo2f;
|
||||
use self::k_sin::k_sin;
|
||||
use self::k_sinf::k_sinf;
|
||||
use self::k_tan::k_tan;
|
||||
use self::k_tanf::k_tanf;
|
||||
use self::rem_pio2::rem_pio2;
|
||||
use self::rem_pio2_large::rem_pio2_large;
|
||||
use self::rem_pio2f::rem_pio2f;
|
||||
|
||||
#[inline]
|
||||
fn get_high_word(x: f64) -> u32 {
|
||||
(x.to_bits() >> 32) as u32
|
||||
|
|
|
|||
34
library/compiler-builtins/libm/src/math/support/macros.rs
Normal file
34
library/compiler-builtins/libm/src/math/support/macros.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/// Choose among using an intrinsic (if available) and falling back to the default function body.
|
||||
/// Returns directly if the intrinsic version is used, otherwise continues to the rest of the
|
||||
/// function.
|
||||
///
|
||||
/// Use this if the intrinsic is likely to be more performant on the platform(s) specified
|
||||
/// in `intrinsic_available`.
|
||||
///
|
||||
/// The `cfg` used here is controlled by `build.rs` so the passed meta does not need to account
|
||||
/// for e.g. the `unstable-intrinsics` or `force-soft-float` features.
|
||||
macro_rules! select_implementation {
|
||||
(
|
||||
name: $fname:ident,
|
||||
// Configuration meta for when to call intrinsics and let LLVM figure it out
|
||||
$( use_intrinsic: $use_intrinsic:meta, )?
|
||||
args: $($arg:ident),+ ,
|
||||
) => {
|
||||
// FIXME: these use paths that are a pretty fragile (`super`). We should figure out
|
||||
// something better w.r.t. how this is vendored into compiler-builtins.
|
||||
|
||||
// Never use intrinsics if we are forcing soft floats, and only enable with the
|
||||
// `unstable-intrinsics` feature.
|
||||
#[cfg(intrinsics_enabled)]
|
||||
select_implementation! {
|
||||
@cfg $( $use_intrinsic )?;
|
||||
if true {
|
||||
return super::arch::intrinsics::$fname( $($arg),+ );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Coalesce helper to construct an expression only if a config is provided
|
||||
(@cfg ; $ex:expr) => { };
|
||||
(@cfg $provided:meta; $ex:expr) => { #[cfg($provided)] $ex };
|
||||
}
|
||||
2
library/compiler-builtins/libm/src/math/support/mod.rs
Normal file
2
library/compiler-builtins/libm/src/math/support/mod.rs
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#[macro_use]
|
||||
pub mod macros;
|
||||
Loading…
Add table
Add a link
Reference in a new issue