]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
fold-const.c (int_binop_types_match_p): New function.
authorRoger Sayle <roger@eyesopen.com>
Sun, 12 Nov 2006 02:57:10 +0000 (02:57 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Sun, 12 Nov 2006 02:57:10 +0000 (02:57 +0000)
* fold-const.c (int_binop_types_match_p): New function.
(size_binop): Relax constraint that both arguments must both have
exactly the same sizetype type.  Instead use int_binop_types_match_p.
(size_diffop): Likewise.

(make_range): Use build_int_cst instead of fold_convert.
(fold_cond_expr_with_comparison): Use build_int_cst to construct
integer constants of the correct type.
(fold_div_compare): Likewise.
(fold_single_bit_test): Likewise.
(fold_binary): Likewise.
* stor-layout.c (layout_type) <VECTOR_TYPE>: Ensure that TYPE_SIZE
has type bitsizetype and TYPE_SIZE_UNIT has type sizetype.

From-SVN: r118718

gcc/ChangeLog
gcc/fold-const.c
gcc/stor-layout.c

index 3cca0dcc2d364d757e952b6f62cc9530fd76fbdd..7a7013d4b5ea0f5c4eb496e499967ae23b543073 100644 (file)
@@ -1,3 +1,19 @@
+2006-11-11  Roger Sayle  <roger@eyesopen.com>
+
+       * fold-const.c (int_binop_types_match_p): New function.
+       (size_binop): Relax constraint that both arguments must both have
+       exactly the same sizetype type.  Instead use int_binop_types_match_p.
+       (size_diffop): Likewise.
+
+       (make_range): Use build_int_cst instead of fold_convert.
+       (fold_cond_expr_with_comparison): Use build_int_cst to construct
+       integer constants of the correct type.
+       (fold_div_compare): Likewise.
+       (fold_single_bit_test): Likewise.
+       (fold_binary): Likewise.
+       * stor-layout.c (layout_type) <VECTOR_TYPE>: Ensure that TYPE_SIZE
+       has type bitsizetype and TYPE_SIZE_UNIT has type sizetype.
+
 2006-11-11  Andrew Pinski  <andrew_pinski@playstation.sony.com>
 
        PR rtl-opt/28812
index b715ad8072fce6a7713d84a0991b0b31bf9c8d07..08e74a292f9b3db16c56fbea7e0a26db68a781a9 100644 (file)
@@ -1372,6 +1372,35 @@ associate_trees (tree t1, tree t2, enum tree_code code, tree type)
                      fold_convert (type, t2));
 }
 \f
+/* Check whether TYPE1 and TYPE2 are equivalent integer types, suitable
+   for use in int_const_binop, size_binop and size_diffop.  */
+
+static bool
+int_binop_types_match_p (enum tree_code code, tree type1, tree type2)
+{
+  if (TREE_CODE (type1) != INTEGER_TYPE && !POINTER_TYPE_P (type1))
+    return false;
+  if (TREE_CODE (type2) != INTEGER_TYPE && !POINTER_TYPE_P (type2))
+    return false;
+
+  switch (code)
+    {
+    case LSHIFT_EXPR:
+    case RSHIFT_EXPR:
+    case LROTATE_EXPR:
+    case RROTATE_EXPR:
+      return true;
+
+    default:
+      break;
+    }
+
+  return TYPE_UNSIGNED (type1) == TYPE_UNSIGNED (type2)
+        && TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
+        && TYPE_MODE (type1) == TYPE_MODE (type2);
+}
+
+
 /* Combine two integer constants ARG1 and ARG2 under operation CODE
    to produce a new constant.  Return NULL_TREE if we don't know how
    to evaluate CODE at compile-time.
@@ -1733,7 +1762,7 @@ size_int_kind (HOST_WIDE_INT number, enum size_type_kind kind)
 \f
 /* Combine operands OP1 and OP2 with arithmetic operation CODE.  CODE
    is a tree code.  The type of the result is taken from the operands.
-   Both must be the same type integer type and it must be a size type.
+   Both must be equivalent integer types, ala int_binop_types_match_p.
    If the operands are constant, so is the result.  */
 
 tree
@@ -1744,8 +1773,8 @@ size_binop (enum tree_code code, tree arg0, tree arg1)
   if (arg0 == error_mark_node || arg1 == error_mark_node)
     return error_mark_node;
 
-  gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
-             && type == TREE_TYPE (arg1));
+  gcc_assert (int_binop_types_match_p (code, TREE_TYPE (arg0),
+                                       TREE_TYPE (arg1)));
 
   /* Handle the special case of two integer constants faster.  */
   if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
@@ -1776,14 +1805,19 @@ size_diffop (tree arg0, tree arg1)
   tree type = TREE_TYPE (arg0);
   tree ctype;
 
-  gcc_assert (TREE_CODE (type) == INTEGER_TYPE && TYPE_IS_SIZETYPE (type)
-             && type == TREE_TYPE (arg1));
+  gcc_assert (int_binop_types_match_p (MINUS_EXPR, TREE_TYPE (arg0),
+                                      TREE_TYPE (arg1)));
 
   /* If the type is already signed, just do the simple thing.  */
   if (!TYPE_UNSIGNED (type))
     return size_binop (MINUS_EXPR, arg0, arg1);
 
-  ctype = type == bitsizetype ? sbitsizetype : ssizetype;
+  if (type == sizetype)
+    ctype = ssizetype;
+  else if (type == bitsizetype)
+    ctype = sbitsizetype;
+  else
+    ctype = lang_hooks.types.signed_type (type);
 
   /* If either operand is not a constant, do the conversions to the signed
      type and subtract.  The hardware will do the right thing with any
@@ -3978,8 +4012,7 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh)
                high_positive = fold_build2 (RSHIFT_EXPR, arg0_type,
                                             fold_convert (arg0_type,
                                                           high_positive),
-                                            fold_convert (arg0_type,
-                                                          integer_one_node));
+                                            build_int_cst (arg0_type, 1));
 
              /* If the low bound is specified, "and" the range with the
                 range for which the original unsigned value will be
@@ -4625,7 +4658,7 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
                               OEP_ONLY_CONST)
            && operand_equal_p (arg01,
                                const_binop (PLUS_EXPR, arg2,
-                                            integer_one_node, 0),
+                                            build_int_cst (type, 1), 0),
                                OEP_ONLY_CONST))
          return pedantic_non_lvalue (fold_build2 (MIN_EXPR,
                                                   type, arg1, arg2));
@@ -4637,7 +4670,7 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
                               OEP_ONLY_CONST)
            && operand_equal_p (arg01,
                                const_binop (MINUS_EXPR, arg2,
-                                            integer_one_node, 0),
+                                            build_int_cst (type, 1), 0),
                                OEP_ONLY_CONST))
          return pedantic_non_lvalue (fold_build2 (MIN_EXPR,
                                                   type, arg1, arg2));
@@ -4649,7 +4682,7 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
                               OEP_ONLY_CONST)
            && operand_equal_p (arg01,
                                const_binop (MINUS_EXPR, arg2,
-                                            integer_one_node, 0),
+                                            build_int_cst (type, 1), 0),
                                OEP_ONLY_CONST))
          return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
                                                   type, arg1, arg2));
@@ -4661,7 +4694,7 @@ fold_cond_expr_with_comparison (tree type, tree arg0, tree arg1, tree arg2)
                               OEP_ONLY_CONST)
            && operand_equal_p (arg01,
                                const_binop (PLUS_EXPR, arg2,
-                                            integer_one_node, 0),
+                                            build_int_cst (type, 1), 0),
                                OEP_ONLY_CONST))
          return pedantic_non_lvalue (fold_build2 (MAX_EXPR,
                                                   type, arg1, arg2));
@@ -6084,7 +6117,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
 
   if (unsigned_p)
     {
-      tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
+      tmp = int_const_binop (MINUS_EXPR, arg01,
+                             build_int_cst (TREE_TYPE (arg01), 1), 0);
       lo = prod;
 
       /* Likewise hi = int_const_binop (PLUS_EXPR, prod, tmp, 0).  */
@@ -6099,7 +6133,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
     }
   else if (tree_int_cst_sgn (arg01) >= 0)
     {
-      tmp = int_const_binop (MINUS_EXPR, arg01, integer_one_node, 0);
+      tmp = int_const_binop (MINUS_EXPR, arg01,
+                            build_int_cst (TREE_TYPE (arg01), 1), 0);
       switch (tree_int_cst_sgn (arg1))
        {
        case -1:
@@ -6127,7 +6162,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
       /* A negative divisor reverses the relational operators.  */
       code = swap_tree_comparison (code);
 
-      tmp = int_const_binop (PLUS_EXPR, arg01, integer_one_node, 0);
+      tmp = int_const_binop (PLUS_EXPR, arg01,
+                            build_int_cst (TREE_TYPE (arg01), 1), 0);
       switch (tree_int_cst_sgn (arg1))
        {
        case -1:
@@ -6265,7 +6301,7 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
       enum machine_mode operand_mode = TYPE_MODE (type);
       int ops_unsigned;
       tree signed_type, unsigned_type, intermediate_type;
-      tree tem;
+      tree tem, one;
 
       /* First, see if we can fold the single bit test into a sign-bit
         test.  */
@@ -6310,13 +6346,13 @@ fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
        inner = build2 (RSHIFT_EXPR, intermediate_type,
                        inner, size_int (bitnum));
 
+      one = build_int_cst (intermediate_type, 1);
+
       if (code == EQ_EXPR)
-       inner = fold_build2 (BIT_XOR_EXPR, intermediate_type,
-                            inner, integer_one_node);
+       inner = fold_build2 (BIT_XOR_EXPR, intermediate_type, inner, one);
 
       /* Put the AND last so it can combine with more things.  */
-      inner = build2 (BIT_AND_EXPR, intermediate_type,
-                     inner, integer_one_node);
+      inner = build2 (BIT_AND_EXPR, intermediate_type, inner, one);
 
       /* Make sure to return the proper type.  */
       inner = fold_convert (result_type, inner);
@@ -10035,8 +10071,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
 
          if (integer_pow2p (c) && tree_int_cst_sgn (c) > 0)
            {
-             tree mask = fold_build2 (MINUS_EXPR, TREE_TYPE (arg1),
-                                      arg1, integer_one_node);
+             tree mask = fold_build2 (MINUS_EXPR, TREE_TYPE (arg1), arg1,
+                                      build_int_cst (TREE_TYPE (arg1), 1));
              return fold_build2 (BIT_AND_EXPR, type,
                                  fold_convert (type, arg0),
                                  fold_convert (type, mask));
@@ -10148,9 +10184,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
         RROTATE_EXPR by a new constant.  */
       if (code == LROTATE_EXPR && TREE_CODE (arg1) == INTEGER_CST)
        {
-         tree tem = build_int_cst (NULL_TREE,
+         tree tem = build_int_cst (TREE_TYPE (arg1),
                                    GET_MODE_BITSIZE (TYPE_MODE (type)));
-         tem = fold_convert (TREE_TYPE (arg1), tem);
          tem = const_binop (MINUS_EXPR, tem, arg1, 0);
          return fold_build2 (RROTATE_EXPR, type, arg0, tem);
        }
@@ -10970,10 +11005,12 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
              switch (code)
                {
                case GT_EXPR:
-                 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
+                 arg1 = const_binop (PLUS_EXPR, arg1,
+                                     build_int_cst (TREE_TYPE (arg1), 1), 0);
                  return fold_build2 (EQ_EXPR, type, arg0, arg1);
                case LE_EXPR:
-                 arg1 = const_binop (PLUS_EXPR, arg1, integer_one_node, 0);
+                 arg1 = const_binop (PLUS_EXPR, arg1,
+                                     build_int_cst (TREE_TYPE (arg1), 1), 0);
                  return fold_build2 (NE_EXPR, type, arg0, arg1);
                default:
                  break;
index 51db310bd48ad84f89b100e24b56f21d8927ed6a..ccbf9f7f3199ceea25646d0d4e162ad7140ce557 100644 (file)
@@ -1617,7 +1617,6 @@ layout_type (tree type)
     case VECTOR_TYPE:
       {
        int nunits = TYPE_VECTOR_SUBPARTS (type);
-       tree nunits_tree = build_int_cst (NULL_TREE, nunits);
        tree innertype = TREE_TYPE (type);
 
        gcc_assert (!(nunits & (nunits - 1)));
@@ -1655,9 +1654,9 @@ layout_type (tree type)
         TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
        TYPE_SIZE_UNIT (type) = int_const_binop (MULT_EXPR,
                                                 TYPE_SIZE_UNIT (innertype),
-                                                nunits_tree, 0);
+                                                size_int (nunits), 0);
        TYPE_SIZE (type) = int_const_binop (MULT_EXPR, TYPE_SIZE (innertype),
-                                           nunits_tree, 0);
+                                           bitsize_int (nunits), 0);
 
        /* Always naturally align vectors.  This prevents ABI changes
           depending on whether or not native vector modes are supported.  */