OSDN Git Service

* fold-const.c (fold_relational_hi_lo): Delete function and prototype.
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 16 Apr 2005 01:59:11 +0000 (01:59 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 16 Apr 2005 01:59:11 +0000 (01:59 +0000)
(fold_binary): Update comment mentioning fold_relational_hi_lo.
(fold_binary_to_constant): Simplify using fold_binary.
(fold_unary_to_constant): Likewise, simplify using fold_unary.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98220 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c

index b7448c7..f3ba578 100644 (file)
@@ -1,3 +1,10 @@
+2005-04-15  Roger Sayle  <roger@eyesopen.com>
+
+       * fold-const.c (fold_relational_hi_lo): Delete function and prototype.
+       (fold_binary): Update comment mentioning fold_relational_hi_lo.
+       (fold_binary_to_constant): Simplify using fold_binary.
+       (fold_unary_to_constant): Likewise, simplify using fold_unary.
+
 2005-04-15  Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>
 
        * gthr-posix.c (pthread_cancel): Define.
index 9487d3c..e9b0e21 100644 (file)
@@ -133,8 +133,6 @@ static bool reorder_operands_p (tree, tree);
 static tree fold_negate_const (tree, tree);
 static tree fold_not_const (tree, tree);
 static tree fold_relational_const (enum tree_code, tree, tree, tree);
-static tree fold_relational_hi_lo (enum tree_code *, const tree,
-                                   tree *, tree *);
 static bool tree_expr_nonzero_p (tree);
 
 /* We know that A1 + B1 = SUM1, using 2's complement arithmetic and ignoring
@@ -9033,10 +9031,7 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
        }
 
       /* Comparisons with the highest or lowest possible integer of
-        the specified size will have known values.
-
-        This is quite similar to fold_relational_hi_lo, however,
-        attempts to share the code have been nothing but trouble.  */
+        the specified size will have known values.  */
       {
        int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (arg1)));
 
@@ -10793,155 +10788,6 @@ tree_expr_nonzero_p (tree t)
   return false;
 }
 
-/* See if we are applying CODE, a relational to the highest or lowest
-   possible integer of TYPE.  If so, then the result is a compile
-   time constant.  */
-
-static tree
-fold_relational_hi_lo (enum tree_code *code_p, const tree type, tree *op0_p,
-                      tree *op1_p)
-{
-  tree op0 = *op0_p;
-  tree op1 = *op1_p;
-  enum tree_code code = *code_p;
-  int width = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (op1)));
-
-  if (TREE_CODE (op1) == INTEGER_CST
-      && ! TREE_CONSTANT_OVERFLOW (op1)
-      && width <= HOST_BITS_PER_WIDE_INT
-      && (INTEGRAL_TYPE_P (TREE_TYPE (op1))
-         || POINTER_TYPE_P (TREE_TYPE (op1))))
-    {
-      unsigned HOST_WIDE_INT signed_max;
-      unsigned HOST_WIDE_INT max, min;
-
-      signed_max = ((unsigned HOST_WIDE_INT) 1 << (width - 1)) - 1;
-
-      if (TYPE_UNSIGNED (TREE_TYPE (op1)))
-        {
-          max = ((unsigned HOST_WIDE_INT) 2 << (width - 1)) - 1;
-         min = 0;
-       }
-      else
-        {
-          max = signed_max;
-         min = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
-       }
-
-      if (TREE_INT_CST_HIGH (op1) == 0
-         && TREE_INT_CST_LOW (op1) == max)
-       switch (code)
-         {
-         case GT_EXPR:
-           return omit_one_operand (type, integer_zero_node, op0);
-
-         case GE_EXPR:
-           *code_p = EQ_EXPR;
-           break;
-         case LE_EXPR:
-           return omit_one_operand (type, integer_one_node, op0);
-
-         case LT_EXPR:
-           *code_p = NE_EXPR;
-           break;
-
-         /* The GE_EXPR and LT_EXPR cases above are not normally
-            reached because of  previous transformations.  */
-
-         default:
-           break;
-         }
-      else if (TREE_INT_CST_HIGH (op1) == 0
-              && TREE_INT_CST_LOW (op1) == max - 1)
-       switch (code)
-         {
-         case GT_EXPR:
-           *code_p = EQ_EXPR;
-           *op1_p = const_binop (PLUS_EXPR, op1, integer_one_node, 0);
-           break;
-         case LE_EXPR:
-           *code_p = NE_EXPR;
-           *op1_p = const_binop (PLUS_EXPR, op1, integer_one_node, 0);
-           break;
-         default:
-           break;
-         }
-      else if (TREE_INT_CST_HIGH (op1) == (min ? -1 : 0)
-              && TREE_INT_CST_LOW (op1) == min)
-       switch (code)
-         {
-         case LT_EXPR:
-           return omit_one_operand (type, integer_zero_node, op0);
-
-         case LE_EXPR:
-           *code_p = EQ_EXPR;
-           break;
-
-         case GE_EXPR:
-           return omit_one_operand (type, integer_one_node, op0);
-
-         case GT_EXPR:
-           *code_p = NE_EXPR;
-           break;
-
-         default:
-           break;
-         }
-      else if (TREE_INT_CST_HIGH (op1) == (min ? -1 : 0)
-              && TREE_INT_CST_LOW (op1) == min + 1)
-       switch (code)
-         {
-         case GE_EXPR:
-           *code_p = NE_EXPR;
-           *op1_p = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
-           break;
-         case LT_EXPR:
-           *code_p = EQ_EXPR;
-           *op1_p = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
-           break;
-         default:
-           break;
-         }
-
-      else if (TREE_INT_CST_HIGH (op1) == 0
-              && TREE_INT_CST_LOW (op1) == signed_max
-              && TYPE_UNSIGNED (TREE_TYPE (op1))
-              /* signed_type does not work on pointer types.  */
-              && INTEGRAL_TYPE_P (TREE_TYPE (op1)))
-       {
-         /* The following case also applies to X < signed_max+1
-            and X >= signed_max+1 because previous transformations.  */
-         if (code == LE_EXPR || code == GT_EXPR)
-           {
-             tree st0, st1, exp, retval;
-             st0 = lang_hooks.types.signed_type (TREE_TYPE (op0));
-             st1 = lang_hooks.types.signed_type (TREE_TYPE (op1));
-
-             exp = build2 (code == LE_EXPR ? GE_EXPR: LT_EXPR,
-                           type,
-                           fold_convert (st0, op0),
-                           fold_convert (st1, integer_zero_node));
-
-             retval = fold_binary_to_constant (TREE_CODE (exp),
-                                               TREE_TYPE (exp),
-                                               TREE_OPERAND (exp, 0),
-                                               TREE_OPERAND (exp, 1));
-
-             /* If we are in gimple form, then returning EXP would create
-                non-gimple expressions.  Clearing it is safe and insures
-                we do not allow a non-gimple expression to escape.  */
-             if (in_gimple_form)
-               exp = NULL;
-
-             return (retval ? retval : exp);
-           }
-       }
-    }
-
-  return NULL_TREE;
-}
-
-
 /* Given the components of a binary expression CODE, TYPE, OP0 and OP1,
    attempt to fold the expression to a constant without modifying TYPE,
    OP0 or OP1.
@@ -10958,282 +10804,8 @@ fold_relational_hi_lo (enum tree_code *code_p, const tree type, tree *op0_p,
 tree
 fold_binary_to_constant (enum tree_code code, tree type, tree op0, tree op1)
 {
-  int wins = 1;
-  tree subop0;
-  tree subop1;
-  tree tem;
-
-  /* If this is a commutative operation, and ARG0 is a constant, move it
-     to ARG1 to reduce the number of tests below.  */
-  if (commutative_tree_code (code)
-      && (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST))
-    {
-      tem = op0;
-      op0 = op1;
-      op1 = tem;
-    }
-
-  /* If either operand is a complex type, extract its real component.  */
-  if (TREE_CODE (op0) == COMPLEX_CST)
-    subop0 = TREE_REALPART (op0);
-  else
-    subop0 = op0;
-
-  if (TREE_CODE (op1) == COMPLEX_CST)
-    subop1 = TREE_REALPART (op1);
-  else
-    subop1 = op1;
-
-  /* Note if either argument is not a real or integer constant.
-     With a few exceptions, simplification is limited to cases
-     where both arguments are constants.  */
-  if ((TREE_CODE (subop0) != INTEGER_CST
-       && TREE_CODE (subop0) != REAL_CST)
-      || (TREE_CODE (subop1) != INTEGER_CST
-         && TREE_CODE (subop1) != REAL_CST))
-    wins = 0;
-
-  switch (code)
-    {
-    case PLUS_EXPR:
-      /* (plus (address) (const_int)) is a constant.  */
-      if (TREE_CODE (op0) == PLUS_EXPR
-         && TREE_CODE (op1) == INTEGER_CST
-         && (TREE_CODE (TREE_OPERAND (op0, 0)) == ADDR_EXPR
-             || (TREE_CODE (TREE_OPERAND (op0, 0)) == NOP_EXPR
-                 && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (op0, 0), 0))
-                     == ADDR_EXPR)))
-         && TREE_CODE (TREE_OPERAND (op0, 1)) == INTEGER_CST)
-       {
-          return build2 (PLUS_EXPR, type, TREE_OPERAND (op0, 0),
-                        const_binop (PLUS_EXPR, op1,
-                                     TREE_OPERAND (op0, 1), 0));
-       }
-    case BIT_XOR_EXPR:
-
-    binary:
-      if (!wins)
-       return NULL_TREE;
-
-      /* Both arguments are constants.  Simplify.  */
-      tem = const_binop (code, op0, op1, 0);
-      if (tem != NULL_TREE)
-       {
-         /* The return value should always have the same type as
-            the original expression.  */
-         if (TREE_TYPE (tem) != type)
-           tem = fold_convert (type, tem);
-
-         return tem;
-       }
-      return NULL_TREE;
-
-    case MINUS_EXPR:
-      /* Fold &x - &x.  This can happen from &x.foo - &x.
-         This is unsafe for certain floats even in non-IEEE formats.
-         In IEEE, it is unsafe because it does wrong for NaNs.
-         Also note that operand_equal_p is always false if an
-         operand is volatile.  */
-      if (! FLOAT_TYPE_P (type) && operand_equal_p (op0, op1, 0))
-       return fold_convert (type, integer_zero_node);
-
-      goto binary;
-
-    case MULT_EXPR:
-    case BIT_AND_EXPR:
-      /* Special case multiplication or bitwise AND where one argument
-        is zero.  */
-      if (! FLOAT_TYPE_P (type) && integer_zerop (op1))
-       return omit_one_operand (type, op1, op0);
-      else
-        if (!HONOR_NANS (TYPE_MODE (TREE_TYPE (op0)))
-           && !HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (op0)))
-           && real_zerop (op1))
-         return omit_one_operand (type, op1, op0);
-
-      goto binary;
-
-    case BIT_IOR_EXPR:
-      /* Special case when we know the result will be all ones.  */
-      if (integer_all_onesp (op1))
-       return omit_one_operand (type, op1, op0);
-
-      goto binary;
-
-    case TRUNC_DIV_EXPR:
-    case ROUND_DIV_EXPR:
-    case FLOOR_DIV_EXPR:
-    case CEIL_DIV_EXPR:
-    case EXACT_DIV_EXPR:
-    case TRUNC_MOD_EXPR:
-    case ROUND_MOD_EXPR:
-    case FLOOR_MOD_EXPR:
-    case CEIL_MOD_EXPR:
-    case RDIV_EXPR:
-      /* Division by zero is undefined.  */
-      if (integer_zerop (op1))
-       return NULL_TREE;
-
-      if (TREE_CODE (op1) == REAL_CST
-         && !MODE_HAS_INFINITIES (TYPE_MODE (TREE_TYPE (op1)))
-         && real_zerop (op1))
-       return NULL_TREE;
-
-      goto binary;
-
-    case MIN_EXPR:
-      if (INTEGRAL_TYPE_P (type)
-         && operand_equal_p (op1, TYPE_MIN_VALUE (type), OEP_ONLY_CONST))
-       return omit_one_operand (type, op1, op0);
-
-      goto binary;
-
-    case MAX_EXPR:
-      if (INTEGRAL_TYPE_P (type)
-         && TYPE_MAX_VALUE (type)
-         && operand_equal_p (op1, TYPE_MAX_VALUE (type), OEP_ONLY_CONST))
-       return omit_one_operand (type, op1, op0);
-
-      goto binary;
-
-    case RSHIFT_EXPR:
-      /* Optimize -1 >> x for arithmetic right shifts.  */
-      if (integer_all_onesp (op0) && ! TYPE_UNSIGNED (type))
-       return omit_one_operand (type, op0, op1);
-      /* ... fall through ...  */
-
-    case LSHIFT_EXPR:
-      if (integer_zerop (op0))
-       return omit_one_operand (type, op0, op1);
-
-      /* Since negative shift count is not well-defined, don't
-        try to compute it in the compiler.  */
-      if (TREE_CODE (op1) == INTEGER_CST && tree_int_cst_sgn (op1) < 0)
-       return NULL_TREE;
-
-      goto binary;
-
-    case LROTATE_EXPR:
-    case RROTATE_EXPR:
-      /* -1 rotated either direction by any amount is still -1.  */
-      if (integer_all_onesp (op0))
-       return omit_one_operand (type, op0, op1);
-
-      /* 0 rotated either direction by any amount is still zero.  */
-      if (integer_zerop (op0))
-       return omit_one_operand (type, op0, op1);
-
-      goto binary;
-
-    case COMPLEX_EXPR:
-      if (wins)
-       return build_complex (type, op0, op1);
-      return NULL_TREE;
-
-    case LT_EXPR:
-    case LE_EXPR:
-    case GT_EXPR:
-    case GE_EXPR:
-    case EQ_EXPR:
-    case NE_EXPR:
-      /* If one arg is a real or integer constant, put it last.  */
-      if ((TREE_CODE (op0) == INTEGER_CST
-          && TREE_CODE (op1) != INTEGER_CST)
-         || (TREE_CODE (op0) == REAL_CST
-             && TREE_CODE (op0) != REAL_CST))
-       {
-         tree temp;
-
-         temp = op0;
-         op0 = op1;
-         op1 = temp;
-         code = swap_tree_comparison (code);
-       }
-
-      /* Change X >= C to X > (C - 1) and X < C to X <= (C - 1) if C > 0.
-        This transformation affects the cases which are handled in later
-        optimizations involving comparisons with non-negative constants.  */
-      if (TREE_CODE (op1) == INTEGER_CST
-         && TREE_CODE (op0) != INTEGER_CST
-         && tree_int_cst_sgn (op1) > 0)
-       {
-         switch (code)
-           {
-           case GE_EXPR:
-             code = GT_EXPR;
-             op1 = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
-             break;
-
-           case LT_EXPR:
-             code = LE_EXPR;
-             op1 = const_binop (MINUS_EXPR, op1, integer_one_node, 0);
-             break;
-
-           default:
-             break;
-           }
-       }
-
-      tem = fold_relational_hi_lo (&code, type, &op0, &op1);
-      if (tem)
-       return tem;
-
-      /* Fall through.  */
-
-    case ORDERED_EXPR:
-    case UNORDERED_EXPR:
-    case UNLT_EXPR:
-    case UNLE_EXPR:
-    case UNGT_EXPR:
-    case UNGE_EXPR:
-    case UNEQ_EXPR:
-    case LTGT_EXPR:
-      if (!wins)
-       return NULL_TREE;
-
-      return fold_relational_const (code, type, op0, op1);
-
-    case RANGE_EXPR:
-      /* This could probably be handled.  */
-      return NULL_TREE;
-
-    case TRUTH_AND_EXPR:
-      /* If second arg is constant zero, result is zero, but first arg
-        must be evaluated.  */
-      if (integer_zerop (op1))
-       return omit_one_operand (type, op1, op0);
-      /* Likewise for first arg, but note that only the TRUTH_AND_EXPR
-        case will be handled here.  */
-      if (integer_zerop (op0))
-       return omit_one_operand (type, op0, op1);
-      if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
-       return constant_boolean_node (true, type);
-      return NULL_TREE;
-
-    case TRUTH_OR_EXPR:
-      /* If second arg is constant true, result is true, but we must
-        evaluate first arg.  */
-      if (TREE_CODE (op1) == INTEGER_CST && ! integer_zerop (op1))
-       return omit_one_operand (type, op1, op0);
-      /* Likewise for first arg, but note this only occurs here for
-        TRUTH_OR_EXPR.  */
-      if (TREE_CODE (op0) == INTEGER_CST && ! integer_zerop (op0))
-       return omit_one_operand (type, op0, op1);
-      if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
-       return constant_boolean_node (false, type);
-      return NULL_TREE;
-
-    case TRUTH_XOR_EXPR:
-      if (TREE_CODE (op0) == INTEGER_CST && TREE_CODE (op1) == INTEGER_CST)
-       {
-         int x = ! integer_zerop (op0) ^ ! integer_zerop (op1);
-         return constant_boolean_node (x, type);
-       }
-      return NULL_TREE;
-
-    default:
-      return NULL_TREE;
-    }
+  tree tem = fold_binary (code, type, op0, op1);
+  return (tem && TREE_CONSTANT (tem)) ? tem : NULL_TREE;
 }
 
 /* Given the components of a unary expression CODE, TYPE and OP0,
@@ -11252,71 +10824,8 @@ fold_binary_to_constant (enum tree_code code, tree type, tree op0, tree op1)
 tree
 fold_unary_to_constant (enum tree_code code, tree type, tree op0)
 {
-  /* Make sure we have a suitable constant argument.  */
-  if (code == NOP_EXPR || code == FLOAT_EXPR || code == CONVERT_EXPR)
-    {
-      tree subop;
-
-      if (TREE_CODE (op0) == COMPLEX_CST)
-       subop = TREE_REALPART (op0);
-      else
-       subop = op0;
-
-      if (TREE_CODE (subop) != INTEGER_CST && TREE_CODE (subop) != REAL_CST)
-       return NULL_TREE;
-    }
-
-  switch (code)
-    {
-    case NOP_EXPR:
-    case FLOAT_EXPR:
-    case CONVERT_EXPR:
-    case FIX_TRUNC_EXPR:
-    case FIX_FLOOR_EXPR:
-    case FIX_CEIL_EXPR:
-    case FIX_ROUND_EXPR:
-      return fold_convert_const (code, type, op0);
-
-    case NEGATE_EXPR:
-      if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
-       return fold_negate_const (op0, type);
-      else
-       return NULL_TREE;
-
-    case ABS_EXPR:
-      if (TREE_CODE (op0) == INTEGER_CST || TREE_CODE (op0) == REAL_CST)
-       return fold_abs_const (op0, type);
-      else
-       return NULL_TREE;
-
-    case BIT_NOT_EXPR:
-      if (TREE_CODE (op0) == INTEGER_CST)
-       return fold_not_const (op0, type);
-      else
-       return NULL_TREE;
-
-    case REALPART_EXPR:
-      if (TREE_CODE (op0) == COMPLEX_CST)
-       return TREE_REALPART (op0);
-      else
-       return NULL_TREE;
-
-    case IMAGPART_EXPR:
-      if (TREE_CODE (op0) == COMPLEX_CST)
-       return TREE_IMAGPART (op0);
-      else
-       return NULL_TREE;
-
-    case CONJ_EXPR:
-      if (TREE_CODE (op0) == COMPLEX_CST
-         && TREE_CODE (TREE_TYPE (op0)) == COMPLEX_TYPE)
-       return build_complex (type, TREE_REALPART (op0),
-                             negate_expr (TREE_IMAGPART (op0)));
-      return NULL_TREE;
-
-    default:
-      return NULL_TREE;
-    }
+  tree tem = fold_unary (code, type, op0);
+  return (tem && TREE_CONSTANT (tem)) ? tem : NULL_TREE;
 }
 
 /* If EXP represents referencing an element in a constant string