Use combined_fn in tree-ssa-reassoc.c

Another patch to extend uses of built_in_function to combined_fn, this time
in tree-ssa-reassoc.c.

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

gcc/
	* tree-ssa-reassoc.c: Include case-cfn-macros.h.
	(stmt_is_power_of_op): Use combined_fn instead of built-in codes.
	(decrement_power, acceptable_pow_call): Likewise.
	(attempt_builtin_copysign): Likewise.

From-SVN: r230480
This commit is contained in:
Richard Sandiford 2015-11-17 18:45:20 +00:00 committed by Richard Sandiford
parent 9c0a9e1277
commit 314709cdbe
2 changed files with 43 additions and 50 deletions

View File

@ -1,3 +1,10 @@
2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
* tree-ssa-reassoc.c: Include case-cfn-macros.h.
(stmt_is_power_of_op): Use combined_fn instead of built-in codes.
(decrement_power, acceptable_pow_call): Likewise.
(attempt_builtin_copysign): Likewise.
2015-11-17 Richard Sandiford <richard.sandiford@arm.com> 2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
* tree-vrp.c: Include case-cfn-macros.h. * tree-vrp.c: Include case-cfn-macros.h.

View File

@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h" #include "params.h"
#include "builtins.h" #include "builtins.h"
#include "gimplify.h" #include "gimplify.h"
#include "case-cfn-macros.h"
/* This is a simple global reassociation pass. It is, in part, based /* This is a simple global reassociation pass. It is, in part, based
on the LLVM pass of the same name (They do some things more/less on the LLVM pass of the same name (They do some things more/less
@ -1038,21 +1039,13 @@ oecount_cmp (const void *p1, const void *p2)
static bool static bool
stmt_is_power_of_op (gimple *stmt, tree op) stmt_is_power_of_op (gimple *stmt, tree op)
{ {
tree fndecl;
if (!is_gimple_call (stmt)) if (!is_gimple_call (stmt))
return false; return false;
fndecl = gimple_call_fndecl (stmt); switch (gimple_call_combined_fn (stmt))
if (!fndecl
|| DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
return false;
switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt)))
{ {
CASE_FLT_FN (BUILT_IN_POW): CASE_CFN_POW:
CASE_FLT_FN (BUILT_IN_POWI): CASE_CFN_POWI:
return (operand_equal_p (gimple_call_arg (stmt, 0), op, 0)); return (operand_equal_p (gimple_call_arg (stmt, 0), op, 0));
default: default:
@ -1071,9 +1064,9 @@ decrement_power (gimple *stmt)
HOST_WIDE_INT power; HOST_WIDE_INT power;
tree arg1; tree arg1;
switch (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))) switch (gimple_call_combined_fn (stmt))
{ {
CASE_FLT_FN (BUILT_IN_POW): CASE_CFN_POW:
arg1 = gimple_call_arg (stmt, 1); arg1 = gimple_call_arg (stmt, 1);
c = TREE_REAL_CST (arg1); c = TREE_REAL_CST (arg1);
power = real_to_integer (&c) - 1; power = real_to_integer (&c) - 1;
@ -1081,7 +1074,7 @@ decrement_power (gimple *stmt)
gimple_call_set_arg (stmt, 1, build_real (TREE_TYPE (arg1), cint)); gimple_call_set_arg (stmt, 1, build_real (TREE_TYPE (arg1), cint));
return power; return power;
CASE_FLT_FN (BUILT_IN_POWI): CASE_CFN_POWI:
arg1 = gimple_call_arg (stmt, 1); arg1 = gimple_call_arg (stmt, 1);
power = TREE_INT_CST_LOW (arg1) - 1; power = TREE_INT_CST_LOW (arg1) - 1;
gimple_call_set_arg (stmt, 1, build_int_cst (TREE_TYPE (arg1), power)); gimple_call_set_arg (stmt, 1, build_int_cst (TREE_TYPE (arg1), power));
@ -3940,7 +3933,7 @@ break_up_subtract (gimple *stmt, gimple_stmt_iterator *gsip)
static bool static bool
acceptable_pow_call (gimple *stmt, tree *base, HOST_WIDE_INT *exponent) acceptable_pow_call (gimple *stmt, tree *base, HOST_WIDE_INT *exponent)
{ {
tree fndecl, arg1; tree arg1;
REAL_VALUE_TYPE c, cint; REAL_VALUE_TYPE c, cint;
if (!reassoc_insert_powi_p if (!reassoc_insert_powi_p
@ -3949,15 +3942,9 @@ acceptable_pow_call (gimple *stmt, tree *base, HOST_WIDE_INT *exponent)
|| !has_single_use (gimple_call_lhs (stmt))) || !has_single_use (gimple_call_lhs (stmt)))
return false; return false;
fndecl = gimple_call_fndecl (stmt); switch (gimple_call_combined_fn (stmt))
if (!fndecl
|| DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
return false;
switch (DECL_FUNCTION_CODE (fndecl))
{ {
CASE_FLT_FN (BUILT_IN_POW): CASE_CFN_POW:
if (flag_errno_math) if (flag_errno_math)
return false; return false;
@ -3979,7 +3966,7 @@ acceptable_pow_call (gimple *stmt, tree *base, HOST_WIDE_INT *exponent)
break; break;
CASE_FLT_FN (BUILT_IN_POWI): CASE_CFN_POWI:
*base = gimple_call_arg (stmt, 0); *base = gimple_call_arg (stmt, 0);
arg1 = gimple_call_arg (stmt, 1); arg1 = gimple_call_arg (stmt, 1);
@ -4639,35 +4626,40 @@ attempt_builtin_copysign (vec<operand_entry *> *ops)
&& has_single_use (oe->op)) && has_single_use (oe->op))
{ {
gimple *def_stmt = SSA_NAME_DEF_STMT (oe->op); gimple *def_stmt = SSA_NAME_DEF_STMT (oe->op);
if (gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL)) if (gcall *old_call = dyn_cast <gcall *> (def_stmt))
{ {
tree fndecl = gimple_call_fndecl (def_stmt);
tree arg0, arg1; tree arg0, arg1;
switch (DECL_FUNCTION_CODE (fndecl)) switch (gimple_call_combined_fn (old_call))
{ {
CASE_FLT_FN (BUILT_IN_COPYSIGN): CASE_CFN_COPYSIGN:
arg0 = gimple_call_arg (def_stmt, 0); arg0 = gimple_call_arg (old_call, 0);
arg1 = gimple_call_arg (def_stmt, 1); arg1 = gimple_call_arg (old_call, 1);
/* The first argument of copysign must be a constant, /* The first argument of copysign must be a constant,
otherwise there's nothing to do. */ otherwise there's nothing to do. */
if (TREE_CODE (arg0) == REAL_CST) if (TREE_CODE (arg0) == REAL_CST)
{ {
tree mul = const_binop (MULT_EXPR, TREE_TYPE (cst), tree type = TREE_TYPE (arg0);
cst, arg0); tree mul = const_binop (MULT_EXPR, type, cst, arg0);
/* If we couldn't fold to a single constant, skip it. /* If we couldn't fold to a single constant, skip it.
That happens e.g. for inexact multiplication when That happens e.g. for inexact multiplication when
-frounding-math. */ -frounding-math. */
if (mul == NULL_TREE) if (mul == NULL_TREE)
break; break;
/* Instead of adjusting the old DEF_STMT, let's build /* Instead of adjusting OLD_CALL, let's build a new
a new call to not leak the LHS and prevent keeping call to not leak the LHS and prevent keeping bogus
bogus debug statements. DCE will clean up the old debug statements. DCE will clean up the old call. */
call. */ gcall *new_call;
gcall *call = gimple_build_call (fndecl, 2, mul, arg1); if (gimple_call_internal_p (old_call))
tree lhs = make_ssa_name (TREE_TYPE (arg0)); new_call = gimple_build_call_internal
gimple_call_set_lhs (call, lhs); (IFN_COPYSIGN, 2, mul, arg1);
gimple_set_location (call, gimple_location (def_stmt)); else
insert_stmt_after (call, def_stmt); new_call = gimple_build_call
(gimple_call_fndecl (old_call), 2, mul, arg1);
tree lhs = make_ssa_name (type);
gimple_call_set_lhs (new_call, lhs);
gimple_set_location (new_call,
gimple_location (old_call));
insert_stmt_after (new_call, old_call);
/* We've used the constant, get rid of it. */ /* We've used the constant, get rid of it. */
ops->pop (); ops->pop ();
bool cst1_neg = real_isneg (TREE_REAL_CST_PTR (cst)); bool cst1_neg = real_isneg (TREE_REAL_CST_PTR (cst));
@ -4677,7 +4669,7 @@ attempt_builtin_copysign (vec<operand_entry *> *ops)
tree negrhs = make_ssa_name (TREE_TYPE (lhs)); tree negrhs = make_ssa_name (TREE_TYPE (lhs));
gimple *negate_stmt gimple *negate_stmt
= gimple_build_assign (negrhs, NEGATE_EXPR, lhs); = gimple_build_assign (negrhs, NEGATE_EXPR, lhs);
insert_stmt_after (negate_stmt, call); insert_stmt_after (negate_stmt, new_call);
oe->op = negrhs; oe->op = negrhs;
} }
else else
@ -4686,18 +4678,12 @@ attempt_builtin_copysign (vec<operand_entry *> *ops)
{ {
fprintf (dump_file, "Optimizing copysign: "); fprintf (dump_file, "Optimizing copysign: ");
print_generic_expr (dump_file, cst, 0); print_generic_expr (dump_file, cst, 0);
fprintf (dump_file, " * "); fprintf (dump_file, " * COPYSIGN (");
print_generic_expr (dump_file,
gimple_call_fn (def_stmt), 0);
fprintf (dump_file, " (");
print_generic_expr (dump_file, arg0, 0); print_generic_expr (dump_file, arg0, 0);
fprintf (dump_file, ", "); fprintf (dump_file, ", ");
print_generic_expr (dump_file, arg1, 0); print_generic_expr (dump_file, arg1, 0);
fprintf (dump_file, ") into %s", fprintf (dump_file, ") into %sCOPYSIGN (",
cst1_neg ? "-" : ""); cst1_neg ? "-" : "");
print_generic_expr (dump_file,
gimple_call_fn (def_stmt), 0);
fprintf (dump_file, " (");
print_generic_expr (dump_file, mul, 0); print_generic_expr (dump_file, mul, 0);
fprintf (dump_file, ", "); fprintf (dump_file, ", ");
print_generic_expr (dump_file, arg1, 0); print_generic_expr (dump_file, arg1, 0);