diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 398a2d99a73..7ed5cc6ac13 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-06-10 Bill Schmidt + + PR lto/49302 + * tree-ssa-math-opts.c (powi_as_mults): Minor cleanup. + (build_and_insert_call): Likewise. + (build_and_insert_ref): New. + (gimple_expand_builtin_pow): Minor cleanup. + (gimple_expand_builtin_cabs): New. + (execute_cse_sincos): Add case for BUILT_IN_CABS. + 2011-06-10 Jan Hubicka * ipa-cp.c (ipcp_versionable_function_p): Aliases are not versionable. diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index 5b82fb0aa43..bffd7f26c43 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -987,7 +987,7 @@ powi_as_mults (gimple_stmt_iterator *gsi, location_t loc, memset (cache, 0, sizeof (cache)); cache[1] = arg0; - target = create_tmp_var (type, "powmult"); + target = create_tmp_reg (type, "powmult"); add_referenced_var (target); result = powi_as_mults_1 (gsi, loc, type, (n < 0) ? -n : n, cache, target); @@ -1041,7 +1041,7 @@ build_and_insert_call (gimple_stmt_iterator *gsi, location_t loc, if (!*var) { - *var = create_tmp_var (TREE_TYPE (arg), "powroot"); + *var = create_tmp_reg (TREE_TYPE (arg), "powroot"); add_referenced_var (*var); } @@ -1070,6 +1070,22 @@ build_and_insert_binop (gimple_stmt_iterator *gsi, location_t loc, return result; } +/* Build a gimple reference operation with the given CODE and argument + ARG, assigning the result to a new SSA name for variable TARGET. + Insert the statement prior to GSI's current position, and return + the fresh SSA name. */ + +static inline tree +build_and_insert_ref (gimple_stmt_iterator *gsi, location_t loc, tree type, + tree target, enum tree_code code, tree arg0) +{ + tree result = make_ssa_name (target, NULL); + gimple stmt = gimple_build_assign (result, build1 (code, type, arg0)); + gimple_set_location (stmt, loc); + gsi_insert_before (gsi, stmt, GSI_SAME_STMT); + return result; +} + /* 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 @@ -1124,7 +1140,7 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, if we don't have a hardware sqrt insn. */ dconst1_4 = dconst1; SET_REAL_EXP (&dconst1_4, REAL_EXP (&dconst1_4) - 2); - hw_sqrt_exists = optab_handler(sqrt_optab, mode) != CODE_FOR_nothing; + hw_sqrt_exists = optab_handler (sqrt_optab, mode) != CODE_FOR_nothing; if (flag_unsafe_math_optimizations && sqrtfn @@ -1306,6 +1322,42 @@ gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, return NULL_TREE; } +/* ARG is the argument to a cabs builtin call in GSI with location info + LOC. Create a sequence of statements prior to GSI that calculates + sqrt(R*R + I*I), where R and I are the real and imaginary components + of ARG, respectively. Return an expression holding the result. */ + +static tree +gimple_expand_builtin_cabs (gimple_stmt_iterator *gsi, location_t loc, tree arg) +{ + tree target, real_part, imag_part, addend1, addend2, sum, result; + tree type = TREE_TYPE (TREE_TYPE (arg)); + tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT); + enum machine_mode mode = TYPE_MODE (type); + + if (!flag_unsafe_math_optimizations + || !optimize_bb_for_speed_p (gimple_bb (gsi_stmt (*gsi))) + || !sqrtfn + || optab_handler (sqrt_optab, mode) == CODE_FOR_nothing) + return NULL_TREE; + + target = create_tmp_reg (type, "cabs"); + add_referenced_var (target); + + real_part = build_and_insert_ref (gsi, loc, type, target, + REALPART_EXPR, arg); + addend1 = build_and_insert_binop (gsi, loc, target, MULT_EXPR, + real_part, real_part); + imag_part = build_and_insert_ref (gsi, loc, type, target, + IMAGPART_EXPR, arg); + addend2 = build_and_insert_binop (gsi, loc, target, MULT_EXPR, + imag_part, imag_part); + sum = build_and_insert_binop (gsi, loc, target, PLUS_EXPR, addend1, addend2); + result = build_and_insert_call (gsi, loc, &target, sqrtfn, sum); + + return result; +} + /* 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. */ @@ -1388,6 +1440,21 @@ execute_cse_sincos (void) } break; + CASE_FLT_FN (BUILT_IN_CABS): + arg0 = gimple_call_arg (stmt, 0); + loc = gimple_location (stmt); + result = gimple_expand_builtin_cabs (&gsi, loc, arg0); + + 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; + default:; } }