diff mbox

Expand pow(x,n) into mulitplies in cse_sincos pass (PR46728, patch 2)

Message ID 1306269353.4821.47.camel@L3G5336.ibm.com
State New
Headers show

Commit Message

Bill Schmidt May 24, 2011, 8:35 p.m. UTC
Here's a small patch to expand pow(x,n) for integer n using the
powi(x,n) logic in the cse_sincos pass.  OK for trunk?

For the next patch, I'll plan on expanding pow(x,n) for n in
{0.5, 0.25, 0.75, 1./3., 1./6.}.  This logic will be added to
gimple_expand_builtin_pow.

Bill


2011-05-24  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
	PR tree-optimization/46728
	* tree-ssa-math-opts.c (gimple_expand_builtin_pow): New.
	(execute_cse_sincos): Add switch case for BUILT_IN_POW.

Comments

Richard Biener May 25, 2011, 8:47 a.m. UTC | #1
On Tue, May 24, 2011 at 10:35 PM, William J. Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> Here's a small patch to expand pow(x,n) for integer n using the
> powi(x,n) logic in the cse_sincos pass.  OK for trunk?
>
> For the next patch, I'll plan on expanding pow(x,n) for n in
> {0.5, 0.25, 0.75, 1./3., 1./6.}.  This logic will be added to
> gimple_expand_builtin_pow.

Ok.

Thanks,
Richard.

> Bill
>
>
> 2011-05-24  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
>        PR tree-optimization/46728
>        * tree-ssa-math-opts.c (gimple_expand_builtin_pow): New.
>        (execute_cse_sincos): Add switch case for BUILT_IN_POW.
>
> Index: gcc/tree-ssa-math-opts.c
> ===================================================================
> --- gcc/tree-ssa-math-opts.c    (revision 174129)
> +++ gcc/tree-ssa-math-opts.c    (working copy)
> @@ -1024,6 +1024,39 @@ gimple_expand_builtin_powi (gimple_stmt_iterator *
>   return NULL_TREE;
>  }
>
> +/* ARG0 and ARG1 are the two arguments to a pow builtin call in GSI
> +   with location info LOC.  If possible, create an equivalent and
> +   less expensive sequence of statements prior to GSI, and return an
> +   expession holding the result.  */
> +
> +static tree
> +gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
> +                          tree arg0, tree arg1)
> +{
> +  REAL_VALUE_TYPE c, cint;
> +  HOST_WIDE_INT n;
> +
> +  /* If the exponent isn't a constant, there's nothing of interest
> +     to be done.  */
> +  if (TREE_CODE (arg1) != REAL_CST)
> +    return NULL_TREE;
> +
> +  /* If the exponent is equivalent to an integer, expand it into
> +     multiplies when profitable.  */
> +  c = TREE_REAL_CST (arg1);
> +  n = real_to_integer (&c);
> +  real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
> +
> +  if (real_identical (&c, &cint)
> +      && ((n >= -1 && n <= 2)
> +         || (flag_unsafe_math_optimizations
> +             && optimize_insn_for_speed_p ()
> +             && powi_cost (n) <= POWI_MAX_MULTS)))
> +    return gimple_expand_builtin_powi (gsi, loc, arg0, n);
> +
> +  return NULL_TREE;
> +}
> +
>  /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
>    on the SSA_NAME argument of each of them.  Also expand powi(x,n) into
>    an optimal number of multiplies, when n is a constant.  */
> @@ -1065,6 +1098,23 @@ execute_cse_sincos (void)
>                    cfg_changed |= execute_cse_sincos_1 (arg);
>                  break;
>
> +               CASE_FLT_FN (BUILT_IN_POW):
> +                 arg0 = gimple_call_arg (stmt, 0);
> +                 arg1 = gimple_call_arg (stmt, 1);
> +
> +                 loc = gimple_location (stmt);
> +                 result = gimple_expand_builtin_pow (&gsi, loc, arg0, arg1);
> +
> +                 if (result)
> +                   {
> +                     tree lhs = gimple_get_lhs (stmt);
> +                     gimple new_stmt = gimple_build_assign (lhs, result);
> +                     gimple_set_location (new_stmt, loc);
> +                     unlink_stmt_vdef (stmt);
> +                     gsi_replace (&gsi, new_stmt, true);
> +                   }
> +                 break;
> +
>                CASE_FLT_FN (BUILT_IN_POWI):
>                  arg0 = gimple_call_arg (stmt, 0);
>                  arg1 = gimple_call_arg (stmt, 1);
>
>
>
H.J. Lu Sept. 13, 2012, 12:41 p.m. UTC | #2
On Tue, May 24, 2011 at 1:35 PM, William J. Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> Here's a small patch to expand pow(x,n) for integer n using the
> powi(x,n) logic in the cse_sincos pass.  OK for trunk?
>
> For the next patch, I'll plan on expanding pow(x,n) for n in
> {0.5, 0.25, 0.75, 1./3., 1./6.}.  This logic will be added to
> gimple_expand_builtin_pow.
>
> Bill
>
>
> 2011-05-24  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
>         PR tree-optimization/46728
>         * tree-ssa-math-opts.c (gimple_expand_builtin_pow): New.
>         (execute_cse_sincos): Add switch case for BUILT_IN_POW.
>

This caused:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54563
diff mbox

Patch

Index: gcc/tree-ssa-math-opts.c
===================================================================
--- gcc/tree-ssa-math-opts.c	(revision 174129)
+++ gcc/tree-ssa-math-opts.c	(working copy)
@@ -1024,6 +1024,39 @@  gimple_expand_builtin_powi (gimple_stmt_iterator *
   return NULL_TREE;
 }
 
+/* ARG0 and ARG1 are the two arguments to a pow builtin call in GSI
+   with location info LOC.  If possible, create an equivalent and
+   less expensive sequence of statements prior to GSI, and return an
+   expession holding the result.  */
+
+static tree
+gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, 
+			   tree arg0, tree arg1)
+{
+  REAL_VALUE_TYPE c, cint;
+  HOST_WIDE_INT n;
+
+  /* If the exponent isn't a constant, there's nothing of interest
+     to be done.  */
+  if (TREE_CODE (arg1) != REAL_CST)
+    return NULL_TREE;
+
+  /* If the exponent is equivalent to an integer, expand it into
+     multiplies when profitable.  */
+  c = TREE_REAL_CST (arg1);
+  n = real_to_integer (&c);
+  real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
+
+  if (real_identical (&c, &cint)
+      && ((n >= -1 && n <= 2)
+	  || (flag_unsafe_math_optimizations
+	      && optimize_insn_for_speed_p ()
+	      && powi_cost (n) <= POWI_MAX_MULTS)))
+    return gimple_expand_builtin_powi (gsi, loc, arg0, n);
+
+  return NULL_TREE;
+}
+
 /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
    on the SSA_NAME argument of each of them.  Also expand powi(x,n) into
    an optimal number of multiplies, when n is a constant.  */
@@ -1065,6 +1098,23 @@  execute_cse_sincos (void)
 		    cfg_changed |= execute_cse_sincos_1 (arg);
 		  break;
 
+		CASE_FLT_FN (BUILT_IN_POW):
+		  arg0 = gimple_call_arg (stmt, 0);
+		  arg1 = gimple_call_arg (stmt, 1);
+
+		  loc = gimple_location (stmt);
+		  result = gimple_expand_builtin_pow (&gsi, loc, arg0, arg1);
+
+		  if (result)
+		    {
+		      tree lhs = gimple_get_lhs (stmt);
+		      gimple new_stmt = gimple_build_assign (lhs, result);
+		      gimple_set_location (new_stmt, loc);
+		      unlink_stmt_vdef (stmt);
+		      gsi_replace (&gsi, new_stmt, true);
+		    }
+		  break;
+
 		CASE_FLT_FN (BUILT_IN_POWI):
 		  arg0 = gimple_call_arg (stmt, 0);
 		  arg1 = gimple_call_arg (stmt, 1);