Message ID | 1306269353.4821.47.camel@L3G5336.ibm.com |
---|---|
State | New |
Headers | show |
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); > > >
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
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);