]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
2007-01-08 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Jan 2007 23:07:44 +0000 (23:07 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 8 Jan 2007 23:07:44 +0000 (23:07 +0000)
* tree.h (force_fit_type_double): Export.
(force_fit_type): Remove.
* fold-const.c (force_fit_type_double): New function.
(force_fit_type): Remove.
(int_const_binop): Use it.
(fold_convert_const_int_from_int): Likewise.
(fold_convert_const_int_from_real): Likewise.
(fold_div_compare): Likewise.
(fold_sign_changed_comparison): Likewise.
(fold_unary): Likewise.
(fold_negate_const): Likewise.
(fold_abs_const): Likewise.
(fold_not_const): Likewise.
* c-common.c (shorten_compare): Use force_fit_type_double.
* convert.c (convert_to_pointer): Likewise.

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

gcc/ChangeLog
gcc/c-common.c
gcc/convert.c
gcc/fold-const.c
gcc/tree.h

index db828ec9b927de208526189c250082a2e6364f3e..13ac72f9b724398cad817554f08440d6c65d280c 100644 (file)
@@ -1,3 +1,21 @@
+2007-01-08  Richard Guenther  <rguenther@suse.de>
+
+       * tree.h (force_fit_type_double): Export.
+       (force_fit_type): Remove.
+       * fold-const.c (force_fit_type_double): New function.
+       (force_fit_type): Remove.
+       (int_const_binop): Use it.
+       (fold_convert_const_int_from_int): Likewise.
+       (fold_convert_const_int_from_real): Likewise.
+       (fold_div_compare): Likewise.
+       (fold_sign_changed_comparison): Likewise.
+       (fold_unary): Likewise.
+       (fold_negate_const): Likewise.
+       (fold_abs_const): Likewise. 
+       (fold_not_const): Likewise.
+       * c-common.c (shorten_compare): Use force_fit_type_double.
+       * convert.c (convert_to_pointer): Likewise.
+
 2007-01-08  Richard Guenther  <rguenther@suse.de>
 
        * tree.h (build_int_cst_wide_type): Export.
index ef4c2e86bc5b294c17f75869d7c0afbe2c700d15..c1661b23a3da91554db977b30e7d5a0ac7aeac1e 100644 (file)
@@ -2316,12 +2316,11 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
        {
          /* Convert primop1 to target type, but do not introduce
             additional overflow.  We know primop1 is an int_cst.  */
-         tree tmp = build_int_cst_wide (*restype_ptr,
-                                        TREE_INT_CST_LOW (primop1),
-                                        TREE_INT_CST_HIGH (primop1));
-
-         primop1 = force_fit_type (tmp, 0, TREE_OVERFLOW (primop1),
-                                   TREE_CONSTANT_OVERFLOW (primop1));
+         primop1 = force_fit_type_double (*restype_ptr,
+                                          TREE_INT_CST_LOW (primop1),
+                                          TREE_INT_CST_HIGH (primop1), 0,
+                                          TREE_OVERFLOW (primop1),
+                                          TREE_CONSTANT_OVERFLOW (primop1));
        }
       if (type != *restype_ptr)
        {
index 0a9743ac8f84bf3e924cdc9f2b6345e7e0cdf8c0..11d84921849c19b718b7c85d4fe0546dd4a99dda 100644 (file)
@@ -44,14 +44,10 @@ convert_to_pointer (tree type, tree expr)
   if (TREE_TYPE (expr) == type)
     return expr;
 
+  /* Propagate overflow to the NULL pointer.  */
   if (integer_zerop (expr))
-    {
-      tree t = build_int_cst (type, 0);
-      if (TREE_OVERFLOW (expr) || TREE_CONSTANT_OVERFLOW (expr))
-       t = force_fit_type (t, 0, TREE_OVERFLOW (expr),
-                           TREE_CONSTANT_OVERFLOW (expr));
-      return t;
-    }
+    return force_fit_type_double (type, 0, 0, 0, TREE_OVERFLOW (expr),
+                                 TREE_CONSTANT_OVERFLOW (expr));
 
   switch (TREE_CODE (TREE_TYPE (expr)))
     {
index d88c01b02be87becdd8cef994ae891317c9ed4f6..9e1eae31918951da1a66ac53194eca1594937515 100644 (file)
@@ -263,7 +263,9 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
   return l1 != low0 || h1 != high0;
 }
 
-/* T is an INT_CST node.  OVERFLOWABLE indicates if we are interested
+/* We force the double-int HIGH:LOW to the range of the type TYPE by
+   sign or zero extending it.
+   OVERFLOWABLE indicates if we are interested
    in overflow of the value, when >0 we are only interested in signed
    overflow, for <0 we are interested in any overflow.  OVERFLOWED
    indicates whether overflow has already occurred.  CONST_OVERFLOWED
@@ -276,50 +278,54 @@ fit_double_type (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
    We set TREE_CONSTANT_OVERFLOWED if,
         CONST_OVERFLOWED is nonzero
        or we set TREE_OVERFLOWED.
-  We return either the original T, or a copy.  */
+   We return a new tree node for the extended double-int.  The node
+   is shared if no overflow flags are set.  */
 
 tree
-force_fit_type (tree t, int overflowable,
-               bool overflowed, bool overflowed_const)
+force_fit_type_double (tree type, unsigned HOST_WIDE_INT low,
+                      HOST_WIDE_INT high, int overflowable,
+                      bool overflowed, bool overflowed_const)
 {
-  unsigned HOST_WIDE_INT low;
-  HOST_WIDE_INT high;
   int sign_extended_type;
   bool overflow;
 
-  gcc_assert (TREE_CODE (t) == INTEGER_CST);
-
   /* Size types *are* sign extended.  */
-  sign_extended_type = (!TYPE_UNSIGNED (TREE_TYPE (t))
-                       || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
-                           && TYPE_IS_SIZETYPE (TREE_TYPE (t))));
-
-  low = TREE_INT_CST_LOW (t);
-  high = TREE_INT_CST_HIGH (t);
+  sign_extended_type = (!TYPE_UNSIGNED (type)
+                       || (TREE_CODE (type) == INTEGER_TYPE
+                           && TYPE_IS_SIZETYPE (type)));
 
-  overflow = fit_double_type (low, high, &low, &high, TREE_TYPE (t));
+  overflow = fit_double_type (low, high, &low, &high, type);
 
-  /* If the value changed, return a new node.  */
+  /* If we need to set overflow flags, return a new unshared node.  */
   if (overflowed || overflowed_const || overflow)
     {
-      t = build_int_cst_wide (TREE_TYPE (t), low, high);
-
       if (overflowed
          || overflowable < 0
          || (overflowable > 0 && sign_extended_type))
        {
-         t = copy_node (t);
+          tree t = make_node (INTEGER_CST);
+          TREE_INT_CST_LOW (t) = low;
+          TREE_INT_CST_HIGH (t) = high;
+          TREE_TYPE (t) = type;
          TREE_OVERFLOW (t) = 1;
          TREE_CONSTANT_OVERFLOW (t) = 1;
+
+         return t;
        }
       else if (overflowed_const)
        {
-         t = copy_node (t);
+          tree t = make_node (INTEGER_CST);
+          TREE_INT_CST_LOW (t) = low;
+          TREE_INT_CST_HIGH (t) = high;
+          TREE_TYPE (t) = type;
          TREE_CONSTANT_OVERFLOW (t) = 1;
+
+         return t;
        }
     }
 
-  return t;
+  /* Else build a shared node.  */
+  return build_int_cst_wide (type, low, high);
 }
 \f
 /* Add two doubleword integers with doubleword result.
@@ -1601,10 +1607,10 @@ int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
       return NULL_TREE;
     }
 
-  t = build_int_cst_wide (TREE_TYPE (arg1), low, hi);
-
   if (notrunc)
     {
+      t = build_int_cst_wide (TREE_TYPE (arg1), low, hi);
+
       /* Propagate overflow flags ourselves.  */
       if (((!uns || is_sizetype) && overflow)
          | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2))
@@ -1620,11 +1626,11 @@ int_const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
        }
     }
   else
-    t = force_fit_type (t, 1,
-                       ((!uns || is_sizetype) && overflow)
-                       | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2),
-                       TREE_CONSTANT_OVERFLOW (arg1)
-                       | TREE_CONSTANT_OVERFLOW (arg2));
+    t = force_fit_type_double (TREE_TYPE (arg1), low, hi, 1,
+                              ((!uns || is_sizetype) && overflow)
+                              | TREE_OVERFLOW (arg1) | TREE_OVERFLOW (arg2),
+                              TREE_CONSTANT_OVERFLOW (arg1)
+                              | TREE_CONSTANT_OVERFLOW (arg2));
 
   return t;
 }
@@ -1896,18 +1902,16 @@ fold_convert_const_int_from_int (tree type, tree arg1)
 
   /* Given an integer constant, make new constant with new type,
      appropriately sign-extended or truncated.  */
-  t = build_int_cst_wide (type, TREE_INT_CST_LOW (arg1),
-                         TREE_INT_CST_HIGH (arg1));
-
-  t = force_fit_type (t,
-                     /* Don't set the overflow when
-                        converting a pointer  */
-                     !POINTER_TYPE_P (TREE_TYPE (arg1)),
-                     (TREE_INT_CST_HIGH (arg1) < 0
-                      && (TYPE_UNSIGNED (type)
-                          < TYPE_UNSIGNED (TREE_TYPE (arg1))))
-                     | TREE_OVERFLOW (arg1),
-                     TREE_CONSTANT_OVERFLOW (arg1));
+  t = force_fit_type_double (type, TREE_INT_CST_LOW (arg1),
+                            TREE_INT_CST_HIGH (arg1),
+                            /* Don't set the overflow when
+                               converting a pointer  */
+                            !POINTER_TYPE_P (TREE_TYPE (arg1)),
+                            (TREE_INT_CST_HIGH (arg1) < 0
+                             && (TYPE_UNSIGNED (type)
+                                 < TYPE_UNSIGNED (TREE_TYPE (arg1))))
+                            | TREE_OVERFLOW (arg1),
+                            TREE_CONSTANT_OVERFLOW (arg1));
 
   return t;
 }
@@ -1985,10 +1989,9 @@ fold_convert_const_int_from_real (enum tree_code code, tree type, tree arg1)
   if (! overflow)
     REAL_VALUE_TO_INT (&low, &high, r);
 
-  t = build_int_cst_wide (type, low, high);
-
-  t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg1),
-                     TREE_CONSTANT_OVERFLOW (arg1));
+  t = force_fit_type_double (type, low, high, -1,
+                            overflow | TREE_OVERFLOW (arg1),
+                            TREE_CONSTANT_OVERFLOW (arg1));
   return t;
 }
 
@@ -6172,8 +6175,8 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
                                   TREE_INT_CST_LOW (arg1),
                                   TREE_INT_CST_HIGH (arg1),
                                   &lpart, &hpart, unsigned_p);
-  prod = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart);
-  prod = force_fit_type (prod, -1, overflow, false);
+  prod = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart,
+                               -1, overflow, false);
   neg_overflow = false;
 
   if (unsigned_p)
@@ -6188,9 +6191,9 @@ fold_div_compare (enum tree_code code, tree type, tree arg0, tree arg1)
                                       TREE_INT_CST_LOW (tmp),
                                       TREE_INT_CST_HIGH (tmp),
                                       &lpart, &hpart, unsigned_p);
-      hi = build_int_cst_wide (TREE_TYPE (arg00), lpart, hpart);
-      hi = force_fit_type (hi, -1, overflow | TREE_OVERFLOW (prod),
-                          TREE_CONSTANT_OVERFLOW (prod));
+      hi = force_fit_type_double (TREE_TYPE (arg00), lpart, hpart,
+                                 -1, overflow | TREE_OVERFLOW (prod),
+                                 TREE_CONSTANT_OVERFLOW (prod));
     }
   else if (tree_int_cst_sgn (arg01) >= 0)
     {
@@ -6589,7 +6592,7 @@ static tree
 fold_sign_changed_comparison (enum tree_code code, tree type,
                              tree arg0, tree arg1)
 {
-  tree arg0_inner, tmp;
+  tree arg0_inner;
   tree inner_type, outer_type;
 
   if (TREE_CODE (arg0) != NOP_EXPR
@@ -6624,14 +6627,10 @@ fold_sign_changed_comparison (enum tree_code code, tree type,
     return NULL_TREE;
 
   if (TREE_CODE (arg1) == INTEGER_CST)
-    {
-      tmp = build_int_cst_wide (inner_type,
-                               TREE_INT_CST_LOW (arg1),
-                               TREE_INT_CST_HIGH (arg1));
-      arg1 = force_fit_type (tmp, 0,
-                            TREE_OVERFLOW (arg1),
-                            TREE_CONSTANT_OVERFLOW (arg1));
-    }
+    arg1 = force_fit_type_double (inner_type, TREE_INT_CST_LOW (arg1),
+                                 TREE_INT_CST_HIGH (arg1), 0,
+                                 TREE_OVERFLOW (arg1),
+                                 TREE_CONSTANT_OVERFLOW (arg1));
   else
     arg1 = fold_convert (inner_type, arg1);
 
@@ -7563,10 +7562,10 @@ fold_unary (enum tree_code code, tree type, tree op0)
            }
          if (change)
            {
-             tem = build_int_cst_wide (type, TREE_INT_CST_LOW (and1),
-                                       TREE_INT_CST_HIGH (and1));
-             tem = force_fit_type (tem, 0, TREE_OVERFLOW (and1),
-                                   TREE_CONSTANT_OVERFLOW (and1));
+             tem = force_fit_type_double (type, TREE_INT_CST_LOW (and1),
+                                          TREE_INT_CST_HIGH (and1), 0,
+                                          TREE_OVERFLOW (and1),
+                                          TREE_CONSTANT_OVERFLOW (and1));
              return fold_build2 (BIT_AND_EXPR, type,
                                  fold_convert (type, and0), tem);
            }
@@ -13056,11 +13055,10 @@ fold_negate_const (tree arg0, tree type)
        int overflow = neg_double (TREE_INT_CST_LOW (arg0),
                                   TREE_INT_CST_HIGH (arg0),
                                   &low, &high);
-       t = build_int_cst_wide (type, low, high);
-       t = force_fit_type (t, 1,
-                           (overflow | TREE_OVERFLOW (arg0))
-                           && !TYPE_UNSIGNED (type),
-                           TREE_CONSTANT_OVERFLOW (arg0));
+       t = force_fit_type_double (type, low, high, 1,
+                                  (overflow | TREE_OVERFLOW (arg0))
+                                  && !TYPE_UNSIGNED (type),
+                                  TREE_CONSTANT_OVERFLOW (arg0));
        break;
       }
 
@@ -13104,9 +13102,9 @@ fold_abs_const (tree arg0, tree type)
          int overflow = neg_double (TREE_INT_CST_LOW (arg0),
                                     TREE_INT_CST_HIGH (arg0),
                                     &low, &high);
-         t = build_int_cst_wide (type, low, high);
-         t = force_fit_type (t, -1, overflow | TREE_OVERFLOW (arg0),
-                             TREE_CONSTANT_OVERFLOW (arg0));
+         t = force_fit_type_double (type, low, high, -1,
+                                    overflow | TREE_OVERFLOW (arg0),
+                                    TREE_CONSTANT_OVERFLOW (arg0));
        }
       break;
 
@@ -13134,11 +13132,10 @@ fold_not_const (tree arg0, tree type)
 
   gcc_assert (TREE_CODE (arg0) == INTEGER_CST);
 
-  t = build_int_cst_wide (type,
-                         ~ TREE_INT_CST_LOW (arg0),
-                         ~ TREE_INT_CST_HIGH (arg0));
-  t = force_fit_type (t, 0, TREE_OVERFLOW (arg0),
-                     TREE_CONSTANT_OVERFLOW (arg0));
+  t = force_fit_type_double (type, ~TREE_INT_CST_LOW (arg0),
+                            ~TREE_INT_CST_HIGH (arg0), 0,
+                            TREE_OVERFLOW (arg0),
+                            TREE_CONSTANT_OVERFLOW (arg0));
 
   return t;
 }
index 37a854608dc7c5e00a1238f63741113cdfb1b7e2..2e3c087fa3122b93c78e2b9ce6269ee210f6485b 100644 (file)
@@ -4321,7 +4321,8 @@ extern tree fold_ignored_result (tree);
 extern tree fold_abs_const (tree, tree);
 extern tree fold_indirect_ref_1 (tree, tree);
 
-extern tree force_fit_type (tree, int, bool, bool);
+extern tree force_fit_type_double (tree, unsigned HOST_WIDE_INT, HOST_WIDE_INT,
+                                  int, bool, bool);
 
 extern int fit_double_type (unsigned HOST_WIDE_INT, HOST_WIDE_INT,
                            unsigned HOST_WIDE_INT *, HOST_WIDE_INT *, tree);