diff options
| author | bors <bors@rust-lang.org> | 2013-04-20 11:57:50 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-04-20 11:57:50 -0700 |
| commit | ae3b8690c1e9c4debf20b4455ad50a79d5859ee9 (patch) | |
| tree | 58406cf3c0ff22fc9ada505a40109c6acc779a2d | |
| parent | 2b09267b762398a3c851ecfd55d5d01aee906352 (diff) | |
| parent | c5baeb1db3d84e1ab0d14a8055db3a7d3cba638d (diff) | |
auto merge of #5975 : huonw/rust/rustc-intrinsics-fixed-stack, r=pcwalton
This implements the fixed_stack_segment for items with the rust-intrinsic abi, and then uses it to make f32 and f64 use intrinsics where appropriate, but without overflowing stacks and killing canaries (cf. #5686 and #5697). Hopefully. @pcwalton, the fixed_stack_segment implementation involved mirroring its implementation in `base.rs` in `trans_closure`, but without adding the `set_no_inline` (reasoning: that would defeat the purpose of intrinsics), which is possibly incorrect. I'm a little hazy about how the underlying structure works, so I've annotated the 4 that have caused problems so far, but there's no guarantee that the other intrinsics are entirely well-behaved. Anyway, it has good results (the following are just summing the result of each function for 1 up to 100 million): ``` $ ./intrinsics-perf.sh f32 func new old speedup sin 0.80 2.75 3.44 cos 0.80 2.76 3.45 sqrt 0.56 2.73 4.88 ln 1.01 2.94 2.91 log10 0.97 2.90 2.99 log2 1.01 2.95 2.92 exp 0.90 2.85 3.17 exp2 0.92 2.87 3.12 pow 6.95 8.57 1.23 geometric mean: 2.97 $ ./intrinsics-perf.sh f64 func new old speedup sin 12.08 14.06 1.16 cos 12.04 13.67 1.14 sqrt 0.49 2.73 5.57 ln 4.11 5.59 1.36 log10 5.09 6.54 1.28 log2 2.78 5.10 1.83 exp 2.00 3.97 1.99 exp2 1.71 3.71 2.17 pow 5.90 7.51 1.27 geometric mean: 1.72 ``` So about 3x faster on average for f32, and 1.7x for f64. This isn't exactly apples to apples though, since this patch also adds #[inline(always)] to all the function definitions too, which possibly gives a speedup. (fwiw, GitHub is showing 93c0888 after d9c54f8 (since I cherry-picked the latter from #5697), but git's order is the other way.)
| -rw-r--r-- | src/libcore/num/f32.rs | 152 | ||||
| -rw-r--r-- | src/libcore/num/f64.rs | 165 | ||||
| -rw-r--r-- | src/libcore/num/float.rs | 2 | ||||
| -rw-r--r-- | src/libcore/unstable/intrinsics.rs | 13 | ||||
| -rw-r--r-- | src/librustc/middle/trans/foreign.rs | 6 | ||||
| -rw-r--r-- | src/librustc/middle/trans/monomorphize.rs | 2 | ||||
| -rw-r--r-- | src/test/bench/shootout-nbody.rs | 6 | ||||
| -rw-r--r-- | src/test/bench/shootout-spectralnorm.rs | 4 |
8 files changed, 188 insertions, 162 deletions
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 404f1a82de5..6233f8c2a61 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -10,12 +10,9 @@ //! Operations and constants for `f32` -use cmath; -use libc::{c_float, c_int}; use num::strconv; use num; use option::Option; -use unstable::intrinsics::floorf32; use from_str; use to_str; @@ -24,79 +21,93 @@ use to_str; pub use cmath::c_float_targ_consts::*; +// An inner module is required to get the #[inline(always)] attribute on the +// functions. +pub use self::delegated::*; + macro_rules! delegate( ( - fn $name:ident( - $( - $arg:ident : $arg_ty:ty - ),* - ) -> $rv:ty = $bound_name:path + $( + fn $name:ident( + $( + $arg:ident : $arg_ty:ty + ),* + ) -> $rv:ty = $bound_name:path + ),* ) => ( - pub fn $name($( $arg : $arg_ty ),*) -> $rv { - unsafe { - $bound_name($( $arg ),*) - } + mod delegated { + use cmath::c_float_utils; + use libc::{c_float, c_int}; + use unstable::intrinsics; + + $( + #[inline(always)] + pub fn $name($( $arg : $arg_ty ),*) -> $rv { + unsafe { + $bound_name($( $arg ),*) + } + } + )* } ) ) -delegate!(fn acos(n: c_float) -> c_float = cmath::c_float_utils::acos) -delegate!(fn asin(n: c_float) -> c_float = cmath::c_float_utils::asin) -delegate!(fn atan(n: c_float) -> c_float = cmath::c_float_utils::atan) -delegate!(fn atan2(a: c_float, b: c_float) -> c_float = - cmath::c_float_utils::atan2) -delegate!(fn cbrt(n: c_float) -> c_float = cmath::c_float_utils::cbrt) -delegate!(fn ceil(n: c_float) -> c_float = cmath::c_float_utils::ceil) -delegate!(fn copysign(x: c_float, y: c_float) -> c_float = - cmath::c_float_utils::copysign) -delegate!(fn cos(n: c_float) -> c_float = cmath::c_float_utils::cos) -delegate!(fn cosh(n: c_float) -> c_float = cmath::c_float_utils::cosh) -delegate!(fn erf(n: c_float) -> c_float = cmath::c_float_utils::erf) -delegate!(fn erfc(n: c_float) -> c_float = cmath::c_float_utils::erfc) -delegate!(fn exp(n: c_float) -> c_float = cmath::c_float_utils::exp) -delegate!(fn expm1(n: c_float) -> c_float = cmath::c_float_utils::expm1) -delegate!(fn exp2(n: c_float) -> c_float = cmath::c_float_utils::exp2) -delegate!(fn abs(n: c_float) -> c_float = cmath::c_float_utils::abs) -delegate!(fn abs_sub(a: c_float, b: c_float) -> c_float = - cmath::c_float_utils::abs_sub) -delegate!(fn mul_add(a: c_float, b: c_float, c: c_float) -> c_float = - cmath::c_float_utils::mul_add) -delegate!(fn fmax(a: c_float, b: c_float) -> c_float = - cmath::c_float_utils::fmax) -delegate!(fn fmin(a: c_float, b: c_float) -> c_float = - cmath::c_float_utils::fmin) -delegate!(fn nextafter(x: c_float, y: c_float) -> c_float = - cmath::c_float_utils::nextafter) -delegate!(fn frexp(n: c_float, value: &mut c_int) -> c_float = - cmath::c_float_utils::frexp) -delegate!(fn hypot(x: c_float, y: c_float) -> c_float = - cmath::c_float_utils::hypot) -delegate!(fn ldexp(x: c_float, n: c_int) -> c_float = - cmath::c_float_utils::ldexp) -delegate!(fn lgamma(n: c_float, sign: &mut c_int) -> c_float = - cmath::c_float_utils::lgamma) -delegate!(fn ln(n: c_float) -> c_float = cmath::c_float_utils::ln) -delegate!(fn log_radix(n: c_float) -> c_float = - cmath::c_float_utils::log_radix) -delegate!(fn ln1p(n: c_float) -> c_float = cmath::c_float_utils::ln1p) -delegate!(fn log10(n: c_float) -> c_float = cmath::c_float_utils::log10) -delegate!(fn log2(n: c_float) -> c_float = cmath::c_float_utils::log2) -delegate!(fn ilog_radix(n: c_float) -> c_int = - cmath::c_float_utils::ilog_radix) -delegate!(fn modf(n: c_float, iptr: &mut c_float) -> c_float = - cmath::c_float_utils::modf) -delegate!(fn pow(n: c_float, e: c_float) -> c_float = - cmath::c_float_utils::pow) -delegate!(fn round(n: c_float) -> c_float = cmath::c_float_utils::round) -delegate!(fn ldexp_radix(n: c_float, i: c_int) -> c_float = - cmath::c_float_utils::ldexp_radix) -delegate!(fn sin(n: c_float) -> c_float = cmath::c_float_utils::sin) -delegate!(fn sinh(n: c_float) -> c_float = cmath::c_float_utils::sinh) -delegate!(fn sqrt(n: c_float) -> c_float = cmath::c_float_utils::sqrt) -delegate!(fn tan(n: c_float) -> c_float = cmath::c_float_utils::tan) -delegate!(fn tanh(n: c_float) -> c_float = cmath::c_float_utils::tanh) -delegate!(fn tgamma(n: c_float) -> c_float = cmath::c_float_utils::tgamma) -delegate!(fn trunc(n: c_float) -> c_float = cmath::c_float_utils::trunc) +delegate!( + // intrinsics + fn abs(n: f32) -> f32 = intrinsics::fabsf32, + fn cos(n: f32) -> f32 = intrinsics::cosf32, + fn exp(n: f32) -> f32 = intrinsics::expf32, + fn exp2(n: f32) -> f32 = intrinsics::exp2f32, + fn floor(x: f32) -> f32 = intrinsics::floorf32, + fn ln(n: f32) -> f32 = intrinsics::logf32, + fn log10(n: f32) -> f32 = intrinsics::log10f32, + fn log2(n: f32) -> f32 = intrinsics::log2f32, + fn mul_add(a: f32, b: f32, c: f32) -> f32 = intrinsics::fmaf32, + fn pow(n: f32, e: f32) -> f32 = intrinsics::powf32, + fn powi(n: f32, e: c_int) -> f32 = intrinsics::powif32, + fn sin(n: f32) -> f32 = intrinsics::sinf32, + fn sqrt(n: f32) -> f32 = intrinsics::sqrtf32, + + // LLVM 3.3 required to use intrinsics for these four + fn ceil(n: c_float) -> c_float = c_float_utils::ceil, + fn trunc(n: c_float) -> c_float = c_float_utils::trunc, + /* + fn ceil(n: f32) -> f32 = intrinsics::ceilf32, + fn trunc(n: f32) -> f32 = intrinsics::truncf32, + fn rint(n: f32) -> f32 = intrinsics::rintf32, + fn nearbyint(n: f32) -> f32 = intrinsics::nearbyintf32, + */ + + // cmath + fn acos(n: c_float) -> c_float = c_float_utils::acos, + fn asin(n: c_float) -> c_float = c_float_utils::asin, + fn atan(n: c_float) -> c_float = c_float_utils::atan, + fn atan2(a: c_float, b: c_float) -> c_float = c_float_utils::atan2, + fn cbrt(n: c_float) -> c_float = c_float_utils::cbrt, + fn copysign(x: c_float, y: c_float) -> c_float = c_float_utils::copysign, + fn cosh(n: c_float) -> c_float = c_float_utils::cosh, + fn erf(n: c_float) -> c_float = c_float_utils::erf, + fn erfc(n: c_float) -> c_float = c_float_utils::erfc, + fn expm1(n: c_float) -> c_float = c_float_utils::expm1, + fn abs_sub(a: c_float, b: c_float) -> c_float = c_float_utils::abs_sub, + fn fmax(a: c_float, b: c_float) -> c_float = c_float_utils::fmax, + fn fmin(a: c_float, b: c_float) -> c_float = c_float_utils::fmin, + fn nextafter(x: c_float, y: c_float) -> c_float = c_float_utils::nextafter, + fn frexp(n: c_float, value: &mut c_int) -> c_float = c_float_utils::frexp, + fn hypot(x: c_float, y: c_float) -> c_float = c_float_utils::hypot, + fn ldexp(x: c_float, n: c_int) -> c_float = c_float_utils::ldexp, + fn lgamma(n: c_float, sign: &mut c_int) -> c_float = c_float_utils::lgamma, + fn log_radix(n: c_float) -> c_float = c_float_utils::log_radix, + fn ln1p(n: c_float) -> c_float = c_float_utils::ln1p, + fn ilog_radix(n: c_float) -> c_int = c_float_utils::ilog_radix, + fn modf(n: c_float, iptr: &mut c_float) -> c_float = c_float_utils::modf, + fn round(n: c_float) -> c_float = c_float_utils::round, + fn ldexp_radix(n: c_float, i: c_int) -> c_float = c_float_utils::ldexp_radix, + fn sinh(n: c_float) -> c_float = c_float_utils::sinh, + fn tan(n: c_float) -> c_float = c_float_utils::tan, + fn tanh(n: c_float) -> c_float = c_float_utils::tanh, + fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma) + // These are not defined inside consts:: for consistency with // the integer types @@ -143,9 +154,6 @@ pub fn ge(x: f32, y: f32) -> bool { return x >= y; } #[inline(always)] pub fn gt(x: f32, y: f32) -> bool { return x > y; } -/// Returns `x` rounded down -#[inline(always)] -pub fn floor(x: f32) -> f32 { unsafe { floorf32(x) } } // FIXME (#1999): replace the predicates below with llvm intrinsics or // calls to the libmath macros in the rust runtime for performance. diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index b4eaa0e7fdc..7f32893f5bf 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -10,12 +10,9 @@ //! Operations and constants for `f64` -use cmath; -use libc::{c_double, c_int}; use num::strconv; use num; use option::Option; -use unstable::intrinsics::floorf64; use to_str; use from_str; @@ -25,87 +22,98 @@ use from_str; pub use cmath::c_double_targ_consts::*; pub use cmp::{min, max}; +// An inner module is required to get the #[inline(always)] attribute on the +// functions. +pub use self::delegated::*; + macro_rules! delegate( ( - fn $name:ident( - $( - $arg:ident : $arg_ty:ty - ),* - ) -> $rv:ty = $bound_name:path + $( + fn $name:ident( + $( + $arg:ident : $arg_ty:ty + ),* + ) -> $rv:ty = $bound_name:path + ),* ) => ( - pub fn $name($( $arg : $arg_ty ),*) -> $rv { - unsafe { - $bound_name($( $arg ),*) - } + mod delegated { + use cmath::c_double_utils; + use libc::{c_double, c_int}; + use unstable::intrinsics; + + $( + #[inline(always)] + pub fn $name($( $arg : $arg_ty ),*) -> $rv { + unsafe { + $bound_name($( $arg ),*) + } + } + )* } ) ) -delegate!(fn acos(n: c_double) -> c_double = cmath::c_double_utils::acos) -delegate!(fn asin(n: c_double) -> c_double = cmath::c_double_utils::asin) -delegate!(fn atan(n: c_double) -> c_double = cmath::c_double_utils::atan) -delegate!(fn atan2(a: c_double, b: c_double) -> c_double = - cmath::c_double_utils::atan2) -delegate!(fn cbrt(n: c_double) -> c_double = cmath::c_double_utils::cbrt) -delegate!(fn ceil(n: c_double) -> c_double = cmath::c_double_utils::ceil) -delegate!(fn copysign(x: c_double, y: c_double) -> c_double = - cmath::c_double_utils::copysign) -delegate!(fn cos(n: c_double) -> c_double = cmath::c_double_utils::cos) -delegate!(fn cosh(n: c_double) -> c_double = cmath::c_double_utils::cosh) -delegate!(fn erf(n: c_double) -> c_double = cmath::c_double_utils::erf) -delegate!(fn erfc(n: c_double) -> c_double = cmath::c_double_utils::erfc) -delegate!(fn exp(n: c_double) -> c_double = cmath::c_double_utils::exp) -delegate!(fn expm1(n: c_double) -> c_double = cmath::c_double_utils::expm1) -delegate!(fn exp2(n: c_double) -> c_double = cmath::c_double_utils::exp2) -delegate!(fn abs(n: c_double) -> c_double = cmath::c_double_utils::abs) -delegate!(fn abs_sub(a: c_double, b: c_double) -> c_double = - cmath::c_double_utils::abs_sub) -delegate!(fn mul_add(a: c_double, b: c_double, c: c_double) -> c_double = - cmath::c_double_utils::mul_add) -delegate!(fn fmax(a: c_double, b: c_double) -> c_double = - cmath::c_double_utils::fmax) -delegate!(fn fmin(a: c_double, b: c_double) -> c_double = - cmath::c_double_utils::fmin) -delegate!(fn nextafter(x: c_double, y: c_double) -> c_double = - cmath::c_double_utils::nextafter) -delegate!(fn frexp(n: c_double, value: &mut c_int) -> c_double = - cmath::c_double_utils::frexp) -delegate!(fn hypot(x: c_double, y: c_double) -> c_double = - cmath::c_double_utils::hypot) -delegate!(fn ldexp(x: c_double, n: c_int) -> c_double = - cmath::c_double_utils::ldexp) -delegate!(fn lgamma(n: c_double, sign: &mut c_int) -> c_double = - cmath::c_double_utils::lgamma) -delegate!(fn ln(n: c_double) -> c_double = cmath::c_double_utils::ln) -delegate!(fn log_radix(n: c_double) -> c_double = - cmath::c_double_utils::log_radix) -delegate!(fn ln1p(n: c_double) -> c_double = cmath::c_double_utils::ln1p) -delegate!(fn log10(n: c_double) -> c_double = cmath::c_double_utils::log10) -delegate!(fn log2(n: c_double) -> c_double = cmath::c_double_utils::log2) -delegate!(fn ilog_radix(n: c_double) -> c_int = - cmath::c_double_utils::ilog_radix) -delegate!(fn modf(n: c_double, iptr: &mut c_double) -> c_double = - cmath::c_double_utils::modf) -delegate!(fn pow(n: c_double, e: c_double) -> c_double = - cmath::c_double_utils::pow) -delegate!(fn round(n: c_double) -> c_double = cmath::c_double_utils::round) -delegate!(fn ldexp_radix(n: c_double, i: c_int) -> c_double = - cmath::c_double_utils::ldexp_radix) -delegate!(fn sin(n: c_double) -> c_double = cmath::c_double_utils::sin) -delegate!(fn sinh(n: c_double) -> c_double = cmath::c_double_utils::sinh) -delegate!(fn sqrt(n: c_double) -> c_double = cmath::c_double_utils::sqrt) -delegate!(fn tan(n: c_double) -> c_double = cmath::c_double_utils::tan) -delegate!(fn tanh(n: c_double) -> c_double = cmath::c_double_utils::tanh) -delegate!(fn tgamma(n: c_double) -> c_double = cmath::c_double_utils::tgamma) -delegate!(fn trunc(n: c_double) -> c_double = cmath::c_double_utils::trunc) -delegate!(fn j0(n: c_double) -> c_double = cmath::c_double_utils::j0) -delegate!(fn j1(n: c_double) -> c_double = cmath::c_double_utils::j1) -delegate!(fn jn(i: c_int, n: c_double) -> c_double = - cmath::c_double_utils::jn) -delegate!(fn y0(n: c_double) -> c_double = cmath::c_double_utils::y0) -delegate!(fn y1(n: c_double) -> c_double = cmath::c_double_utils::y1) -delegate!(fn yn(i: c_int, n: c_double) -> c_double = - cmath::c_double_utils::yn) +delegate!( + // intrinsics + fn abs(n: f64) -> f64 = intrinsics::fabsf64, + fn cos(n: f64) -> f64 = intrinsics::cosf64, + fn exp(n: f64) -> f64 = intrinsics::expf64, + fn exp2(n: f64) -> f64 = intrinsics::exp2f64, + fn floor(x: f64) -> f64 = intrinsics::floorf64, + fn ln(n: f64) -> f64 = intrinsics::logf64, + fn log10(n: f64) -> f64 = intrinsics::log10f64, + fn log2(n: f64) -> f64 = intrinsics::log2f64, + fn mul_add(a: f64, b: f64, c: f64) -> f64 = intrinsics::fmaf64, + fn pow(n: f64, e: f64) -> f64 = intrinsics::powf64, + fn powi(n: f64, e: c_int) -> f64 = intrinsics::powif64, + fn sin(n: f64) -> f64 = intrinsics::sinf64, + fn sqrt(n: f64) -> f64 = intrinsics::sqrtf64, + + // LLVM 3.3 required to use intrinsics for these four + fn ceil(n: c_double) -> c_double = c_double_utils::ceil, + fn trunc(n: c_double) -> c_double = c_double_utils::trunc, + /* + fn ceil(n: f64) -> f64 = intrinsics::ceilf64, + fn trunc(n: f64) -> f64 = intrinsics::truncf64, + fn rint(n: c_double) -> c_double = intrinsics::rintf64, + fn nearbyint(n: c_double) -> c_double = intrinsics::nearbyintf64, + */ + + // cmath + fn acos(n: c_double) -> c_double = c_double_utils::acos, + fn asin(n: c_double) -> c_double = c_double_utils::asin, + fn atan(n: c_double) -> c_double = c_double_utils::atan, + fn atan2(a: c_double, b: c_double) -> c_double = c_double_utils::atan2, + fn cbrt(n: c_double) -> c_double = c_double_utils::cbrt, + fn copysign(x: c_double, y: c_double) -> c_double = c_double_utils::copysign, + fn cosh(n: c_double) -> c_double = c_double_utils::cosh, + fn erf(n: c_double) -> c_double = c_double_utils::erf, + fn erfc(n: c_double) -> c_double = c_double_utils::erfc, + fn expm1(n: c_double) -> c_double = c_double_utils::expm1, + fn abs_sub(a: c_double, b: c_double) -> c_double = c_double_utils::abs_sub, + fn fmax(a: c_double, b: c_double) -> c_double = c_double_utils::fmax, + fn fmin(a: c_double, b: c_double) -> c_double = c_double_utils::fmin, + fn nextafter(x: c_double, y: c_double) -> c_double = c_double_utils::nextafter, + fn frexp(n: c_double, value: &mut c_int) -> c_double = c_double_utils::frexp, + fn hypot(x: c_double, y: c_double) -> c_double = c_double_utils::hypot, + fn ldexp(x: c_double, n: c_int) -> c_double = c_double_utils::ldexp, + fn lgamma(n: c_double, sign: &mut c_int) -> c_double = c_double_utils::lgamma, + fn log_radix(n: c_double) -> c_double = c_double_utils::log_radix, + fn ln1p(n: c_double) -> c_double = c_double_utils::ln1p, + fn ilog_radix(n: c_double) -> c_int = c_double_utils::ilog_radix, + fn modf(n: c_double, iptr: &mut c_double) -> c_double = c_double_utils::modf, + fn round(n: c_double) -> c_double = c_double_utils::round, + fn ldexp_radix(n: c_double, i: c_int) -> c_double = c_double_utils::ldexp_radix, + fn sinh(n: c_double) -> c_double = c_double_utils::sinh, + fn tan(n: c_double) -> c_double = c_double_utils::tan, + fn tanh(n: c_double) -> c_double = c_double_utils::tanh, + fn tgamma(n: c_double) -> c_double = c_double_utils::tgamma, + fn j0(n: c_double) -> c_double = c_double_utils::j0, + fn j1(n: c_double) -> c_double = c_double_utils::j1, + fn jn(i: c_int, n: c_double) -> c_double = c_double_utils::jn, + fn y0(n: c_double) -> c_double = c_double_utils::y0, + fn y1(n: c_double) -> c_double = c_double_utils::y1, + fn yn(i: c_int, n: c_double) -> c_double = c_double_utils::yn) // FIXME (#1433): obtain these in a different way @@ -218,9 +226,6 @@ pub fn is_finite(x: f64) -> bool { return !(is_NaN(x) || is_infinite(x)); } -/// Returns `x` rounded down -#[inline(always)] -pub fn floor(x: f64) -> f64 { unsafe { floorf64(x) } } // FIXME (#1999): add is_normal, is_subnormal, and fpclassify diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index 38111210c73..c9cda20640d 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -36,7 +36,7 @@ pub use f64::{acos, asin, atan2, cbrt, ceil, copysign, cosh, floor}; pub use f64::{erf, erfc, exp, expm1, exp2, abs_sub}; pub use f64::{mul_add, fmax, fmin, nextafter, frexp, hypot, ldexp}; pub use f64::{lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix}; -pub use f64::{modf, pow, round, sinh, tanh, tgamma, trunc}; +pub use f64::{modf, pow, powi, round, sinh, tanh, tgamma, trunc}; pub use f64::signbit; pub use f64::{j0, j1, jn, y0, y1, yn}; diff --git a/src/libcore/unstable/intrinsics.rs b/src/libcore/unstable/intrinsics.rs index ba96c6e5d30..a18ad173886 100644 --- a/src/libcore/unstable/intrinsics.rs +++ b/src/libcore/unstable/intrinsics.rs @@ -70,16 +70,28 @@ pub extern "rust-intrinsic" { pub fn powif32(a: f32, x: i32) -> f32; pub fn powif64(a: f64, x: i32) -> f64; + // the following kill the stack canary without + // `fixed_stack_segment`. This possibly only affects the f64 + // variants, but it's hard to be sure since it seems to only + // occur with fairly specific arguments. + #[fixed_stack_segment] pub fn sinf32(x: f32) -> f32; + #[fixed_stack_segment] pub fn sinf64(x: f64) -> f64; + #[fixed_stack_segment] pub fn cosf32(x: f32) -> f32; + #[fixed_stack_segment] pub fn cosf64(x: f64) -> f64; + #[fixed_stack_segment] pub fn powf32(a: f32, x: f32) -> f32; + #[fixed_stack_segment] pub fn powf64(a: f64, x: f64) -> f64; + #[fixed_stack_segment] pub fn expf32(x: f32) -> f32; + #[fixed_stack_segment] pub fn expf64(x: f64) -> f64; pub fn exp2f32(x: f32) -> f32; @@ -128,4 +140,3 @@ pub extern "rust-intrinsic" { pub fn bswap32(x: i32) -> i32; pub fn bswap64(x: i64) -> i64; } - diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 854ec585d5c..956ee3bf144 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -546,6 +546,7 @@ pub fn trans_intrinsic(ccx: @CrateContext, item: @ast::foreign_item, path: ast_map::path, substs: @param_substs, + attributes: &[ast::attribute], ref_id: Option<ast::node_id>) { debug!("trans_intrinsic(item.ident=%s)", *ccx.sess.str_of(item.ident)); @@ -561,6 +562,11 @@ pub fn trans_intrinsic(ccx: @CrateContext, Some(copy substs), Some(item.span)); + // Set the fixed stack segment flag if necessary. + if attr::attrs_contains_name(attributes, "fixed_stack_segment") { + set_fixed_stack_segment(fcx.llfn); + } + let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb; match *ccx.sess.str_of(item.ident) { ~"atomic_cxchg" => { diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 9d63ac854a9..52ca8ec49bb 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -212,7 +212,7 @@ pub fn monomorphic_fn(ccx: @CrateContext, } ast_map::node_foreign_item(i, _, _, _) => { let d = mk_lldecl(); - foreign::trans_intrinsic(ccx, d, i, pt, psubsts.get(), + foreign::trans_intrinsic(ccx, d, i, pt, psubsts.get(), i.attrs, ref_id); d } diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs index e633f307bc2..da06b36af67 100644 --- a/src/test/bench/shootout-nbody.rs +++ b/src/test/bench/shootout-nbody.rs @@ -1,6 +1,5 @@ use core::from_str::FromStr; use core::uint::range; -use core::unstable::intrinsics::sqrtf64; static PI: f64 = 3.141592653589793; static SOLAR_MASS: f64 = 4.0 * PI * PI; @@ -88,7 +87,7 @@ fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: i32) { d[2] = bodies[i].x[2] - bodies[j].x[2]; let d2 = d[0]*d[0] + d[1]*d[1] + d[2]*d[2]; - let mag = dt / (d2 * sqrtf64(d2)); + let mag = dt / (d2 * f64::sqrt(d2)); let a_mass = bodies[i].mass, b_mass = bodies[j].mass; bodies[i].v[0] -= d[0] * b_mass * mag; @@ -121,7 +120,7 @@ fn energy(bodies: &[Planet, ..N_BODIES]) -> f64 { for range(0, 3) |k| { d[k] = bodies[i].x[k] - bodies[j].x[k]; } - let dist = sqrtf64(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]); + let dist = f64::sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]); e -= bodies[i].mass * bodies[j].mass / dist; } } @@ -147,4 +146,3 @@ fn main() { println(fmt!("%.9f", energy(&bodies) as float)); } - diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index 00e255d890b..6840384ca7c 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -1,6 +1,5 @@ use core::from_str::FromStr; use core::iter::ExtendedMutableIter; -use core::unstable::intrinsics::sqrtf64; #[inline] fn A(i: i32, j: i32) -> i32 { @@ -49,6 +48,5 @@ fn main() { mult_AtAv(v, u, tmp); } - println(fmt!("%.9f", sqrtf64(dot(u,v) / dot(v,v)) as float)); + println(fmt!("%.9f", f64::sqrt(dot(u,v) / dot(v,v)) as float)); } - |
