Move constant bitop and bswap folds to fold-const-call.c
The only folds left in builtins.c were for constants, so we can remove the builtins.c handling entirely. Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi. gcc/ * builtins.c (fold_builtin_bitop, fold_builtin_bswap): Delete. (fold_builtin_1): Don't call them. * fold-const-call.c: Include tm.h. (fold_const_call_ss): New variant for integer-to-integer folds. (fold_const_call): Call it. From-SVN: r229921
This commit is contained in:
parent
2556a032cc
commit
db9bd5d575
3 changed files with 84 additions and 107 deletions
|
@ -1,3 +1,11 @@
|
|||
2015-11-07 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* builtins.c (fold_builtin_bitop, fold_builtin_bswap): Delete.
|
||||
(fold_builtin_1): Don't call them.
|
||||
* fold-const-call.c: Include tm.h.
|
||||
(fold_const_call_ss): New variant for integer-to-integer folds.
|
||||
(fold_const_call): Call it.
|
||||
|
||||
2015-11-07 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* builtins.c (fold_builtin_classify): Move constant cases to...
|
||||
|
|
107
gcc/builtins.c
107
gcc/builtins.c
|
@ -148,7 +148,6 @@ static tree rewrite_call_expr (location_t, tree, int, tree, int, ...);
|
|||
static bool validate_arg (const_tree, enum tree_code code);
|
||||
static rtx expand_builtin_fabs (tree, rtx, rtx);
|
||||
static rtx expand_builtin_signbit (tree, rtx);
|
||||
static tree fold_builtin_bitop (tree, tree);
|
||||
static tree fold_builtin_strchr (location_t, tree, tree, tree);
|
||||
static tree fold_builtin_memchr (location_t, tree, tree, tree, tree);
|
||||
static tree fold_builtin_memcmp (location_t, tree, tree, tree);
|
||||
|
@ -7332,99 +7331,6 @@ fold_builtin_sincos (location_t loc,
|
|||
fold_build1_loc (loc, REALPART_EXPR, type, call)));
|
||||
}
|
||||
|
||||
/* Fold function call to builtin ffs, clz, ctz, popcount and parity
|
||||
and their long and long long variants (i.e. ffsl and ffsll). ARG is
|
||||
the argument to the call. Return NULL_TREE if no simplification can
|
||||
be made. */
|
||||
|
||||
static tree
|
||||
fold_builtin_bitop (tree fndecl, tree arg)
|
||||
{
|
||||
if (!validate_arg (arg, INTEGER_TYPE))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Optimize for constant argument. */
|
||||
if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
|
||||
{
|
||||
tree type = TREE_TYPE (arg);
|
||||
int result;
|
||||
|
||||
switch (DECL_FUNCTION_CODE (fndecl))
|
||||
{
|
||||
CASE_INT_FN (BUILT_IN_FFS):
|
||||
result = wi::ffs (arg);
|
||||
break;
|
||||
|
||||
CASE_INT_FN (BUILT_IN_CLZ):
|
||||
if (wi::ne_p (arg, 0))
|
||||
result = wi::clz (arg);
|
||||
else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
|
||||
result = TYPE_PRECISION (type);
|
||||
break;
|
||||
|
||||
CASE_INT_FN (BUILT_IN_CTZ):
|
||||
if (wi::ne_p (arg, 0))
|
||||
result = wi::ctz (arg);
|
||||
else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (type), result))
|
||||
result = TYPE_PRECISION (type);
|
||||
break;
|
||||
|
||||
CASE_INT_FN (BUILT_IN_CLRSB):
|
||||
result = wi::clrsb (arg);
|
||||
break;
|
||||
|
||||
CASE_INT_FN (BUILT_IN_POPCOUNT):
|
||||
result = wi::popcount (arg);
|
||||
break;
|
||||
|
||||
CASE_INT_FN (BUILT_IN_PARITY):
|
||||
result = wi::parity (arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), result);
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Fold function call to builtin_bswap and the short, long and long long
|
||||
variants. Return NULL_TREE if no simplification can be made. */
|
||||
static tree
|
||||
fold_builtin_bswap (tree fndecl, tree arg)
|
||||
{
|
||||
if (! validate_arg (arg, INTEGER_TYPE))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Optimize constant value. */
|
||||
if (TREE_CODE (arg) == INTEGER_CST && !TREE_OVERFLOW (arg))
|
||||
{
|
||||
tree type = TREE_TYPE (TREE_TYPE (fndecl));
|
||||
|
||||
switch (DECL_FUNCTION_CODE (fndecl))
|
||||
{
|
||||
case BUILT_IN_BSWAP16:
|
||||
case BUILT_IN_BSWAP32:
|
||||
case BUILT_IN_BSWAP64:
|
||||
{
|
||||
signop sgn = TYPE_SIGN (type);
|
||||
tree result =
|
||||
wide_int_to_tree (type,
|
||||
wide_int::from (arg, TYPE_PRECISION (type),
|
||||
sgn).bswap ());
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Fold function call to builtin memchr. ARG1, ARG2 and LEN are the
|
||||
arguments to the call, and TYPE is its return type.
|
||||
Return NULL_TREE if no simplification can be made. */
|
||||
|
@ -8364,19 +8270,6 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0)
|
|||
CASE_FLT_FN (BUILT_IN_NANS):
|
||||
return fold_builtin_nan (arg0, type, false);
|
||||
|
||||
case BUILT_IN_BSWAP16:
|
||||
case BUILT_IN_BSWAP32:
|
||||
case BUILT_IN_BSWAP64:
|
||||
return fold_builtin_bswap (fndecl, arg0);
|
||||
|
||||
CASE_INT_FN (BUILT_IN_FFS):
|
||||
CASE_INT_FN (BUILT_IN_CLZ):
|
||||
CASE_INT_FN (BUILT_IN_CTZ):
|
||||
CASE_INT_FN (BUILT_IN_CLRSB):
|
||||
CASE_INT_FN (BUILT_IN_POPCOUNT):
|
||||
CASE_INT_FN (BUILT_IN_PARITY):
|
||||
return fold_builtin_bitop (fndecl, arg0);
|
||||
|
||||
case BUILT_IN_ISASCII:
|
||||
return fold_builtin_isascii (loc, arg0);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "stor-layout.h"
|
||||
#include "options.h"
|
||||
#include "fold-const-call.h"
|
||||
#include "tm.h" /* For C[LT]Z_DEFINED_AT_ZERO. */
|
||||
|
||||
/* Functions that test for certain constant types, abstracting away the
|
||||
decision about whether to check for overflow. */
|
||||
|
@ -766,6 +767,69 @@ fold_const_call_ss (wide_int *result, built_in_function fn,
|
|||
}
|
||||
}
|
||||
|
||||
/* Try to evaluate:
|
||||
|
||||
*RESULT = FN (ARG)
|
||||
|
||||
where ARG_TYPE is the type of ARG and PRECISION is the number of bits
|
||||
in the result. Return true on success. */
|
||||
|
||||
static bool
|
||||
fold_const_call_ss (wide_int *result, built_in_function fn,
|
||||
const wide_int_ref &arg, unsigned int precision,
|
||||
tree arg_type)
|
||||
{
|
||||
switch (fn)
|
||||
{
|
||||
CASE_INT_FN (BUILT_IN_FFS):
|
||||
*result = wi::shwi (wi::ffs (arg), precision);
|
||||
return true;
|
||||
|
||||
CASE_INT_FN (BUILT_IN_CLZ):
|
||||
{
|
||||
int tmp;
|
||||
if (wi::ne_p (arg, 0))
|
||||
tmp = wi::clz (arg);
|
||||
else if (! CLZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (arg_type), tmp))
|
||||
tmp = TYPE_PRECISION (arg_type);
|
||||
*result = wi::shwi (tmp, precision);
|
||||
return true;
|
||||
}
|
||||
|
||||
CASE_INT_FN (BUILT_IN_CTZ):
|
||||
{
|
||||
int tmp;
|
||||
if (wi::ne_p (arg, 0))
|
||||
tmp = wi::ctz (arg);
|
||||
else if (! CTZ_DEFINED_VALUE_AT_ZERO (TYPE_MODE (arg_type), tmp))
|
||||
tmp = TYPE_PRECISION (arg_type);
|
||||
*result = wi::shwi (tmp, precision);
|
||||
return true;
|
||||
}
|
||||
|
||||
CASE_INT_FN (BUILT_IN_CLRSB):
|
||||
*result = wi::shwi (wi::clrsb (arg), precision);
|
||||
return true;
|
||||
|
||||
CASE_INT_FN (BUILT_IN_POPCOUNT):
|
||||
*result = wi::shwi (wi::popcount (arg), precision);
|
||||
return true;
|
||||
|
||||
CASE_INT_FN (BUILT_IN_PARITY):
|
||||
*result = wi::shwi (wi::parity (arg), precision);
|
||||
return true;
|
||||
|
||||
case BUILT_IN_BSWAP16:
|
||||
case BUILT_IN_BSWAP32:
|
||||
case BUILT_IN_BSWAP64:
|
||||
*result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to evaluate:
|
||||
|
||||
RESULT = FN (*ARG)
|
||||
|
@ -916,6 +980,18 @@ fold_const_call (built_in_function fn, tree type, tree arg)
|
|||
machine_mode mode = TYPE_MODE (type);
|
||||
machine_mode arg_mode = TYPE_MODE (TREE_TYPE (arg));
|
||||
|
||||
if (integer_cst_p (arg))
|
||||
{
|
||||
if (SCALAR_INT_MODE_P (mode))
|
||||
{
|
||||
wide_int result;
|
||||
if (fold_const_call_ss (&result, fn, arg, TYPE_PRECISION (type),
|
||||
TREE_TYPE (arg)))
|
||||
return wide_int_to_tree (type, result);
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (real_cst_p (arg))
|
||||
{
|
||||
gcc_checking_assert (SCALAR_FLOAT_MODE_P (arg_mode));
|
||||
|
|
Loading…
Add table
Reference in a new issue