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
corresponding long long versions) and other rounding functions. ARG
is the argument to the call. Return NULL_TREE if no simplification
break;
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):
if (validate_arg (arg0, REAL_TYPE))
s->capture_max + 1, indexes[0]->get_name (opname));
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");
}
if (token->type == CPP_ATSIGN
&& !(token->flags & PREV_WHITE))
- op = parse_capture (e, !parsing_match_operand);
+ op = parse_capture (e, false);
else if (force_capture)
{
unsigned num = capture_ids->elements ();
(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 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 CPROJ BUILT_IN_CPROJF BUILT_IN_CPROJ BUILT_IN_CPROJL)
(define_operator_list CCOS BUILT_IN_CCOSF BUILT_IN_CCOS BUILT_IN_CCOSL)
(mult @0 integer_minus_onep)
(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. */
(simplify
(complex (realpart @0) (imagpart @0))
/* cabs(x+xi) -> fabs(x)*sqrt(2). */
(simplify
(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 ())
/* floor(x) -> trunc(x) if x is nonnegative. */