Commit 1d9da71f by Richard Sandiford Committed by Richard Sandiford

Make more use of combined_fn

This patch generalises fold-const.[hc] routines to use combined_fn
instead of built_in_function.  It also updates gimple-ssa-backprop,c
since the update is simple and it avoids churn on the call to
negate_mathfn_p.

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

gcc/
	* fold-const.h (negate_mathfn_p): Take a combined_fn rather
	than a built_in_function.
	(tree_call_nonnegative_warnv_p): Take a combined_fn rather than
	a function decl.
	(integer_valued_real_call_p): Likewise.
	* fold-const.c: Include case-cfn-macros.h
	(negate_mathfn_p): Take a combined_fn rather than a built_in_function.
	(negate_expr_p): Update accordingly.
	(tree_call_nonnegative_warnv_p): Take a combined_fn rather than
	a function decl.
	(integer_valued_real_call_p): Likewise.
	(tree_invalid_nonnegative_warnv_p): Update accordingly.
	(integer_valued_real_p): Likewise.
	* gimple-fold.c (gimple_call_nonnegative_warnv_p): Update call
	to tree_call_nonnegative_warnv_p.
	(gimple_call_integer_valued_real_p): Likewise
	integer_valued_real_call_p.
	* gimple-ssa-backprop.c: Include case-cfn-macros.h.
	(backprop::process_builtin_call_use): Extend to combined_fn.
	(strip_sign_op_1): Likewise.
	(backprop::process_use): Don't check for built-in calls here.
	(backprop::execute): Likewise.
	(backprop::optimize_builtin_call): Update call to negate_mathfn_p.

From-SVN: r230478
parent d7ebef06
2015-11-17 Richard Sandiford <richard.sandiford@arm.com> 2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
* fold-const.h (negate_mathfn_p): Take a combined_fn rather
than a built_in_function.
(tree_call_nonnegative_warnv_p): Take a combined_fn rather than
a function decl.
(integer_valued_real_call_p): Likewise.
* fold-const.c: Include case-cfn-macros.h
(negate_mathfn_p): Take a combined_fn rather than a built_in_function.
(negate_expr_p): Update accordingly.
(tree_call_nonnegative_warnv_p): Take a combined_fn rather than
a function decl.
(integer_valued_real_call_p): Likewise.
(tree_invalid_nonnegative_warnv_p): Update accordingly.
(integer_valued_real_p): Likewise.
* gimple-fold.c (gimple_call_nonnegative_warnv_p): Update call
to tree_call_nonnegative_warnv_p.
(gimple_call_integer_valued_real_p): Likewise
integer_valued_real_call_p.
* gimple-ssa-backprop.c: Include case-cfn-macros.h.
(backprop::process_builtin_call_use): Extend to combined_fn.
(strip_sign_op_1): Likewise.
(backprop::process_use): Don't check for built-in calls here.
(backprop::execute): Likewise.
(backprop::optimize_builtin_call): Update call to negate_mathfn_p.
2015-11-17 Richard Sandiford <richard.sandiford@arm.com>
* fold-const-call.h (fold_const_call): Replace built_in_function * fold-const-call.h (fold_const_call): Replace built_in_function
arguments with combined_fn arguments. arguments with combined_fn arguments.
* fold-const-call.c: Include case-cfn-macros.h. * fold-const-call.c: Include case-cfn-macros.h.
...@@ -73,6 +73,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -73,6 +73,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h" #include "params.h"
#include "tree-into-ssa.h" #include "tree-into-ssa.h"
#include "md5.h" #include "md5.h"
#include "case-cfn-macros.h"
#ifndef LOAD_EXTEND_OP #ifndef LOAD_EXTEND_OP
#define LOAD_EXTEND_OP(M) UNKNOWN #define LOAD_EXTEND_OP(M) UNKNOWN
...@@ -313,39 +314,39 @@ fold_overflow_warning (const char* gmsgid, enum warn_strict_overflow_code wc) ...@@ -313,39 +314,39 @@ fold_overflow_warning (const char* gmsgid, enum warn_strict_overflow_code wc)
is odd, i.e. -f(x) == f(-x). */ is odd, i.e. -f(x) == f(-x). */
bool bool
negate_mathfn_p (enum built_in_function code) negate_mathfn_p (combined_fn fn)
{ {
switch (code) switch (fn)
{ {
CASE_FLT_FN (BUILT_IN_ASIN): CASE_CFN_ASIN:
CASE_FLT_FN (BUILT_IN_ASINH): CASE_CFN_ASINH:
CASE_FLT_FN (BUILT_IN_ATAN): CASE_CFN_ATAN:
CASE_FLT_FN (BUILT_IN_ATANH): CASE_CFN_ATANH:
CASE_FLT_FN (BUILT_IN_CASIN): CASE_CFN_CASIN:
CASE_FLT_FN (BUILT_IN_CASINH): CASE_CFN_CASINH:
CASE_FLT_FN (BUILT_IN_CATAN): CASE_CFN_CATAN:
CASE_FLT_FN (BUILT_IN_CATANH): CASE_CFN_CATANH:
CASE_FLT_FN (BUILT_IN_CBRT): CASE_CFN_CBRT:
CASE_FLT_FN (BUILT_IN_CPROJ): CASE_CFN_CPROJ:
CASE_FLT_FN (BUILT_IN_CSIN): CASE_CFN_CSIN:
CASE_FLT_FN (BUILT_IN_CSINH): CASE_CFN_CSINH:
CASE_FLT_FN (BUILT_IN_CTAN): CASE_CFN_CTAN:
CASE_FLT_FN (BUILT_IN_CTANH): CASE_CFN_CTANH:
CASE_FLT_FN (BUILT_IN_ERF): CASE_CFN_ERF:
CASE_FLT_FN (BUILT_IN_LLROUND): CASE_CFN_LLROUND:
CASE_FLT_FN (BUILT_IN_LROUND): CASE_CFN_LROUND:
CASE_FLT_FN (BUILT_IN_ROUND): CASE_CFN_ROUND:
CASE_FLT_FN (BUILT_IN_SIN): CASE_CFN_SIN:
CASE_FLT_FN (BUILT_IN_SINH): CASE_CFN_SINH:
CASE_FLT_FN (BUILT_IN_TAN): CASE_CFN_TAN:
CASE_FLT_FN (BUILT_IN_TANH): CASE_CFN_TANH:
CASE_FLT_FN (BUILT_IN_TRUNC): CASE_CFN_TRUNC:
return true; return true;
CASE_FLT_FN (BUILT_IN_LLRINT): CASE_CFN_LLRINT:
CASE_FLT_FN (BUILT_IN_LRINT): CASE_CFN_LRINT:
CASE_FLT_FN (BUILT_IN_NEARBYINT): CASE_CFN_NEARBYINT:
CASE_FLT_FN (BUILT_IN_RINT): CASE_CFN_RINT:
return !flag_rounding_math; return !flag_rounding_math;
default: default:
...@@ -506,7 +507,7 @@ negate_expr_p (tree t) ...@@ -506,7 +507,7 @@ negate_expr_p (tree t)
case CALL_EXPR: case CALL_EXPR:
/* Negate -f(x) as f(-x). */ /* Negate -f(x) as f(-x). */
if (negate_mathfn_p (builtin_mathfn_code (t))) if (negate_mathfn_p (get_call_combined_fn (t)))
return negate_expr_p (CALL_EXPR_ARG (t, 0)); return negate_expr_p (CALL_EXPR_ARG (t, 0));
break; break;
...@@ -693,7 +694,7 @@ fold_negate_expr (location_t loc, tree t) ...@@ -693,7 +694,7 @@ fold_negate_expr (location_t loc, tree t)
case CALL_EXPR: case CALL_EXPR:
/* Negate -f(x) as f(-x). */ /* Negate -f(x) as f(-x). */
if (negate_mathfn_p (builtin_mathfn_code (t)) if (negate_mathfn_p (get_call_combined_fn (t))
&& negate_expr_p (CALL_EXPR_ARG (t, 0))) && negate_expr_p (CALL_EXPR_ARG (t, 0)))
{ {
tree fndecl, arg; tree fndecl, arg;
...@@ -12910,121 +12911,120 @@ tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth) ...@@ -12910,121 +12911,120 @@ tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth)
*STRICT_OVERFLOW_P. DEPTH is the current nesting depth of the query. */ *STRICT_OVERFLOW_P. DEPTH is the current nesting depth of the query. */
bool bool
tree_call_nonnegative_warnv_p (tree type, tree fndecl, tree arg0, tree arg1, tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
bool *strict_overflow_p, int depth) bool *strict_overflow_p, int depth)
{ {
if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) switch (fn)
switch (DECL_FUNCTION_CODE (fndecl)) {
{ CASE_CFN_ACOS:
CASE_FLT_FN (BUILT_IN_ACOS): CASE_CFN_ACOSH:
CASE_FLT_FN (BUILT_IN_ACOSH): CASE_CFN_CABS:
CASE_FLT_FN (BUILT_IN_CABS): CASE_CFN_COSH:
CASE_FLT_FN (BUILT_IN_COSH): CASE_CFN_ERFC:
CASE_FLT_FN (BUILT_IN_ERFC): CASE_CFN_EXP:
CASE_FLT_FN (BUILT_IN_EXP): CASE_CFN_EXP10:
CASE_FLT_FN (BUILT_IN_EXP10): CASE_CFN_EXP2:
CASE_FLT_FN (BUILT_IN_EXP2): CASE_CFN_FABS:
CASE_FLT_FN (BUILT_IN_FABS): CASE_CFN_FDIM:
CASE_FLT_FN (BUILT_IN_FDIM): CASE_CFN_HYPOT:
CASE_FLT_FN (BUILT_IN_HYPOT): CASE_CFN_POW10:
CASE_FLT_FN (BUILT_IN_POW10): CASE_CFN_FFS:
CASE_INT_FN (BUILT_IN_FFS): CASE_CFN_PARITY:
CASE_INT_FN (BUILT_IN_PARITY): CASE_CFN_POPCOUNT:
CASE_INT_FN (BUILT_IN_POPCOUNT): CASE_CFN_CLZ:
CASE_INT_FN (BUILT_IN_CLZ): CASE_CFN_CLRSB:
CASE_INT_FN (BUILT_IN_CLRSB): case CFN_BUILT_IN_BSWAP32:
case BUILT_IN_BSWAP32: case CFN_BUILT_IN_BSWAP64:
case BUILT_IN_BSWAP64: /* Always true. */
/* Always true. */ return true;
return true;
CASE_FLT_FN (BUILT_IN_SQRT): CASE_CFN_SQRT:
/* sqrt(-0.0) is -0.0. */ /* sqrt(-0.0) is -0.0. */
if (!HONOR_SIGNED_ZEROS (element_mode (type))) if (!HONOR_SIGNED_ZEROS (element_mode (type)))
return true; return true;
return RECURSE (arg0); return RECURSE (arg0);
CASE_FLT_FN (BUILT_IN_ASINH): CASE_CFN_ASINH:
CASE_FLT_FN (BUILT_IN_ATAN): CASE_CFN_ATAN:
CASE_FLT_FN (BUILT_IN_ATANH): CASE_CFN_ATANH:
CASE_FLT_FN (BUILT_IN_CBRT): CASE_CFN_CBRT:
CASE_FLT_FN (BUILT_IN_CEIL): CASE_CFN_CEIL:
CASE_FLT_FN (BUILT_IN_ERF): CASE_CFN_ERF:
CASE_FLT_FN (BUILT_IN_EXPM1): CASE_CFN_EXPM1:
CASE_FLT_FN (BUILT_IN_FLOOR): CASE_CFN_FLOOR:
CASE_FLT_FN (BUILT_IN_FMOD): CASE_CFN_FMOD:
CASE_FLT_FN (BUILT_IN_FREXP): CASE_CFN_FREXP:
CASE_FLT_FN (BUILT_IN_ICEIL): CASE_CFN_ICEIL:
CASE_FLT_FN (BUILT_IN_IFLOOR): CASE_CFN_IFLOOR:
CASE_FLT_FN (BUILT_IN_IRINT): CASE_CFN_IRINT:
CASE_FLT_FN (BUILT_IN_IROUND): CASE_CFN_IROUND:
CASE_FLT_FN (BUILT_IN_LCEIL): CASE_CFN_LCEIL:
CASE_FLT_FN (BUILT_IN_LDEXP): CASE_CFN_LDEXP:
CASE_FLT_FN (BUILT_IN_LFLOOR): CASE_CFN_LFLOOR:
CASE_FLT_FN (BUILT_IN_LLCEIL): CASE_CFN_LLCEIL:
CASE_FLT_FN (BUILT_IN_LLFLOOR): CASE_CFN_LLFLOOR:
CASE_FLT_FN (BUILT_IN_LLRINT): CASE_CFN_LLRINT:
CASE_FLT_FN (BUILT_IN_LLROUND): CASE_CFN_LLROUND:
CASE_FLT_FN (BUILT_IN_LRINT): CASE_CFN_LRINT:
CASE_FLT_FN (BUILT_IN_LROUND): CASE_CFN_LROUND:
CASE_FLT_FN (BUILT_IN_MODF): CASE_CFN_MODF:
CASE_FLT_FN (BUILT_IN_NEARBYINT): CASE_CFN_NEARBYINT:
CASE_FLT_FN (BUILT_IN_RINT): CASE_CFN_RINT:
CASE_FLT_FN (BUILT_IN_ROUND): CASE_CFN_ROUND:
CASE_FLT_FN (BUILT_IN_SCALB): CASE_CFN_SCALB:
CASE_FLT_FN (BUILT_IN_SCALBLN): CASE_CFN_SCALBLN:
CASE_FLT_FN (BUILT_IN_SCALBN): CASE_CFN_SCALBN:
CASE_FLT_FN (BUILT_IN_SIGNBIT): CASE_CFN_SIGNBIT:
CASE_FLT_FN (BUILT_IN_SIGNIFICAND): CASE_CFN_SIGNIFICAND:
CASE_FLT_FN (BUILT_IN_SINH): CASE_CFN_SINH:
CASE_FLT_FN (BUILT_IN_TANH): CASE_CFN_TANH:
CASE_FLT_FN (BUILT_IN_TRUNC): CASE_CFN_TRUNC:
/* True if the 1st argument is nonnegative. */ /* True if the 1st argument is nonnegative. */
return RECURSE (arg0); return RECURSE (arg0);
CASE_FLT_FN (BUILT_IN_FMAX): CASE_CFN_FMAX:
/* True if the 1st OR 2nd arguments are nonnegative. */ /* True if the 1st OR 2nd arguments are nonnegative. */
return RECURSE (arg0) || RECURSE (arg1); return RECURSE (arg0) || RECURSE (arg1);
CASE_FLT_FN (BUILT_IN_FMIN): CASE_CFN_FMIN:
/* True if the 1st AND 2nd arguments are nonnegative. */ /* True if the 1st AND 2nd arguments are nonnegative. */
return RECURSE (arg0) && RECURSE (arg1); return RECURSE (arg0) && RECURSE (arg1);
CASE_FLT_FN (BUILT_IN_COPYSIGN): CASE_CFN_COPYSIGN:
/* True if the 2nd argument is nonnegative. */ /* True if the 2nd argument is nonnegative. */
return RECURSE (arg1); return RECURSE (arg1);
CASE_FLT_FN (BUILT_IN_POWI): CASE_CFN_POWI:
/* True if the 1st argument is nonnegative or the second /* True if the 1st argument is nonnegative or the second
argument is an even integer. */ argument is an even integer. */
if (TREE_CODE (arg1) == INTEGER_CST if (TREE_CODE (arg1) == INTEGER_CST
&& (TREE_INT_CST_LOW (arg1) & 1) == 0) && (TREE_INT_CST_LOW (arg1) & 1) == 0)
return true; return true;
return RECURSE (arg0); return RECURSE (arg0);
CASE_FLT_FN (BUILT_IN_POW): CASE_CFN_POW:
/* True if the 1st argument is nonnegative or the second /* True if the 1st argument is nonnegative or the second
argument is an even integer valued real. */ argument is an even integer valued real. */
if (TREE_CODE (arg1) == REAL_CST) if (TREE_CODE (arg1) == REAL_CST)
{ {
REAL_VALUE_TYPE c; REAL_VALUE_TYPE c;
HOST_WIDE_INT n; HOST_WIDE_INT n;
c = TREE_REAL_CST (arg1); c = TREE_REAL_CST (arg1);
n = real_to_integer (&c); n = real_to_integer (&c);
if ((n & 1) == 0) if ((n & 1) == 0)
{ {
REAL_VALUE_TYPE cint; REAL_VALUE_TYPE cint;
real_from_integer (&cint, VOIDmode, n, SIGNED); real_from_integer (&cint, VOIDmode, n, SIGNED);
if (real_identical (&c, &cint)) if (real_identical (&c, &cint))
return true; return true;
} }
} }
return RECURSE (arg0); return RECURSE (arg0);
default: default:
break; break;
} }
return tree_simple_nonnegative_warnv_p (CALL_EXPR, type); return tree_simple_nonnegative_warnv_p (CALL_EXPR, type);
} }
...@@ -13079,7 +13079,7 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth) ...@@ -13079,7 +13079,7 @@ tree_invalid_nonnegative_warnv_p (tree t, bool *strict_overflow_p, int depth)
tree arg1 = call_expr_nargs (t) > 1 ? CALL_EXPR_ARG (t, 1) : NULL_TREE; tree arg1 = call_expr_nargs (t) > 1 ? CALL_EXPR_ARG (t, 1) : NULL_TREE;
return tree_call_nonnegative_warnv_p (TREE_TYPE (t), return tree_call_nonnegative_warnv_p (TREE_TYPE (t),
get_callee_fndecl (t), get_call_combined_fn (t),
arg0, arg0,
arg1, arg1,
strict_overflow_p, depth); strict_overflow_p, depth);
...@@ -13482,26 +13482,25 @@ integer_valued_real_binary_p (tree_code code, tree op0, tree op1, int depth) ...@@ -13482,26 +13482,25 @@ integer_valued_real_binary_p (tree_code code, tree op0, tree op1, int depth)
DEPTH is the current nesting depth of the query. */ DEPTH is the current nesting depth of the query. */
bool bool
integer_valued_real_call_p (tree fndecl, tree arg0, tree arg1, int depth) integer_valued_real_call_p (combined_fn fn, tree arg0, tree arg1, int depth)
{ {
if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) switch (fn)
switch (DECL_FUNCTION_CODE (fndecl)) {
{ CASE_CFN_CEIL:
CASE_FLT_FN (BUILT_IN_CEIL): CASE_CFN_FLOOR:
CASE_FLT_FN (BUILT_IN_FLOOR): CASE_CFN_NEARBYINT:
CASE_FLT_FN (BUILT_IN_NEARBYINT): CASE_CFN_RINT:
CASE_FLT_FN (BUILT_IN_RINT): CASE_CFN_ROUND:
CASE_FLT_FN (BUILT_IN_ROUND): CASE_CFN_TRUNC:
CASE_FLT_FN (BUILT_IN_TRUNC): return true;
return true;
CASE_FLT_FN (BUILT_IN_FMIN): CASE_CFN_FMIN:
CASE_FLT_FN (BUILT_IN_FMAX): CASE_CFN_FMAX:
return RECURSE (arg0) && RECURSE (arg1); return RECURSE (arg0) && RECURSE (arg1);
default: default:
break; break;
} }
return false; return false;
} }
...@@ -13612,7 +13611,7 @@ integer_valued_real_p (tree t, int depth) ...@@ -13612,7 +13611,7 @@ integer_valued_real_p (tree t, int depth)
tree arg1 = (call_expr_nargs (t) > 1 tree arg1 = (call_expr_nargs (t) > 1
? CALL_EXPR_ARG (t, 1) ? CALL_EXPR_ARG (t, 1)
: NULL_TREE); : NULL_TREE);
return integer_valued_real_call_p (get_callee_fndecl (t), return integer_valued_real_call_p (get_call_combined_fn (t),
arg0, arg1, depth); arg0, arg1, depth);
} }
......
...@@ -137,12 +137,12 @@ extern bool tree_unary_nonnegative_warnv_p (enum tree_code, tree, tree, ...@@ -137,12 +137,12 @@ extern bool tree_unary_nonnegative_warnv_p (enum tree_code, tree, tree,
extern bool tree_binary_nonnegative_warnv_p (enum tree_code, tree, tree, tree, extern bool tree_binary_nonnegative_warnv_p (enum tree_code, tree, tree, tree,
bool *, int); bool *, int);
extern bool tree_single_nonnegative_warnv_p (tree, bool *, int); extern bool tree_single_nonnegative_warnv_p (tree, bool *, int);
extern bool tree_call_nonnegative_warnv_p (tree, tree, tree, tree, bool *, extern bool tree_call_nonnegative_warnv_p (tree, combined_fn, tree, tree,
int); bool *, int);
extern bool integer_valued_real_unary_p (tree_code, tree, int); extern bool integer_valued_real_unary_p (tree_code, tree, int);
extern bool integer_valued_real_binary_p (tree_code, tree, tree, int); extern bool integer_valued_real_binary_p (tree_code, tree, tree, int);
extern bool integer_valued_real_call_p (tree, tree, tree, int); extern bool integer_valued_real_call_p (combined_fn, tree, tree, int);
extern bool integer_valued_real_single_p (tree, int); extern bool integer_valued_real_single_p (tree, int);
extern bool integer_valued_real_p (tree, int = 0); extern bool integer_valued_real_p (tree, int = 0);
...@@ -179,7 +179,7 @@ extern tree sign_bit_p (tree, const_tree); ...@@ -179,7 +179,7 @@ extern tree sign_bit_p (tree, const_tree);
extern tree exact_inverse (tree, tree); extern tree exact_inverse (tree, tree);
extern tree const_unop (enum tree_code, tree, tree); extern tree const_unop (enum tree_code, tree, tree);
extern tree const_binop (enum tree_code, tree, tree, tree); extern tree const_binop (enum tree_code, tree, tree, tree);
extern bool negate_mathfn_p (enum built_in_function); extern bool negate_mathfn_p (combined_fn);
extern const char *c_getstr (tree); extern const char *c_getstr (tree);
/* Return OFF converted to a pointer offset type suitable as offset for /* Return OFF converted to a pointer offset type suitable as offset for
......
...@@ -6202,7 +6202,7 @@ gimple_call_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p, ...@@ -6202,7 +6202,7 @@ gimple_call_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p,
gimple_call_arg (stmt, 1) : NULL_TREE; gimple_call_arg (stmt, 1) : NULL_TREE;
return tree_call_nonnegative_warnv_p (gimple_expr_type (stmt), return tree_call_nonnegative_warnv_p (gimple_expr_type (stmt),
gimple_call_fndecl (stmt), gimple_call_combined_fn (stmt),
arg0, arg0,
arg1, arg1,
strict_overflow_p, depth); strict_overflow_p, depth);
...@@ -6295,7 +6295,7 @@ gimple_call_integer_valued_real_p (gimple *stmt, int depth) ...@@ -6295,7 +6295,7 @@ gimple_call_integer_valued_real_p (gimple *stmt, int depth)
tree arg1 = (gimple_call_num_args (stmt) > 1 tree arg1 = (gimple_call_num_args (stmt) > 1
? gimple_call_arg (stmt, 1) ? gimple_call_arg (stmt, 1)
: NULL_TREE); : NULL_TREE);
return integer_valued_real_call_p (gimple_call_fndecl (stmt), return integer_valued_real_call_p (gimple_call_combined_fn (stmt),
arg0, arg1, depth); arg0, arg1, depth);
} }
......
...@@ -102,6 +102,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -102,6 +102,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-fold.h" #include "gimple-fold.h"
#include "alloc-pool.h" #include "alloc-pool.h"
#include "tree-hash-traits.h" #include "tree-hash-traits.h"
#include "case-cfn-macros.h"
namespace { namespace {
...@@ -337,26 +338,29 @@ backprop::pop_from_worklist () ...@@ -337,26 +338,29 @@ backprop::pop_from_worklist ()
void void
backprop::process_builtin_call_use (gcall *call, tree rhs, usage_info *info) backprop::process_builtin_call_use (gcall *call, tree rhs, usage_info *info)
{ {
enum built_in_function fn = DECL_FUNCTION_CODE (gimple_call_fndecl (call)); combined_fn fn = gimple_call_combined_fn (call);
tree lhs = gimple_call_lhs (call); tree lhs = gimple_call_lhs (call);
switch (fn) switch (fn)
{ {
CASE_FLT_FN (BUILT_IN_COS): case CFN_LAST:
CASE_FLT_FN (BUILT_IN_COSH): break;
CASE_FLT_FN (BUILT_IN_CCOS):
CASE_FLT_FN (BUILT_IN_CCOSH): CASE_CFN_COS:
CASE_FLT_FN (BUILT_IN_HYPOT): CASE_CFN_COSH:
CASE_CFN_CCOS:
CASE_CFN_CCOSH:
CASE_CFN_HYPOT:
/* The signs of all inputs are ignored. */ /* The signs of all inputs are ignored. */
info->flags.ignore_sign = true; info->flags.ignore_sign = true;
break; break;
CASE_FLT_FN (BUILT_IN_COPYSIGN): CASE_CFN_COPYSIGN:
/* The sign of the first input is ignored. */ /* The sign of the first input is ignored. */
if (rhs != gimple_call_arg (call, 1)) if (rhs != gimple_call_arg (call, 1))
info->flags.ignore_sign = true; info->flags.ignore_sign = true;
break; break;
CASE_FLT_FN (BUILT_IN_POW): CASE_CFN_POW:
{ {
/* The sign of the first input is ignored as long as the second /* The sign of the first input is ignored as long as the second
input is an even real. */ input is an even real. */
...@@ -369,7 +373,7 @@ backprop::process_builtin_call_use (gcall *call, tree rhs, usage_info *info) ...@@ -369,7 +373,7 @@ backprop::process_builtin_call_use (gcall *call, tree rhs, usage_info *info)
break; break;
} }
CASE_FLT_FN (BUILT_IN_FMA): CASE_CFN_FMA:
/* In X * X + Y, where Y is distinct from X, the sign of X doesn't /* In X * X + Y, where Y is distinct from X, the sign of X doesn't
matter. */ matter. */
if (gimple_call_arg (call, 0) == rhs if (gimple_call_arg (call, 0) == rhs
...@@ -472,10 +476,7 @@ backprop::process_use (gimple *stmt, tree rhs, usage_info *info) ...@@ -472,10 +476,7 @@ backprop::process_use (gimple *stmt, tree rhs, usage_info *info)
} }
if (gcall *call = dyn_cast <gcall *> (stmt)) if (gcall *call = dyn_cast <gcall *> (stmt))
{ process_builtin_call_use (call, rhs, info);
if (gimple_call_builtin_p (call, BUILT_IN_NORMAL))
process_builtin_call_use (call, rhs, info);
}
else if (gassign *assign = dyn_cast <gassign *> (stmt)) else if (gassign *assign = dyn_cast <gassign *> (stmt))
process_assign_use (assign, rhs, info); process_assign_use (assign, rhs, info);
else if (gphi *phi = dyn_cast <gphi *> (stmt)) else if (gphi *phi = dyn_cast <gphi *> (stmt))
...@@ -686,17 +687,14 @@ strip_sign_op_1 (tree rhs) ...@@ -686,17 +687,14 @@ strip_sign_op_1 (tree rhs)
break; break;
} }
else if (gcall *call = dyn_cast <gcall *> (def_stmt)) else if (gcall *call = dyn_cast <gcall *> (def_stmt))
{ switch (gimple_call_combined_fn (call))
if (gimple_call_builtin_p (call, BUILT_IN_NORMAL)) {
switch (DECL_FUNCTION_CODE (gimple_call_fndecl (call))) CASE_CFN_COPYSIGN:
{ return gimple_call_arg (call, 0);
CASE_FLT_FN (BUILT_IN_COPYSIGN):
return gimple_call_arg (call, 0); default:
break;
default: }
break;
}
}
return NULL_TREE; return NULL_TREE;
} }
...@@ -758,11 +756,10 @@ backprop::complete_change (gimple *stmt) ...@@ -758,11 +756,10 @@ backprop::complete_change (gimple *stmt)
void void
backprop::optimize_builtin_call (gcall *call, tree lhs, const usage_info *info) backprop::optimize_builtin_call (gcall *call, tree lhs, const usage_info *info)
{ {
tree fndecl = gimple_call_fndecl (call);
enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
/* If we have an f such that -f(x) = f(-x), and if the sign of the result /* If we have an f such that -f(x) = f(-x), and if the sign of the result
doesn't matter, strip any sign operations from the input. */ doesn't matter, strip any sign operations from the input. */
if (info->flags.ignore_sign && negate_mathfn_p (fn)) if (info->flags.ignore_sign
&& negate_mathfn_p (gimple_call_combined_fn (call)))
{ {
tree new_arg = strip_sign_op (gimple_call_arg (call, 0)); tree new_arg = strip_sign_op (gimple_call_arg (call, 0));
if (new_arg) if (new_arg)
...@@ -889,10 +886,7 @@ backprop::execute () ...@@ -889,10 +886,7 @@ backprop::execute ()
tree var = m_vars[i].first; tree var = m_vars[i].first;
gimple *stmt = SSA_NAME_DEF_STMT (var); gimple *stmt = SSA_NAME_DEF_STMT (var);
if (gcall *call = dyn_cast <gcall *> (stmt)) if (gcall *call = dyn_cast <gcall *> (stmt))
{ optimize_builtin_call (call, var, info);
if (gimple_call_builtin_p (call, BUILT_IN_NORMAL))
optimize_builtin_call (call, var, info);
}
else if (gassign *assign = dyn_cast <gassign *> (stmt)) else if (gassign *assign = dyn_cast <gassign *> (stmt))
optimize_assign (assign, var, info); optimize_assign (assign, var, info);
else if (gphi *phi = dyn_cast <gphi *> (stmt)) else if (gphi *phi = dyn_cast <gphi *> (stmt))
......
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