On November 6, 2015 4:12:56 PM GMT+01:00, Richard Sandiford 
<richard.sandif...@arm.com> wrote:
>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.
>OK to install?

OK.

>Thanks,
>Richard
>
>
>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.
>
>diff --git a/gcc/builtins.c b/gcc/builtins.c
>index 6eefd54..3f7fe3b 100644
>--- a/gcc/builtins.c
>+++ b/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);
> 
>diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
>index c277d2b..48e05a9 100644
>--- a/gcc/fold-const-call.c
>+++ b/gcc/fold-const-call.c
>@@ -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.  */
>@@ -768,6 +769,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)
> 
>  where FORMAT is the format of ARG and of the real and imaginary parts
>@@ -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));


Reply via email to