expr.c (expand_expr, [...]): Set RTX_UNCHANGING_P on returned MEM.
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Fri, 20 Oct 2000 20:57:21 +0000 (20:57 +0000)
committerRichard Kenner <kenner@gcc.gnu.org>
Fri, 20 Oct 2000 20:57:21 +0000 (16:57 -0400)
* expr.c (expand_expr, case SAVE_EXPR): Set RTX_UNCHANGING_P on
returned MEM.
(expand_expr_unaligned, case ARRAY_REF): Check that index is
a constant before comparing it; use tree_low_cst.
* tree.c (save_expr): Set TREE_READONLY.
(substitute_expr): Return inside of NON_LVALUE_EXPR.
(build, build1): Set TREE_READONLY if all operands are.
(build_index_type): If upper bound is a negative number, lower
bound is zero and sizetype is unsigned, use upper bound of one and
lower of zero.

From-SVN: r36979

gcc/ChangeLog
gcc/expr.c
gcc/tree.c

index 3fdb62f8564cb8d7f34941990c7d86c03eb89ac6..1701c6298deb09704be8f519695c68f75831a34c 100644 (file)
@@ -1,3 +1,16 @@
+Fri Oct 20 17:05:49 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
+       * expr.c (expand_expr, case SAVE_EXPR): Set RTX_UNCHANGING_P on
+       returned MEM.
+       (expand_expr_unaligned, case ARRAY_REF): Check that index is
+       a constant before comparing it; use tree_low_cst.
+       * tree.c (save_expr): Set TREE_READONLY.
+       (substitute_expr): Return inside of NON_LVALUE_EXPR.
+       (build, build1): Set TREE_READONLY if all operands are.
+       (build_index_type): If upper bound is a negative number, lower
+       bound is zero and sizetype is unsigned, use upper bound of one and
+       lower of zero.
+
 2000-10-20  David Edelsohn  <edelsohn@gnu.org>
 
        * gcc.c (process_command, main): Use "because" instead of
index 84e574d915b6a2df0c7f96f118d50d322033e36d..cc3ec34e390a21e2f0eb462bdd350e63502b2772 100644 (file)
@@ -6222,7 +6222,11 @@ expand_expr (exp, target, tmode, modifier)
          if (mode == VOIDmode)
            temp = const0_rtx;
          else
-           temp = assign_temp (type, 3, 0, 0);
+           {
+             temp = assign_temp (type, 3, 0, 0);
+             if (GET_CODE (temp) == MEM)
+               RTX_UNCHANGING_P (temp) = 1;
+           }
 
          SAVE_EXPR_RTL (exp) = temp;
          if (!optimize && GET_CODE (temp) == REG)
@@ -8683,6 +8687,7 @@ expand_expr_unaligned (exp, palign)
           that was declared const.  */
 
        if (TREE_CODE (array) == CONSTRUCTOR && ! TREE_SIDE_EFFECTS (array)
+           && host_integerp (index, 0)
            && 0 > compare_tree_int (index,
                                     list_length (CONSTRUCTOR_ELTS
                                                  (TREE_OPERAND (exp, 0)))))
@@ -8690,7 +8695,7 @@ expand_expr_unaligned (exp, palign)
            tree elem;
 
            for (elem = CONSTRUCTOR_ELTS (TREE_OPERAND (exp, 0)),
-                i = TREE_INT_CST_LOW (index);
+                i = tree_low_cst (index, 0);
                 elem != 0 && i != 0; i--, elem = TREE_CHAIN (elem))
              ;
 
index 7bd7a41309fdf16e5493a024bf81bf429b1ed0bb..f4aae6646134667d3d032bcdbea8ebaebd3f9698 100644 (file)
@@ -1727,6 +1727,7 @@ save_expr (expr)
      value was computed on both sides of the jump.  So make sure it isn't
      eliminated as dead.  */
   TREE_SIDE_EFFECTS (t) = 1;
+  TREE_READONLY (t) = 1;
   return t;
 }
 
@@ -2173,6 +2174,9 @@ substitute_in_expr (exp, f, r)
          if (op0 == TREE_OPERAND (exp, 0))
            return exp;
 
+         if (code == NON_LVALUE_EXPR)
+           return op0;
+
          new = fold (build1 (code, TREE_TYPE (exp), op0));
          break;
 
@@ -2488,10 +2492,10 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
   length = TREE_CODE_LENGTH (code);
   TREE_TYPE (t) = tt;
 
-  /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_RAISED for
-     the result based on those same flags for the arguments.  But, if
-     the arguments aren't really even `tree' expressions, we shouldn't
-     be trying to do this.  */
+  /* Below, we automatically set TREE_SIDE_EFFECTS and TREE_READONLY for the
+     result based on those same flags for the arguments.  But if the
+     arguments aren't really even `tree' expressions, we shouldn't be trying
+     to do this.  */
   fro = first_rtl_op (code);
 
   if (length == 2)
@@ -2499,38 +2503,45 @@ build VPARAMS ((enum tree_code code, tree tt, ...))
       /* This is equivalent to the loop below, but faster.  */
       register tree arg0 = va_arg (p, tree);
       register tree arg1 = va_arg (p, tree);
+
       TREE_OPERAND (t, 0) = arg0;
       TREE_OPERAND (t, 1) = arg1;
+      TREE_READONLY (t) = 1;
       if (arg0 && fro > 0)
        {
          if (TREE_SIDE_EFFECTS (arg0))
            TREE_SIDE_EFFECTS (t) = 1;
+         if (!TREE_READONLY (arg0))
+           TREE_READONLY (t) = 0;
        }
+
       if (arg1 && fro > 1)
        {
          if (TREE_SIDE_EFFECTS (arg1))
            TREE_SIDE_EFFECTS (t) = 1;
+         if (!TREE_READONLY (arg1))
+           TREE_READONLY (t) = 0;
        }
     }
   else if (length == 1)
     {
       register tree arg0 = va_arg (p, tree);
 
-      /* Call build1 for this!  */
+      /* The only one-operand cases we handle here are those with side-effects.
+        Others are handled with build1.  So don't bother checked if the
+        arg has side-effects since we'll already have set it.
+
+        ??? This really should use build1 too.  */
       if (TREE_CODE_CLASS (code) != 's')
        abort ();
       TREE_OPERAND (t, 0) = arg0;
-      if (fro > 0)
-       {
-         if (arg0 && TREE_SIDE_EFFECTS (arg0))
-           TREE_SIDE_EFFECTS (t) = 1;
-       }
     }
   else
     {
       for (i = 0; i < length; i++)
        {
          register tree operand = va_arg (p, tree);
+
          TREE_OPERAND (t, i) = operand;
          if (operand && fro > i)
            {
@@ -2578,11 +2589,15 @@ build1 (code, type, node)
 #endif
 
   TREE_SET_CODE (t, code);
+
   TREE_TYPE (t) = type;
   TREE_COMPLEXITY (t) = 0;
   TREE_OPERAND (t, 0) = node;
-  if (node && first_rtl_op (code) != 0 && TREE_SIDE_EFFECTS (node))
-    TREE_SIDE_EFFECTS (t) = 1;
+  if (node && first_rtl_op (code) != 0)
+    {
+      TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
+      TREE_READONLY (t) = TREE_READONLY (node);
+    }
 
   switch (code)
     {
@@ -2597,6 +2612,7 @@ build1 (code, type, node)
       /* All of these have side-effects, no matter what their
         operands are.  */
       TREE_SIDE_EFFECTS (t) = 1;
+      TREE_READONLY (t) = 0;
       break;
 
     default:
@@ -3802,12 +3818,25 @@ build_index_type (maxval)
      tree maxval;
 {
   register tree itype = make_node (INTEGER_TYPE);
+  int no_hash = 0;
 
   TREE_TYPE (itype) = sizetype;
   TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
-  TYPE_MIN_VALUE (itype) = size_zero_node;
 
-  TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
+  /* If sizetype is unsigned and the upper bound is negative, use a
+     lower bound of one and an upper bound of zero.  */
+  if (TREE_UNSIGNED (sizetype) && TREE_CODE (maxval) == INTEGER_CST
+      && tree_int_cst_sgn (maxval) < 0)
+    {
+      TYPE_MIN_VALUE (itype) = size_one_node;
+      TYPE_MAX_VALUE (itype) = size_zero_node;
+      no_hash = 1;
+    }
+  else
+    {
+      TYPE_MIN_VALUE (itype) = size_zero_node;
+      TYPE_MAX_VALUE (itype) = convert (sizetype, maxval);
+    }
 
   TYPE_MODE (itype) = TYPE_MODE (sizetype);
   TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
@@ -3815,7 +3844,7 @@ build_index_type (maxval)
   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
   TYPE_USER_ALIGN (itype) = TYPE_USER_ALIGN (sizetype);
 
-  if (host_integerp (maxval, 1))
+  if (!no_hash && host_integerp (maxval, 1))
     return type_hash_canon (tree_low_cst (maxval, 1), itype);
   else
     return itype;