Commit 96285749 by Richard Sandiford Committed by Richard Sandiford

Move cexp simplifications to match.pd

This required reinstating support for captures in the result
of a simplification.  That part (genmatch.c) is by Richard B.

Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi.

gcc/
2015-10-20  Richard Sandiford  <richard.sandiford@arm.com>
	    Richard Biener  <rguenther@suse.de>

	* genmatch.c (dt_simplify::gen): Skip captures that are
	part of the result.
	(parser::parse_expr): Allow captures in results too.
	* builtins.c (fold_builtin_cexp): Delete.
	(fold_builtin_1): Handle constant cexp arguments here.
	* match.pd: Fold cexp(x+yi) to exp(x) * cexpi(y).

Co-Authored-By: Richard Biener <rguenther@suse.de>

From-SVN: r229308
parent 9df01367
2015-10-26 Richard Sandiford <richard.sandiford@arm.com>
2015-10-20 Richard Sandiford <richard.sandiford@arm.com>
Richard Biener <rguenther@suse.de>
* genmatch.c (dt_simplify::gen): Skip captures that are
part of the result.
(parser::parse_expr): Allow captures in results too.
* builtins.c (fold_builtin_cexp): Delete.
(fold_builtin_1): Handle constant cexp arguments here.
* match.pd: Fold cexp(x+yi) to exp(x) * cexpi(y).
2015-10-26 Mikhail Maltsev <maltsevm@gmail.com> 2015-10-26 Mikhail Maltsev <maltsevm@gmail.com>
* alloc-pool.h (base_pool_allocator::initialize, ::allocate): Remove * alloc-pool.h (base_pool_allocator::initialize, ::allocate): Remove
...@@ -7460,74 +7460,6 @@ fold_builtin_sincos (location_t loc, ...@@ -7460,74 +7460,6 @@ fold_builtin_sincos (location_t loc,
build1 (REALPART_EXPR, type, call))); build1 (REALPART_EXPR, type, call)));
} }
/* Fold function call to builtin cexp, cexpf, or cexpl. Return
NULL_TREE if no simplification can be made. */
static tree
fold_builtin_cexp (location_t loc, tree arg0, tree type)
{
tree rtype;
tree realp, imagp, ifn;
tree res;
if (!validate_arg (arg0, COMPLEX_TYPE)
|| TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) != REAL_TYPE)
return NULL_TREE;
/* Calculate the result when the argument is a constant. */
if ((res = do_mpc_arg1 (arg0, type, mpc_exp)))
return res;
rtype = TREE_TYPE (TREE_TYPE (arg0));
/* In case we can figure out the real part of arg0 and it is constant zero
fold to cexpi. */
if (!targetm.libc_has_function (function_c99_math_complex))
return NULL_TREE;
ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
if (!ifn)
return NULL_TREE;
if ((realp = fold_unary_loc (loc, REALPART_EXPR, rtype, arg0))
&& real_zerop (realp))
{
tree narg = fold_build1_loc (loc, IMAGPART_EXPR, rtype, arg0);
return build_call_expr_loc (loc, ifn, 1, narg);
}
/* In case we can easily decompose real and imaginary parts split cexp
to exp (r) * cexpi (i). */
if (flag_unsafe_math_optimizations
&& realp)
{
tree rfn, rcall, icall;
rfn = mathfn_built_in (rtype, BUILT_IN_EXP);
if (!rfn)
return NULL_TREE;
imagp = fold_unary_loc (loc, IMAGPART_EXPR, rtype, arg0);
if (!imagp)
return NULL_TREE;
icall = build_call_expr_loc (loc, ifn, 1, imagp);
icall = builtin_save_expr (icall);
rcall = build_call_expr_loc (loc, rfn, 1, realp);
rcall = builtin_save_expr (rcall);
return fold_build2_loc (loc, COMPLEX_EXPR, type,
fold_build2_loc (loc, MULT_EXPR, rtype,
rcall,
fold_build1_loc (loc, REALPART_EXPR,
rtype, icall)),
fold_build2_loc (loc, MULT_EXPR, rtype,
rcall,
fold_build1_loc (loc, IMAGPART_EXPR,
rtype, icall)));
}
return NULL_TREE;
}
/* Fold function call to builtin lround, lroundf or lroundl (or the /* Fold function call to builtin lround, lroundf or lroundl (or the
corresponding long long versions) and other rounding functions. ARG corresponding long long versions) and other rounding functions. ARG
is the argument to the call. Return NULL_TREE if no simplification is the argument to the call. Return NULL_TREE if no simplification
...@@ -9357,7 +9289,10 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0) ...@@ -9357,7 +9289,10 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
break; break;
CASE_FLT_FN (BUILT_IN_CEXP): CASE_FLT_FN (BUILT_IN_CEXP):
return fold_builtin_cexp (loc, arg0, type); if (validate_arg (arg0, COMPLEX_TYPE)
&& TREE_CODE (TREE_TYPE (TREE_TYPE (arg0))) == REAL_TYPE)
return do_mpc_arg1 (arg0, type, mpc_exp);
break;
CASE_FLT_FN (BUILT_IN_CEXPI): CASE_FLT_FN (BUILT_IN_CEXPI):
if (validate_arg (arg0, REAL_TYPE)) if (validate_arg (arg0, REAL_TYPE))
......
...@@ -3163,7 +3163,11 @@ dt_simplify::gen (FILE *f, int indent, bool gimple) ...@@ -3163,7 +3163,11 @@ dt_simplify::gen (FILE *f, int indent, bool gimple)
s->capture_max + 1, indexes[0]->get_name (opname)); s->capture_max + 1, indexes[0]->get_name (opname));
for (int i = 1; i <= s->capture_max; ++i) for (int i = 1; i <= s->capture_max; ++i)
fprintf (f, ", %s", indexes[i]->get_name (opname)); {
if (!indexes[i])
break;
fprintf (f, ", %s", indexes[i]->get_name (opname));
}
fprintf (f, " };\n"); fprintf (f, " };\n");
} }
...@@ -3831,7 +3835,7 @@ parser::parse_expr () ...@@ -3831,7 +3835,7 @@ parser::parse_expr ()
if (token->type == CPP_ATSIGN if (token->type == CPP_ATSIGN
&& !(token->flags & PREV_WHITE)) && !(token->flags & PREV_WHITE))
op = parse_capture (e, !parsing_match_operand); op = parse_capture (e, false);
else if (force_capture) else if (force_capture)
{ {
unsigned num = capture_ids->elements (); unsigned num = capture_ids->elements ();
......
...@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see
(define_operator_list TAN BUILT_IN_TANF BUILT_IN_TAN BUILT_IN_TANL) (define_operator_list TAN BUILT_IN_TANF BUILT_IN_TAN BUILT_IN_TANL)
(define_operator_list ATAN BUILT_IN_ATANF BUILT_IN_ATAN BUILT_IN_ATANL) (define_operator_list ATAN BUILT_IN_ATANF BUILT_IN_ATAN BUILT_IN_ATANL)
(define_operator_list COSH BUILT_IN_COSHF BUILT_IN_COSH BUILT_IN_COSHL) (define_operator_list COSH BUILT_IN_COSHF BUILT_IN_COSH BUILT_IN_COSHL)
(define_operator_list CEXP BUILT_IN_CEXPF BUILT_IN_CEXP BUILT_IN_CEXPL)
(define_operator_list CEXPI BUILT_IN_CEXPIF BUILT_IN_CEXPI BUILT_IN_CEXPIL) (define_operator_list CEXPI BUILT_IN_CEXPIF BUILT_IN_CEXPI BUILT_IN_CEXPIL)
(define_operator_list CPROJ BUILT_IN_CPROJF BUILT_IN_CPROJ BUILT_IN_CPROJL) (define_operator_list CPROJ BUILT_IN_CPROJF BUILT_IN_CPROJ BUILT_IN_CPROJL)
(define_operator_list CCOS BUILT_IN_CCOSF BUILT_IN_CCOS BUILT_IN_CCOSL) (define_operator_list CCOS BUILT_IN_CCOSF BUILT_IN_CCOS BUILT_IN_CCOSL)
...@@ -1562,6 +1563,11 @@ along with GCC; see the file COPYING3. If not see ...@@ -1562,6 +1563,11 @@ along with GCC; see the file COPYING3. If not see
(mult @0 integer_minus_onep) (mult @0 integer_minus_onep)
(negate @0)) (negate @0))
/* True if we can easily extract the real and imaginary parts of a complex
number. */
(match compositional_complex
(convert? (complex @0 @1)))
/* COMPLEX_EXPR and REALPART/IMAGPART_EXPR cancellations. */ /* COMPLEX_EXPR and REALPART/IMAGPART_EXPR cancellations. */
(simplify (simplify
(complex (realpart @0) (imagpart @0)) (complex (realpart @0) (imagpart @0))
...@@ -2584,7 +2590,18 @@ along with GCC; see the file COPYING3. If not see ...@@ -2584,7 +2590,18 @@ along with GCC; see the file COPYING3. If not see
/* cabs(x+xi) -> fabs(x)*sqrt(2). */ /* cabs(x+xi) -> fabs(x)*sqrt(2). */
(simplify (simplify
(CABS (complex @0 @0)) (CABS (complex @0 @0))
(mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); }))) (mult (abs @0) { build_real_truncate (type, dconst_sqrt2 ()); }))
/* cexp(x+yi) -> exp(x)*cexpi(y). */
(for cexps (CEXP)
exps (EXP)
cexpis (CEXPI)
(simplify
(cexps compositional_complex@0)
(if (targetm.libc_has_function (function_c99_math_complex))
(complex
(mult (exps@1 (realpart @0)) (realpart (cexpis:type@2 (imagpart @0))))
(mult @1 (imagpart @2)))))))
(if (canonicalize_math_p ()) (if (canonicalize_math_p ())
/* floor(x) -> trunc(x) if x is nonnegative. */ /* floor(x) -> trunc(x) if x is nonnegative. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment