diff mbox

Cache reals for 1/4, 1/6 and 1/9

Message ID 87twqay9vr.fsf@e105548-lin.cambridge.arm.com
State New
Headers show

Commit Message

Richard Sandiford Oct. 1, 2015, 1:51 p.m. UTC
We have a global 1/2 and a cached 1/3, but recalculate 1/4, 1/6 and 1/9
each time we need them.  That seems a bit arbitrary and makes the folding
code more noisy (especially once it's moved to match.pd).

This patch caches the other three constants too.  Bootstrapped &
regression-tested on x86_64-linux-gnu.  OK to install?

Thanks,
Richard

gcc/
	* real.h (dconst_quarter, dconst_sixth, dconst_ninth): New macros.
	(dconst_quarter_ptr, dconst_sixth_ptr, dconst_ninth_ptr): Declare.
	* real.c (CACHED_FRACTION(: New helper macro.
	(dconst_third_ptr): Use it.
	(dconst_quarter_ptr, dconst_sixth_ptr, dconst_ninth_ptr): New.
	* builtins.c (fold_builtin_sqrt): Use dconst_quarter and
	dconst_sixth.
	(fold_builtin_cbrt): Use dconst_sixth and dconst_ninth.

Comments

Bernd Schmidt Oct. 1, 2015, 1:59 p.m. UTC | #1
On 10/01/2015 03:51 PM, Richard Sandiford wrote:
> We have a global 1/2 and a cached 1/3, but recalculate 1/4, 1/6 and 1/9
> each time we need them.  That seems a bit arbitrary and makes the folding
> code more noisy (especially once it's moved to match.pd).
>
> This patch caches the other three constants too.  Bootstrapped &
> regression-tested on x86_64-linux-gnu.  OK to install?

Looks reasonable enough.


Bernd
Richard Biener Oct. 2, 2015, 8:11 a.m. UTC | #2
On Thu, Oct 1, 2015 at 3:59 PM, Bernd Schmidt <bschmidt@redhat.com> wrote:
> On 10/01/2015 03:51 PM, Richard Sandiford wrote:
>>
>> We have a global 1/2 and a cached 1/3, but recalculate 1/4, 1/6 and 1/9
>> each time we need them.  That seems a bit arbitrary and makes the folding
>> code more noisy (especially once it's moved to match.pd).
>>
>> This patch caches the other three constants too.  Bootstrapped &
>> regression-tested on x86_64-linux-gnu.  OK to install?
>
>
> Looks reasonable enough.

Given

/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */

const REAL_VALUE_TYPE *
dconst_third_ptr (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)
    {
      real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
    }
  return &value;
}

I wonder if it makes sense to have

template<int a, int b>
const REAL_VALUE_TYPE &
dconst (void)
{
  static REAL_VALUE_TYPE value;
  if (value.cl == rvc_zero)
    real_arithmetic (&value, RDIV_EXPR, real_digit (a), real_digit (b));
  return value;
}

instead which allows us to use

  dconst<1,2>()

in place of dconst_half () and allows arbitrary extra cached constants to be
added (well, double-check that, but I think the function static should be
a .comdat).

Richard.


>
> Bernd
diff mbox

Patch

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 1751b37..63724b9 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7743,20 +7743,10 @@  fold_builtin_sqrt (location_t loc, tree arg, tree type)
       if (powfn)
 	{
 	  tree arg0 = CALL_EXPR_ARG (arg, 0);
-	  tree tree_root;
-	  /* The inner root was either sqrt or cbrt.  */
-	  /* This was a conditional expression but it triggered a bug
-	     in Sun C 5.5.  */
-	  REAL_VALUE_TYPE dconstroot;
-	  if (BUILTIN_SQRT_P (fcode))
-	    dconstroot = dconsthalf;
-	  else
-	    dconstroot = dconst_third ();
-
-	  /* Adjust for the outer root.  */
-	  SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
-	  tree_root = build_real_truncate (type, dconstroot);
-	  return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
+	  tree arg1 = (BUILTIN_SQRT_P (fcode)
+		       ? build_real (type, dconst_quarter ())
+		       : build_real_truncate (type, dconst_sixth ()));
+	  return build_call_expr_loc (loc, powfn, 2, arg0, arg1);
 	}
     }
 
@@ -7816,11 +7806,7 @@  fold_builtin_cbrt (location_t loc, tree arg, tree type)
 	  if (powfn)
 	    {
 	      tree arg0 = CALL_EXPR_ARG (arg, 0);
-	      tree tree_root;
-	      REAL_VALUE_TYPE dconstroot = dconst_third ();
-
-	      SET_REAL_EXP (&dconstroot, REAL_EXP (&dconstroot) - 1);
-	      tree_root = build_real_truncate (type, dconstroot);
+	      tree tree_root = build_real_truncate (type, dconst_sixth ());
 	      return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
 	    }
 	}
@@ -7835,12 +7821,7 @@  fold_builtin_cbrt (location_t loc, tree arg, tree type)
 
 	      if (powfn)
 		{
-		  tree tree_root;
-		  REAL_VALUE_TYPE dconstroot;
-
-		  real_arithmetic (&dconstroot, MULT_EXPR,
-                                   dconst_third_ptr (), dconst_third_ptr ());
-		  tree_root = build_real_truncate (type, dconstroot);
+		  tree tree_root = build_real_truncate (type, dconst_ninth ());
 		  return build_call_expr_loc (loc, powfn, 2, arg0, tree_root);
 		}
 	    }
diff --git a/gcc/real.c b/gcc/real.c
index c1ff78d..78f3623 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -2379,21 +2379,26 @@  dconst_e_ptr (void)
   return &value;
 }
 
-/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
-
-const REAL_VALUE_TYPE *
-dconst_third_ptr (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)
-    {
-      real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (3));
-    }
-  return &value;
-}
+/* Returns a cached REAL_VALUE_TYPE corresponding to 1/n, for various n.  */
+
+#define CACHED_FRACTION(NAME, N)					\
+  const REAL_VALUE_TYPE *						\
+  NAME (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)						\
+      real_arithmetic (&value, RDIV_EXPR, &dconst1, real_digit (N));	\
+    return &value;							\
+  }
+
+CACHED_FRACTION (dconst_third_ptr, 3)
+CACHED_FRACTION (dconst_quarter_ptr, 4)
+CACHED_FRACTION (dconst_sixth_ptr, 6)
+CACHED_FRACTION (dconst_ninth_ptr, 9)
 
 /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
 
diff --git a/gcc/real.h b/gcc/real.h
index 455d853..5d8c92c 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -414,15 +414,21 @@  extern REAL_VALUE_TYPE dconst2;
 extern REAL_VALUE_TYPE dconstm1;
 extern REAL_VALUE_TYPE dconsthalf;
 
-#define dconst_e()  (*dconst_e_ptr ())
-#define dconst_third()  (*dconst_third_ptr ())
-#define dconst_sqrt2()  (*dconst_sqrt2_ptr ())
+#define dconst_e() (*dconst_e_ptr ())
+#define dconst_third() (*dconst_third_ptr ())
+#define dconst_quarter() (*dconst_quarter_ptr ())
+#define dconst_sixth() (*dconst_sixth_ptr ())
+#define dconst_ninth() (*dconst_ninth_ptr ())
+#define dconst_sqrt2() (*dconst_sqrt2_ptr ())
 
 /* Function to return the real value special constant 'e'.  */
 extern const REAL_VALUE_TYPE * dconst_e_ptr (void);
 
-/* Returns the special REAL_VALUE_TYPE corresponding to 1/3.  */
-extern const REAL_VALUE_TYPE * dconst_third_ptr (void);
+/* Returns a cached REAL_VALUE_TYPE corresponding to 1/n, for various n.  */
+extern const REAL_VALUE_TYPE *dconst_third_ptr (void);
+extern const REAL_VALUE_TYPE *dconst_quarter_ptr (void);
+extern const REAL_VALUE_TYPE *dconst_sixth_ptr (void);
+extern const REAL_VALUE_TYPE *dconst_ninth_ptr (void);
 
 /* Returns the special REAL_VALUE_TYPE corresponding to sqrt(2).  */
 extern const REAL_VALUE_TYPE * dconst_sqrt2_ptr (void);