From 7519793938af3bb5e74594a45da10bc04bd33f20 Mon Sep 17 00:00:00 2001 From: Scott Violet Date: Thu, 1 Dec 2022 09:02:12 -0800 Subject: [PATCH] [reland] adds the ability for v8 to use sin/cos from libm This differs from the patch that landed in so far as the libm target is only defined if v8_use_libm_trig_functions is defined. Doing this ensures building the 'all' target only builds libm is appropriate. You can diff between patchset 1 and 2 to see the change. This is controlled by a gn arg, which defaults to true for clang builds. I'm limiting to clang builds as the macros for determining endian type are currently clang specific. My understanding is that chrome only uses clang. I can update the endian macros if necessary for other targets. Bug=v8:13477 Change-Id: I59cd450facc9fcb8987fe56e8cfc1c13522e1f6d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4070924 Commit-Queue: Hannes Payer Auto-Submit: Scott Violet Reviewed-by: Hannes Payer Cr-Commit-Position: refs/heads/main@{#84620} --- BUILD.gn | 31 ++++ gni/v8.gni | 3 + src/base/DEPS | 6 + src/base/ieee754.cc | 21 ++- src/base/ieee754.h | 20 +++ .../src/sysdeps/ieee754/dbl-64/branred.c | 2 +- .../src/sysdeps/ieee754/dbl-64/branred.h | 2 +- .../glibc/src/sysdeps/ieee754/dbl-64/dla.h | 148 ------------------ .../glibc/src/sysdeps/ieee754/dbl-64/endian.h | 21 +++ .../glibc/src/sysdeps/ieee754/dbl-64/s_sin.c | 30 +--- .../src/sysdeps/ieee754/dbl-64/sincostab.c | 4 +- .../glibc/src/sysdeps/ieee754/dbl-64/trig.h | 14 ++ 12 files changed, 126 insertions(+), 176 deletions(-) create mode 100644 third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h create mode 100644 third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h diff --git a/BUILD.gn b/BUILD.gn index 0e09b63f5d..11ed823a12 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1063,6 +1063,9 @@ config("features") { if (v8_use_zlib) { defines += [ "V8_USE_ZLIB" ] } + if (v8_use_libm_trig_functions) { + defines += [ "V8_USE_LIBM_TRIG_FUNCTIONS" ] + } if (v8_value_deserializer_hard_fail) { defines += [ "V8_VALUE_DESERIALIZER_HARD_FAIL" ] } @@ -5676,9 +5679,37 @@ v8_component("v8_libbase") { [ "//build/config/clang:llvm-symbolizer_data($host_toolchain)" ] } + if (v8_use_libm_trig_functions) { + deps += [ ":libm" ] + } + # TODO(infra): Add support for qnx, freebsd, openbsd, netbsd, and solaris. } +if (v8_use_libm_trig_functions) { + source_set("libm") { + sources = [ + "third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/mydefs.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h", + "third_party/glibc/src/sysdeps/ieee754/dbl-64/usncs.h", + ] + configs += [ + "//build/config/compiler:no_chromium_code", + ] + configs -= [ "//build/config/compiler:chromium_code" ] + if (!is_debug) { + # Build code using -O3, see: crbug.com/1084371. + configs += [ "//build/config/compiler:optimize_speed" ] + } + } +} + v8_component("v8_libplatform") { sources = [ "//base/trace_event/common/trace_event_common.h", diff --git a/gni/v8.gni b/gni/v8.gni index 3f093597fa..f297eb379b 100644 --- a/gni/v8.gni +++ b/gni/v8.gni @@ -107,6 +107,9 @@ declare_args() { # Enable advanced BigInt algorithms, costing about 10-30 KB binary size # depending on platform. Disabled on Android to save binary size. v8_advanced_bigint_algorithms = !is_android + + # TODO: macros for determining endian type are clang specific. + v8_use_libm_trig_functions = is_clang } if (v8_use_external_startup_data == "") { diff --git a/src/base/DEPS b/src/base/DEPS index a9c31c20d6..3cead70516 100644 --- a/src/base/DEPS +++ b/src/base/DEPS @@ -5,3 +5,9 @@ include_rules = [ "-src", "+src/base", ] + +specific_include_rules = { + "ieee754.h": [ + "+third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h" + ], +} diff --git a/src/base/ieee754.cc b/src/base/ieee754.cc index 73672001cf..f03044611a 100644 --- a/src/base/ieee754.cc +++ b/src/base/ieee754.cc @@ -105,10 +105,12 @@ namespace { } while (false) int32_t __ieee754_rem_pio2(double x, double* y) V8_WARN_UNUSED_RESULT; -double __kernel_cos(double x, double y) V8_WARN_UNUSED_RESULT; int __kernel_rem_pio2(double* x, double* y, int e0, int nx, int prec, const int32_t* ipio2) V8_WARN_UNUSED_RESULT; +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) +double __kernel_cos(double x, double y) V8_WARN_UNUSED_RESULT; double __kernel_sin(double x, double y, int iy) V8_WARN_UNUSED_RESULT; +#endif /* __ieee754_rem_pio2(x,y) * @@ -269,6 +271,7 @@ int32_t __ieee754_rem_pio2(double x, double *y) { return n; } +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) /* __kernel_cos( x, y ) * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 * Input x is assumed to be bounded by ~pi/4 in magnitude. @@ -334,6 +337,7 @@ V8_INLINE double __kernel_cos(double x, double y) { return a - (iz - (z * r - x * y)); } } +#endif /* __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) * double x[],y[]; int e0,nx,prec; int ipio2[]; @@ -643,6 +647,7 @@ recompute: return n & 7; } +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) /* __kernel_sin( x, y, iy) * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854 * Input x is assumed to be bounded by ~pi/4 in magnitude. @@ -696,6 +701,7 @@ V8_INLINE double __kernel_sin(double x, double y, int iy) { return x - ((z * (half * y - v * r) - y) - v * S1); } } +#endif /* __kernel_tan( x, y, k ) * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 @@ -1318,6 +1324,7 @@ double atan2(double y, double x) { } } +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) /* cos(x) * Return cosine function of x. * @@ -1377,6 +1384,7 @@ double cos(double x) { } } } +#endif /* exp(x) * Returns the exponential of x. @@ -2410,6 +2418,7 @@ double cbrt(double x) { return (t); } +#if !defined(V8_USE_LIBM_TRIG_FUNCTIONS) /* sin(x) * Return sine function of x. * @@ -2469,6 +2478,7 @@ double sin(double x) { } } } +#endif /* tan(x) * Return tangent function of x. @@ -3015,6 +3025,15 @@ double tanh(double x) { #undef SET_HIGH_WORD #undef SET_LOW_WORD +#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && defined(BUILDING_V8_BASE_SHARED) +double sin(double x) { + return glibc_sin(x); +} +double cos(double x) { + return glibc_cos(x); +} +#endif + } // namespace ieee754 } // namespace base } // namespace v8 diff --git a/src/base/ieee754.h b/src/base/ieee754.h index f2b3a3eb58..53417179e6 100644 --- a/src/base/ieee754.h +++ b/src/base/ieee754.h @@ -7,6 +7,10 @@ #include "src/base/base-export.h" +#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) +#include "third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h" // nogncheck +#endif + namespace v8 { namespace base { namespace ieee754 { @@ -34,7 +38,15 @@ V8_BASE_EXPORT double atan(double x); V8_BASE_EXPORT double atan2(double y, double x); // Returns the cosine of |x|, where |x| is given in radians. +#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && \ + !defined(BUILDING_V8_BASE_SHARED) && \ + !defined(USING_V8_BASE_SHARED) +inline double cos(double x) { + return glibc_cos(x); +} +#else V8_BASE_EXPORT double cos(double x); +#endif // Returns the base-e exponential of |x|. V8_BASE_EXPORT double exp(double x); @@ -68,8 +80,16 @@ V8_BASE_EXPORT double expm1(double x); // behaviour is preserved for compatibility reasons. V8_BASE_EXPORT double pow(double x, double y); +#if defined(V8_USE_LIBM_TRIG_FUNCTIONS) && \ + !defined(BUILDING_V8_BASE_SHARED) && \ + !defined(USING_V8_BASE_SHARED) +inline double sin(double x) { + return glibc_sin(x); +} +#else // Returns the sine of |x|, where |x| is given in radians. V8_BASE_EXPORT double sin(double x); +#endif // Returns the tangent of |x|, where |x| is given in radians. V8_BASE_EXPORT double tan(double x); diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c b/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c index 8af4890d9a..3abfa1e0b4 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.c @@ -34,8 +34,8 @@ #include "endian.h" #include "mydefs.h" #include "branred.h" + #include -#include #ifndef SECTION # define SECTION diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h b/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h index 1107f9becb..d113c8530d 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/branred.h @@ -25,7 +25,7 @@ #ifndef BRANRED_H #define BRANRED_H -#include +#include "dla.h" #ifdef BIG_ENDI static const mynumber diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h b/third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h index d6630e309b..db4c4d81de 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/dla.h @@ -16,8 +16,6 @@ * along with this program; if not, see . */ -#include - /***********************************************************************/ /*MODULE_NAME: dla.h */ /* */ @@ -38,149 +36,3 @@ /* CN = 1+2**27 = '41a0000002000000' IEEE double format. Use it to split a double for better accuracy. */ #define CN 134217729.0 - - -/* Exact addition of two single-length floating point numbers, Dekker. */ -/* The macro produces a double-length number (z,zz) that satisfies */ -/* z+zz = x+y exactly. */ - -#define EADD(x,y,z,zz) \ - z=(x)+(y); zz=(fabs(x)>fabs(y)) ? (((x)-(z))+(y)) : (((y)-(z))+(x)); - - -/* Exact subtraction of two single-length floating point numbers, Dekker. */ -/* The macro produces a double-length number (z,zz) that satisfies */ -/* z+zz = x-y exactly. */ - -#define ESUB(x,y,z,zz) \ - z=(x)-(y); zz=(fabs(x)>fabs(y)) ? (((x)-(z))-(y)) : ((x)-((y)+(z))); - - -#ifdef __FP_FAST_FMA -# define DLA_FMS(x, y, z) __builtin_fma (x, y, -(z)) -#endif - -/* Exact multiplication of two single-length floating point numbers, */ -/* Veltkamp. The macro produces a double-length number (z,zz) that */ -/* satisfies z+zz = x*y exactly. p,hx,tx,hy,ty are temporary */ -/* storage variables of type double. */ - -#ifdef DLA_FMS -# define EMULV(x, y, z, zz) \ - z = x * y; zz = DLA_FMS (x, y, z); -#else -# define EMULV(x, y, z, zz) \ - ({ __typeof__ (x) __p, hx, tx, hy, ty; \ - __p = CN * (x); hx = ((x) - __p) + __p; tx = (x) - hx; \ - __p = CN * (y); hy = ((y) - __p) + __p; ty = (y) - hy; \ - z = (x) * (y); zz = (((hx * hy - z) + hx * ty) + tx * hy) + tx * ty; \ - }) -#endif - - -/* Exact multiplication of two single-length floating point numbers, Dekker. */ -/* The macro produces a nearly double-length number (z,zz) (see Dekker) */ -/* that satisfies z+zz = x*y exactly. p,hx,tx,hy,ty,q are temporary */ -/* storage variables of type double. */ - -#ifdef DLA_FMS -# define MUL12(x, y, z, zz) \ - EMULV(x, y, z, zz) -#else -# define MUL12(x, y, z, zz) \ - ({ __typeof__ (x) __p, hx, tx, hy, ty, __q; \ - __p=CN*(x); hx=((x)-__p)+__p; tx=(x)-hx; \ - __p=CN*(y); hy=((y)-__p)+__p; ty=(y)-hy; \ - __p=hx*hy; __q=hx*ty+tx*hy; z=__p+__q; zz=((__p-z)+__q)+tx*ty; \ - }) -#endif - - -/* Double-length addition, Dekker. The macro produces a double-length */ -/* number (z,zz) which satisfies approximately z+zz = x+xx + y+yy. */ -/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */ -/* are assumed to be double-length numbers. r,s are temporary */ -/* storage variables of type double. */ - -#define ADD2(x, xx, y, yy, z, zz, r, s) \ - r = (x) + (y); s = (fabs (x) > fabs (y)) ? \ - (((((x) - r) + (y)) + (yy)) + (xx)) : \ - (((((y) - r) + (x)) + (xx)) + (yy)); \ - z = r + s; zz = (r - z) + s; - - -/* Double-length subtraction, Dekker. The macro produces a double-length */ -/* number (z,zz) which satisfies approximately z+zz = x+xx - (y+yy). */ -/* An error bound: (abs(x+xx)+abs(y+yy))*4.94e-32. (x,xx), (y,yy) */ -/* are assumed to be double-length numbers. r,s are temporary */ -/* storage variables of type double. */ - -#define SUB2(x, xx, y, yy, z, zz, r, s) \ - r = (x) - (y); s = (fabs (x) > fabs (y)) ? \ - (((((x) - r) - (y)) - (yy)) + (xx)) : \ - ((((x) - ((y) + r)) + (xx)) - (yy)); \ - z = r + s; zz = (r - z) + s; - - -/* Double-length multiplication, Dekker. The macro produces a double-length */ -/* number (z,zz) which satisfies approximately z+zz = (x+xx)*(y+yy). */ -/* An error bound: abs((x+xx)*(y+yy))*1.24e-31. (x,xx), (y,yy) */ -/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc are */ -/* temporary storage variables of type double. */ - -#define MUL2(x, xx, y, yy, z, zz, c, cc) \ - MUL12 (x, y, c, cc); \ - cc = ((x) * (yy) + (xx) * (y)) + cc; z = c + cc; zz = (c - z) + cc; - - -/* Double-length division, Dekker. The macro produces a double-length */ -/* number (z,zz) which satisfies approximately z+zz = (x+xx)/(y+yy). */ -/* An error bound: abs((x+xx)/(y+yy))*1.50e-31. (x,xx), (y,yy) */ -/* are assumed to be double-length numbers. p,hx,tx,hy,ty,q,c,cc,u,uu */ -/* are temporary storage variables of type double. */ - -#define DIV2(x, xx, y, yy, z, zz, c, cc, u, uu) \ - c=(x)/(y); MUL12(c,y,u,uu); \ - cc=(((((x)-u)-uu)+(xx))-c*(yy))/(y); z=c+cc; zz=(c-z)+cc; - - -/* Double-length addition, slower but more accurate than ADD2. */ -/* The macro produces a double-length */ -/* number (z,zz) which satisfies approximately z+zz = (x+xx)+(y+yy). */ -/* An error bound: abs(x+xx + y+yy)*1.50e-31. (x,xx), (y,yy) */ -/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */ -/* are temporary storage variables of type double. */ - -#define ADD2A(x, xx, y, yy, z, zz, r, rr, s, ss, u, uu, w) \ - r = (x) + (y); \ - if (fabs (x) > fabs (y)) { rr = ((x) - r) + (y); s = (rr + (yy)) + (xx); } \ - else { rr = ((y) - r) + (x); s = (rr + (xx)) + (yy); } \ - if (rr != 0.0) { \ - z = r + s; zz = (r - z) + s; } \ - else { \ - ss = (fabs (xx) > fabs (yy)) ? (((xx) - s) + (yy)) : (((yy) - s) + (xx));\ - u = r + s; \ - uu = (fabs (r) > fabs (s)) ? ((r - u) + s) : ((s - u) + r); \ - w = uu + ss; z = u + w; \ - zz = (fabs (u) > fabs (w)) ? ((u - z) + w) : ((w - z) + u); } - - -/* Double-length subtraction, slower but more accurate than SUB2. */ -/* The macro produces a double-length */ -/* number (z,zz) which satisfies approximately z+zz = (x+xx)-(y+yy). */ -/* An error bound: abs(x+xx - (y+yy))*1.50e-31. (x,xx), (y,yy) */ -/* are assumed to be double-length numbers. r,rr,s,ss,u,uu,w */ -/* are temporary storage variables of type double. */ - -#define SUB2A(x, xx, y, yy, z, zz, r, rr, s, ss, u, uu, w) \ - r = (x) - (y); \ - if (fabs (x) > fabs (y)) { rr = ((x) - r) - (y); s = (rr - (yy)) + (xx); } \ - else { rr = (x) - ((y) + r); s = (rr + (xx)) - (yy); } \ - if (rr != 0.0) { \ - z = r + s; zz = (r - z) + s; } \ - else { \ - ss = (fabs (xx) > fabs (yy)) ? (((xx) - s) - (yy)) : ((xx) - ((yy) + s)); \ - u = r + s; \ - uu = (fabs (r) > fabs (s)) ? ((r - u) + s) : ((s - u) + r); \ - w = uu + ss; z = u + w; \ - zz = (fabs (u) > fabs (w)) ? ((u - z) + w) : ((w - z) + u); } diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h b/third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h new file mode 100644 index 0000000000..d97daca4df --- /dev/null +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/endian.h @@ -0,0 +1,21 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// glibc has a couple of endian.h files. This defines the macros expected by +// the code in this directory using macros defined by clang. +#if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define BIG_ENDI 1 +#undef LITTLE_ENDI +#define HIGH_HALF 0 +#define LOW_HALF 1 +#elif (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#undef BIG_ENDI +#define LITTLE_ENDI 1 +#define HIGH_HALF 1 +#define LOW_HALF 0 +#else +#error +#endif diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c b/third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c index 8e65f7cc00..a7beb04f97 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/s_sin.c @@ -39,11 +39,11 @@ #include "mydefs.h" #include "usncs.h" #include -#include -#include -#include -#include -#include + +#define attribute_hidden +#if !defined(__always_inline) +#define __always_inline +#endif /* Helper macros to compute sin of the input values. */ #define POLYNOMIAL2(xx) ((((s5 * (xx) + s4) * (xx) + s3) * (xx) + s2) * (xx)) @@ -197,21 +197,18 @@ do_sincos (double a, double da, int4 n) #ifndef IN_SINCOS double SECTION -__sin (double x) +glibc_sin (double x) { double t, a, da; mynumber u; int4 k, m, n; double retval = 0; - SET_RESTORE_ROUND_53BIT (FE_TONEAREST); - u.x = x; m = u.i[HIGH_HALF]; k = 0x7fffffff & m; /* no sign */ if (k < 0x3e500000) /* if x->0 =>sin(x)=x */ { - math_check_force_underflow (x); retval = x; } /*--------------------------- 2^-26<|x|< 0.855469---------------------- */ @@ -245,8 +242,6 @@ __sin (double x) /*--------------------- |x| > 2^1024 ----------------------------------*/ else { - if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) - __set_errno (EDOM); retval = x / x; } @@ -261,7 +256,7 @@ __sin (double x) double SECTION -__cos (double x) +glibc_cos (double x) { double y, a, da; mynumber u; @@ -269,8 +264,6 @@ __cos (double x) double retval = 0; - SET_RESTORE_ROUND_53BIT (FE_TONEAREST); - u.x = x; m = u.i[HIGH_HALF]; k = 0x7fffffff & m; @@ -310,19 +303,10 @@ __cos (double x) else { - if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) - __set_errno (EDOM); retval = x / x; /* |x| > 2^1024 */ } return retval; } -#ifndef __cos -libm_alias_double (__cos, cos) -#endif -#ifndef __sin -libm_alias_double (__sin, sin) -#endif - #endif diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c b/third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c index d88e55c6de..8ae29e2f02 100644 --- a/third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/sincostab.c @@ -16,8 +16,8 @@ * along with this program; if not, see . */ -#include -#include +#include "mydefs.h" +#include "endian.h" /****************************************************************/ /* TABLES FOR THE usin() and ucos() FUNCTION */ diff --git a/third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h b/third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h new file mode 100644 index 0000000000..e4dac73048 --- /dev/null +++ b/third_party/glibc/src/sysdeps/ieee754/dbl-64/trig.h @@ -0,0 +1,14 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifdef __cplusplus +extern "C" { +#endif + +double glibc_cos(double x); +double glibc_sin(double x); + +#ifdef __cplusplus +} // extern "C" +#endif