From aefa9d43dcc6925454a258b8107e91462e60beac Mon Sep 17 00:00:00 2001 From: "Kaveh R. Ghazi" Date: Wed, 26 Mar 2008 15:04:44 +0000 Subject: [PATCH] builtins.c (expand_builtin_pow, [...]): Remove uses of dconst3, dconstsqrt2, dconstthird, dconste and/or dconst10. * builtins.c (expand_builtin_pow, fold_builtin_cabs, fold_builtin_sqrt, fold_builtin_cbrt, fold_builtin_logarithm, fold_builtin_hypot, fold_builtin_pow): Remove uses of dconst3, dconstsqrt2, dconstthird, dconste and/or dconst10. * config/i386/i386.c (ix86_emit_swsqrtsf): Likewise. * emit-rtl.c (dconst3, dconst10, dconstm2, dconstthird, dconstsqrt2, dconste): Delete. (init_emit_once): Likewise. Simplify initializing dconstm1. Constify variable. * real.c (get_real_const): New. * real.h (dconst3, dconst10, dconstm2, dconstthird, dconstsqrt2, dconste): Delete. (real_value_const, get_real_const): New. From-SVN: r133607 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/builtins.c | 39 ++++++++++++++++++++++++++------------- gcc/config/i386/i386.c | 2 +- gcc/emit-rtl.c | 24 ++++-------------------- gcc/real.c | 43 +++++++++++++++++++++++++++++++++++++++++++ gcc/real.h | 19 ++++++++++++------- 6 files changed, 102 insertions(+), 41 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d746b8..f8bbc30 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2008-03-26 Kaveh R. Ghazi + + * builtins.c (expand_builtin_pow, fold_builtin_cabs, + fold_builtin_sqrt, fold_builtin_cbrt, fold_builtin_logarithm, + fold_builtin_hypot, fold_builtin_pow): Remove uses of dconst3, + dconstsqrt2, dconstthird, dconste and/or dconst10. + * config/i386/i386.c (ix86_emit_swsqrtsf): Likewise. + * emit-rtl.c (dconst3, dconst10, dconstm2, dconstthird, + dconstsqrt2, dconste): Delete. + (init_emit_once): Likewise. Simplify initializing dconstm1. + Constify variable. + * real.c (get_real_const): New. + * real.h (dconst3, dconst10, dconstm2, dconstthird, + dconstsqrt2, dconste): Delete. + (real_value_const, get_real_const): New. + 2008-03-26 H.J. Lu * config/i386/cygming.h (BIGGEST_ALIGNMENT): Removed. diff --git a/gcc/builtins.c b/gcc/builtins.c index 31b9df2..d07fed8 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -2983,6 +2983,8 @@ expand_builtin_pow (tree exp, rtx target, rtx subtarget) && (tree_expr_nonnegative_p (arg0) || !HONOR_NANS (mode))) { + REAL_VALUE_TYPE dconst3; + real_from_integer (&dconst3, VOIDmode, 3, 0, 0); real_arithmetic (&c2, MULT_EXPR, &c, &dconst3); real_round (&c2, mode, &c2); n = real_to_integer (&c2); @@ -7458,7 +7460,8 @@ fold_builtin_cabs (tree arg, tree type, tree fndecl) && operand_equal_p (real, imag, OEP_PURE_SAME)) { const REAL_VALUE_TYPE sqrt2_trunc - = real_value_truncate (TYPE_MODE (type), dconstsqrt2); + = real_value_truncate (TYPE_MODE (type), + *get_real_const (rv_sqrt2)); STRIP_NOPS (real); return fold_build2 (MULT_EXPR, type, fold_build1 (ABS_EXPR, type, real), @@ -7541,7 +7544,7 @@ fold_builtin_sqrt (tree arg, tree type) tree tree_root; /* The inner root was either sqrt or cbrt. */ REAL_VALUE_TYPE dconstroot = - BUILTIN_SQRT_P (fcode) ? dconsthalf : dconstthird; + BUILTIN_SQRT_P (fcode) ? dconsthalf : *get_real_const (rv_third); /* Adjust for the outer root. */ SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); @@ -7594,7 +7597,7 @@ fold_builtin_cbrt (tree arg, tree type) { tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); const REAL_VALUE_TYPE third_trunc = - real_value_truncate (TYPE_MODE (type), dconstthird); + real_value_truncate (TYPE_MODE (type), *get_real_const (rv_third)); arg = fold_build2 (MULT_EXPR, type, CALL_EXPR_ARG (arg, 0), build_real (type, third_trunc)); @@ -7610,7 +7613,7 @@ fold_builtin_cbrt (tree arg, tree type) { tree arg0 = CALL_EXPR_ARG (arg, 0); tree tree_root; - REAL_VALUE_TYPE dconstroot = dconstthird; + REAL_VALUE_TYPE dconstroot = *get_real_const (rv_third); SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1); dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); @@ -7632,7 +7635,9 @@ fold_builtin_cbrt (tree arg, tree type) tree tree_root; REAL_VALUE_TYPE dconstroot; - real_arithmetic (&dconstroot, MULT_EXPR, &dconstthird, &dconstthird); + real_arithmetic (&dconstroot, MULT_EXPR, + get_real_const (rv_third), + get_real_const (rv_third)); dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot); tree_root = build_real (type, dconstroot); return build_call_expr (powfn, 2, arg0, tree_root); @@ -7651,7 +7656,8 @@ fold_builtin_cbrt (tree arg, tree type) { tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0); const REAL_VALUE_TYPE dconstroot - = real_value_truncate (TYPE_MODE (type), dconstthird); + = real_value_truncate (TYPE_MODE (type), + *get_real_const (rv_third)); tree narg01 = fold_build2 (MULT_EXPR, type, arg01, build_real (type, dconstroot)); return build_call_expr (powfn, 2, arg00, narg01); @@ -8199,7 +8205,7 @@ fold_builtin_logarithm (tree fndecl, tree arg, if (flag_unsafe_math_optimizations && func == mpfr_log) { const REAL_VALUE_TYPE e_truncated = - real_value_truncate (TYPE_MODE (type), dconste); + real_value_truncate (TYPE_MODE (type), *get_real_const (rv_e)); if (real_dconstp (arg, &e_truncated)) return build_real (type, dconst1); } @@ -8233,7 +8239,8 @@ fold_builtin_logarithm (tree fndecl, tree arg, CASE_FLT_FN (BUILT_IN_EXP): /* Prepare to do logN(exp(exponent) -> exponent*logN(e). */ x = build_real (type, - real_value_truncate (TYPE_MODE (type), dconste)); + real_value_truncate (TYPE_MODE (type), + *get_real_const (rv_e))); exponent = CALL_EXPR_ARG (arg, 0); break; CASE_FLT_FN (BUILT_IN_EXP2): @@ -8244,7 +8251,11 @@ fold_builtin_logarithm (tree fndecl, tree arg, CASE_FLT_FN (BUILT_IN_EXP10): CASE_FLT_FN (BUILT_IN_POW10): /* Prepare to do logN(exp10(exponent) -> exponent*logN(10). */ - x = build_real (type, dconst10); + { + REAL_VALUE_TYPE dconst10; + real_from_integer (&dconst10, VOIDmode, 10, 0, 0); + x = build_real (type, dconst10); + } exponent = CALL_EXPR_ARG (arg, 0); break; CASE_FLT_FN (BUILT_IN_SQRT): @@ -8256,7 +8267,7 @@ fold_builtin_logarithm (tree fndecl, tree arg, /* Prepare to do logN(cbrt(x) -> (1/3)*logN(x). */ x = CALL_EXPR_ARG (arg, 0); exponent = build_real (type, real_value_truncate (TYPE_MODE (type), - dconstthird)); + *get_real_const (rv_third))); break; CASE_FLT_FN (BUILT_IN_POW): /* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */ @@ -8316,7 +8327,7 @@ fold_builtin_hypot (tree fndecl, tree arg0, tree arg1, tree type) && operand_equal_p (arg0, arg1, OEP_PURE_SAME)) { const REAL_VALUE_TYPE sqrt2_trunc - = real_value_truncate (TYPE_MODE (type), dconstsqrt2); + = real_value_truncate (TYPE_MODE (type), *get_real_const (rv_sqrt2)); return fold_build2 (MULT_EXPR, type, fold_build1 (ABS_EXPR, type, arg0), build_real (type, sqrt2_trunc)); @@ -8382,7 +8393,8 @@ fold_builtin_pow (tree fndecl, tree arg0, tree arg1, tree type) if (flag_unsafe_math_optimizations) { const REAL_VALUE_TYPE dconstroot - = real_value_truncate (TYPE_MODE (type), dconstthird); + = real_value_truncate (TYPE_MODE (type), + *get_real_const (rv_third)); if (REAL_VALUES_EQUAL (c, dconstroot)) { @@ -8449,7 +8461,8 @@ fold_builtin_pow (tree fndecl, tree arg0, tree arg1, tree type) if (tree_expr_nonnegative_p (arg)) { const REAL_VALUE_TYPE dconstroot - = real_value_truncate (TYPE_MODE (type), dconstthird); + = real_value_truncate (TYPE_MODE (type), + *get_real_const (rv_third)); tree narg1 = fold_build2 (MULT_EXPR, type, arg1, build_real (type, dconstroot)); return build_call_expr (fndecl, 2, arg, narg1); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index e1d5aad..3dfb301 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -24311,7 +24311,7 @@ void ix86_emit_swsqrtsf (rtx res, rtx a, enum machine_mode mode, e2 = gen_reg_rtx (mode); e3 = gen_reg_rtx (mode); - real_arithmetic (&r, NEGATE_EXPR, &dconst3, NULL); + real_from_integer (&r, VOIDmode, -3, -1, 0); mthree = CONST_DOUBLE_FROM_REAL_VALUE (r, SFmode); real_arithmetic (&r, NEGATE_EXPR, &dconsthalf, NULL); diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 02680a9..77889cf 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -100,14 +100,8 @@ rtx const_true_rtx; REAL_VALUE_TYPE dconst0; REAL_VALUE_TYPE dconst1; REAL_VALUE_TYPE dconst2; -REAL_VALUE_TYPE dconst3; -REAL_VALUE_TYPE dconst10; REAL_VALUE_TYPE dconstm1; -REAL_VALUE_TYPE dconstm2; REAL_VALUE_TYPE dconsthalf; -REAL_VALUE_TYPE dconstthird; -REAL_VALUE_TYPE dconstsqrt2; -REAL_VALUE_TYPE dconste; /* Record fixed-point constant 0 and 1. */ FIXED_VALUE_TYPE fconst0[MAX_FCONST0]; @@ -5245,26 +5239,16 @@ init_emit_once (int line_numbers) REAL_VALUE_FROM_INT (dconst0, 0, 0, double_mode); REAL_VALUE_FROM_INT (dconst1, 1, 0, double_mode); REAL_VALUE_FROM_INT (dconst2, 2, 0, double_mode); - REAL_VALUE_FROM_INT (dconst3, 3, 0, double_mode); - REAL_VALUE_FROM_INT (dconst10, 10, 0, double_mode); - REAL_VALUE_FROM_INT (dconstm1, -1, -1, double_mode); - REAL_VALUE_FROM_INT (dconstm2, -2, -1, double_mode); + + dconstm1 = dconst1; + dconstm1.sign = 1; dconsthalf = dconst1; SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1); - real_arithmetic (&dconstthird, RDIV_EXPR, &dconst1, &dconst3); - - /* Initialize mathematical constants for constant folding builtins. - These constants need to be given to at least 160 bits precision. */ - real_from_string (&dconstsqrt2, - "1.4142135623730950488016887242096980785696718753769480731766797379907"); - real_from_string (&dconste, - "2.7182818284590452353602874713526624977572470936999595749669676277241"); - for (i = 0; i < (int) ARRAY_SIZE (const_tiny_rtx); i++) { - REAL_VALUE_TYPE *r = + const REAL_VALUE_TYPE *const r = (i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2); for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); diff --git a/gcc/real.c b/gcc/real.c index 38f18a8..ac3b7dc 100644 --- a/gcc/real.c +++ b/gcc/real.c @@ -2163,6 +2163,49 @@ times_pten (REAL_VALUE_TYPE *r, int exp) do_divide (r, r, &pten); } +/* Returns the special REAL_VALUE_TYPE enumerated by E. */ + +const REAL_VALUE_TYPE * +get_real_const (enum real_value_const e) +{ + static REAL_VALUE_TYPE value[rv_max]; + + gcc_assert (e < rv_max); + + /* Initialize mathematical constants for constant folding builtins. + These constants need to be given to at least 160 bits precision. */ + if (value[e].cl == rvc_zero) + switch (e) + { + case rv_e: + { + mpfr_t m; + mpfr_init2 (m, SIGNIFICAND_BITS); + mpfr_set_ui (m, 1, GMP_RNDN); + mpfr_exp (m, m, GMP_RNDN); + real_from_mpfr (&value[e], m, NULL_TREE, GMP_RNDN); + mpfr_clear (m); + } + break; + case rv_third: + real_arithmetic (&value[e], RDIV_EXPR, &dconst1, real_digit (3)); + break; + case rv_sqrt2: + { + mpfr_t m; + mpfr_init2 (m, SIGNIFICAND_BITS); + mpfr_sqrt_ui (m, 2, GMP_RNDN); + real_from_mpfr (&value[e], m, NULL_TREE, GMP_RNDN); + mpfr_clear (m); + } + break; + default: + gcc_unreachable(); + } + + return &value[e]; +} + /* Fills R with +Inf. */ void diff --git a/gcc/real.h b/gcc/real.h index 6cf0d1f..9809004 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -374,19 +374,24 @@ extern void real_ldexp (REAL_VALUE_TYPE *, const REAL_VALUE_TYPE *, int); /* **** End of software floating point emulator interface macros **** */ -/* Constant real values 0, 1, 2, 3, 10, -1, -2, 0.5 and 1/3. */ +/* Constant real values 0, 1, 2, -1 and 0.5. */ extern REAL_VALUE_TYPE dconst0; extern REAL_VALUE_TYPE dconst1; extern REAL_VALUE_TYPE dconst2; -extern REAL_VALUE_TYPE dconst3; -extern REAL_VALUE_TYPE dconst10; extern REAL_VALUE_TYPE dconstm1; -extern REAL_VALUE_TYPE dconstm2; extern REAL_VALUE_TYPE dconsthalf; -extern REAL_VALUE_TYPE dconstthird; -extern REAL_VALUE_TYPE dconstsqrt2; -extern REAL_VALUE_TYPE dconste; + +/* Enumerate the special constant values we need. */ +enum real_value_const { + rv_e, + rv_third, + rv_sqrt2, + rv_max +}; + +/* Function to return a real value special constant. */ +extern const REAL_VALUE_TYPE * get_real_const (enum real_value_const); /* Function to return a real value (not a tree node) from a given integer constant. */ -- 2.7.4