This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: make real.h constants more consistent
Updated and regression tested after tuples merge.
2008/7/25 Manuel López-Ibáñez <lopezibanez@gmail.com>:
> This is a small patch that simply hides the implementation of real
> constants for e, 1/3, sqrt(2) from outside real.[ch]. I think this
> makes the code cleaner (each constant has its own function, no special
> enumeration constants needed, no switch needed) and easier to read
> (dconst_e is easier and shorter than *get_real_const (rv_e)).
>
> Bootstrapped and regression tested with --enable-languages=all on
> 86_64-unknown-linux-gnu.
>
> OK for trunk?
>
>
> 2008-07-25 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
>
> * real.h (dconst_e, dconst_third, dconst_sqrt2, get_real_const_e,
> get_real_const_third, get_real_const_sqrt2): Declare.
> (enum real_value_const): Delete.
> (get_real_const): Delete.
> * real.c (get_real_const): Delete.
> (get_real_const_e): Define.
> (get_real_const_third): Define.
> (get_real_const_sqrt2): Define.
> * builtins.c: Update all callers.
>
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c (revision 138207)
+++ gcc/builtins.c (working copy)
@@ -7492,12 +7492,11 @@ fold_builtin_cabs (tree arg, tree type,
/* cabs(x+xi) -> fabs(x)*sqrt(2). */
if (flag_unsafe_math_optimizations
&& operand_equal_p (real, imag, OEP_PURE_SAME))
{
const REAL_VALUE_TYPE sqrt2_trunc
- = real_value_truncate (TYPE_MODE (type),
- *get_real_const (rv_sqrt2));
+ = real_value_truncate (TYPE_MODE (type), dconst_sqrt2);
STRIP_NOPS (real);
return fold_build2 (MULT_EXPR, type,
fold_build1 (ABS_EXPR, type, real),
build_real (type, sqrt2_trunc));
}
@@ -7576,11 +7575,11 @@ fold_builtin_sqrt (tree arg, tree type)
{
tree arg0 = CALL_EXPR_ARG (arg, 0);
tree tree_root;
/* The inner root was either sqrt or cbrt. */
REAL_VALUE_TYPE dconstroot =
- BUILTIN_SQRT_P (fcode) ? dconsthalf : *get_real_const (rv_third);
+ BUILTIN_SQRT_P (fcode) ? dconsthalf : dconst_third;
/* Adjust for the outer root. */
SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
tree_root = build_real (type, dconstroot);
@@ -7629,11 +7628,11 @@ fold_builtin_cbrt (tree arg, tree type)
/* Optimize cbrt(expN(x)) -> expN(x/3). */
if (BUILTIN_EXPONENT_P (fcode))
{
tree expfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
const REAL_VALUE_TYPE third_trunc =
- real_value_truncate (TYPE_MODE (type), *get_real_const (rv_third));
+ real_value_truncate (TYPE_MODE (type), dconst_third);
arg = fold_build2 (MULT_EXPR, type,
CALL_EXPR_ARG (arg, 0),
build_real (type, third_trunc));
return build_call_expr (expfn, 1, arg);
}
@@ -7645,11 +7644,11 @@ fold_builtin_cbrt (tree arg, tree type)
if (powfn)
{
tree arg0 = CALL_EXPR_ARG (arg, 0);
tree tree_root;
- REAL_VALUE_TYPE dconstroot = *get_real_const (rv_third);
+ REAL_VALUE_TYPE dconstroot = dconst_third;
SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
tree_root = build_real (type, dconstroot);
return build_call_expr (powfn, 2, arg0, tree_root);
@@ -7668,12 +7667,11 @@ fold_builtin_cbrt (tree arg, tree type)
{
tree tree_root;
REAL_VALUE_TYPE dconstroot;
real_arithmetic (&dconstroot, MULT_EXPR,
- get_real_const (rv_third),
- get_real_const (rv_third));
+ &dconst_third, &dconst_third);
dconstroot = real_value_truncate (TYPE_MODE (type), dconstroot);
tree_root = build_real (type, dconstroot);
return build_call_expr (powfn, 2, arg0, tree_root);
}
}
@@ -7688,12 +7686,11 @@ fold_builtin_cbrt (tree arg, tree type)
tree arg01 = CALL_EXPR_ARG (arg, 1);
if (tree_expr_nonnegative_p (arg00))
{
tree powfn = TREE_OPERAND (CALL_EXPR_FN (arg), 0);
const REAL_VALUE_TYPE dconstroot
- = real_value_truncate (TYPE_MODE (type),
- *get_real_const (rv_third));
+ = real_value_truncate (TYPE_MODE (type), dconst_third);
tree narg01 = fold_build2 (MULT_EXPR, type, arg01,
build_real (type, dconstroot));
return build_call_expr (powfn, 2, arg00, narg01);
}
}
@@ -8237,11 +8234,11 @@ fold_builtin_logarithm (tree fndecl, tre
instead we'll look for 'e' truncated to MODE. So only do
this if flag_unsafe_math_optimizations is set. */
if (flag_unsafe_math_optimizations && func == mpfr_log)
{
const REAL_VALUE_TYPE e_truncated =
- real_value_truncate (TYPE_MODE (type), *get_real_const (rv_e));
+ real_value_truncate (TYPE_MODE (type), dconst_e);
if (real_dconstp (arg, &e_truncated))
return build_real (type, dconst1);
}
/* Calculate the result when the argument is a constant. */
@@ -8271,12 +8268,11 @@ fold_builtin_logarithm (tree fndecl, tre
switch (fcode)
{
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),
- *get_real_const (rv_e)));
+ real_value_truncate (TYPE_MODE (type), dconst_e));
exponent = CALL_EXPR_ARG (arg, 0);
break;
CASE_FLT_FN (BUILT_IN_EXP2):
/* Prepare to do logN(exp2(exponent) -> exponent*logN(2). */
x = build_real (type, dconst2);
@@ -8299,11 +8295,11 @@ fold_builtin_logarithm (tree fndecl, tre
break;
CASE_FLT_FN (BUILT_IN_CBRT):
/* 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),
- *get_real_const (rv_third)));
+ dconst_third));
break;
CASE_FLT_FN (BUILT_IN_POW):
/* Prepare to do logN(pow(x,exponent) -> exponent*logN(x). */
x = CALL_EXPR_ARG (arg, 0);
exponent = CALL_EXPR_ARG (arg, 1);
@@ -8359,11 +8355,11 @@ fold_builtin_hypot (tree fndecl, tree ar
/* hypot(x,x) -> fabs(x)*sqrt(2). */
if (flag_unsafe_math_optimizations
&& operand_equal_p (arg0, arg1, OEP_PURE_SAME))
{
const REAL_VALUE_TYPE sqrt2_trunc
- = real_value_truncate (TYPE_MODE (type), *get_real_const (rv_sqrt2));
+ = real_value_truncate (TYPE_MODE (type), dconst_sqrt2);
return fold_build2 (MULT_EXPR, type,
fold_build1 (ABS_EXPR, type, arg0),
build_real (type, sqrt2_trunc));
}
@@ -8425,12 +8421,11 @@ fold_builtin_pow (tree fndecl, tree arg0
/* Optimize pow(x,1.0/3.0) = cbrt(x). */
if (flag_unsafe_math_optimizations)
{
const REAL_VALUE_TYPE dconstroot
- = real_value_truncate (TYPE_MODE (type),
- *get_real_const (rv_third));
+ = real_value_truncate (TYPE_MODE (type), dconst_third);
if (REAL_VALUES_EQUAL (c, dconstroot))
{
tree cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
if (cbrtfn != NULL_TREE)
@@ -8493,12 +8488,11 @@ fold_builtin_pow (tree fndecl, tree arg0
{
tree arg = CALL_EXPR_ARG (arg0, 0);
if (tree_expr_nonnegative_p (arg))
{
const REAL_VALUE_TYPE dconstroot
- = real_value_truncate (TYPE_MODE (type),
- *get_real_const (rv_third));
+ = real_value_truncate (TYPE_MODE (type), dconst_third);
tree narg1 = fold_build2 (MULT_EXPR, type, arg1,
build_real (type, dconstroot));
return build_call_expr (fndecl, 2, arg, narg1);
}
}
Index: gcc/real.c
===================================================================
--- gcc/real.c (revision 138207)
+++ gcc/real.c (working copy)
@@ -2179,51 +2179,65 @@ times_pten (REAL_VALUE_TYPE *r, int exp)
if (negative)
do_divide (r, r, &pten);
}
-/* Returns the special REAL_VALUE_TYPE enumerated by E. */
+/* Returns the special REAL_VALUE_TYPE corresponding to 'e'. */
const REAL_VALUE_TYPE *
-get_real_const (enum real_value_const e)
+get_real_const_e (void)
{
- static REAL_VALUE_TYPE value[rv_max];
+ static REAL_VALUE_TYPE value;
- 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.cl == rvc_zero)
+ {
+ 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, m, NULL_TREE, GMP_RNDN);
+ mpfr_clear (m);
+ }
+ return &value;
+}
+
+/* Returns the special REAL_VALUE_TYPE corresponding to 1/3. */
+
+const REAL_VALUE_TYPE *
+get_real_const_third (void)
+{
+ static REAL_VALUE_TYPE value;
/* 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)
+ if (value.cl == rvc_zero)
{
- 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();
+ real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
}
+ return &value;
+}
+
+/* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2). */
- return &value[e];
+const REAL_VALUE_TYPE *
+get_real_const_sqrt2 (void)
+{
+ static REAL_VALUE_TYPE value;
+
+ /* Initialize mathematical constants for constant folding builtins.
+ These constants need to be given to at least 160 bits precision. */
+ if (value.cl == rvc_zero)
+ {
+ mpfr_t m;
+ mpfr_init2 (m, SIGNIFICAND_BITS);
+ mpfr_sqrt_ui (m, 2, GMP_RNDN);
+ real_from_mpfr (&value, m, NULL_TREE, GMP_RNDN);
+ mpfr_clear (m);
+ }
+ return &value;
}
/* Fills R with +Inf. */
void
Index: gcc/real.h
===================================================================
--- gcc/real.h (revision 138207)
+++ gcc/real.h (working copy)
@@ -379,21 +379,22 @@ extern void real_ldexp (REAL_VALUE_TYPE
extern REAL_VALUE_TYPE dconst0;
extern REAL_VALUE_TYPE dconst1;
extern REAL_VALUE_TYPE dconst2;
extern REAL_VALUE_TYPE dconstm1;
extern REAL_VALUE_TYPE dconsthalf;
+#define dconst_e (*get_real_const_e ())
+#define dconst_third (*get_real_const_third ())
+#define dconst_sqrt2 (*get_real_const_sqrt2 ())
-/* Enumerate the special constant values we need. */
-enum real_value_const {
- rv_e,
- rv_third,
- rv_sqrt2,
- rv_max
-};
+/* Function to return the real value special constant 'e'. */
+extern const REAL_VALUE_TYPE * get_real_const_e (void);
-/* Function to return a real value special constant. */
-extern const REAL_VALUE_TYPE * get_real_const (enum real_value_const);
+/* Returns the special REAL_VALUE_TYPE corresponding to 1/3. */
+extern const REAL_VALUE_TYPE * get_real_const_third (void);
+
+/* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2). */
+extern const REAL_VALUE_TYPE * get_real_const_sqrt2 (void);
/* Function to return a real value (not a tree node)
from a given integer constant. */
REAL_VALUE_TYPE real_value_from_int_cst (const_tree, const_tree);