OSDN Git Service

(fold, COND_EXPR case): All simplified results
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 8f03250..5f57d43 100644 (file)
@@ -1,5 +1,5 @@
 /* Language-independent node constructors for parse phase of GNU compiler.
-   Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -245,6 +245,8 @@ static int do_identifier_warnings;
 
 /* Unique id for next decl created.  */
 static int next_decl_uid;
+/* Unique id for next type created.  */
+static int next_type_uid = 1;
 
 extern char *mode_name[];
 
@@ -524,19 +526,13 @@ rtl_in_current_obstack ()
   rtl_obstack = current_obstack;
 }
 
-/* Temporarily allocate rtl from saveable_obstack.  Return 1 if we were
-   previously allocating it from current_obstack.  */
+/* Start allocating rtl from saveable_obstack.  Intended to be used after
+   a call to push_obstacks_nochange.  */
 
-int
+void
 rtl_in_saveable_obstack ()
 {
-  if (rtl_obstack == current_obstack)
-    {
-      rtl_obstack = saveable_obstack;
-      return 1;
-    }
-  else
-    return 0;
+  rtl_obstack = saveable_obstack;
 }
 \f
 /* Allocate SIZE bytes in the current obstack
@@ -844,13 +840,21 @@ make_node (code)
       kind = c_kind;
 #endif
       obstack = expression_obstack;
-      /* We can't use tree_code_length for this, since the number of words
-        is machine-dependent due to varying alignment of `double'.  */
-      if (code == REAL_CST)
-       {
-         length = sizeof (struct tree_real_cst);
-         break;
-       }
+
+      /* We can't use tree_code_length for INTEGER_CST, since the number of
+        words is machine-dependent due to varying length of HOST_WIDE_INT,
+        which might be wider than a pointer (e.g., long long).  Similarly
+        for REAL_CST, since the number of words is machine-dependent due
+        to varying size and alignment of `double'.  */
+
+      if (code == INTEGER_CST)
+       length = sizeof (struct tree_int_cst);
+      else if (code == REAL_CST)
+       length = sizeof (struct tree_real_cst);
+      else
+       length = sizeof (struct tree_common)
+         + tree_code_length[(int) code] * sizeof (char *);
+      break;
 
     case 'x':  /* something random, like an identifier.  */
 #ifdef GATHER_STATISTICS
@@ -877,11 +881,12 @@ make_node (code)
   tree_node_sizes[(int)kind] += length;
 #endif
 
-  /* We assume here that the length of a tree node is a multiple of the
-     size of an int.  Rounding up won't work because it would clobber
-     the next object.  */
+  /* Clear a word at a time.  */
   for (i = (length / sizeof (int)) - 1; i >= 0; i--)
     ((int *) t)[i] = 0;
+  /* Clear any extra bytes.  */
+  for (i = length / sizeof (int) * sizeof (int); i < length; i++)
+    ((char *) t)[i] = 0;
 
   TREE_SET_CODE (t, code);
   if (obstack == &permanent_obstack)
@@ -896,20 +901,16 @@ make_node (code)
 
     case 'd':
       if (code != FUNCTION_DECL)
+       DECL_ALIGN (t) = 1;
       DECL_IN_SYSTEM_HEADER (t)
        = in_system_header && (obstack == &permanent_obstack);
-      DECL_ALIGN (t) = 1;
       DECL_SOURCE_LINE (t) = lineno;
       DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>";
       DECL_UID (t) = next_decl_uid++;
       break;
 
     case 't':
-      {
-       static unsigned next_type_uid = 1;
-
-       TYPE_UID (t) = next_type_uid++;
-      }
+      TYPE_UID (t) = next_type_uid++;
       TYPE_ALIGN (t) = 1;
       TYPE_MAIN_VARIANT (t) = t;
       break;
@@ -978,9 +979,17 @@ copy_node (node)
 
   for (i = (length / sizeof (int)) - 1; i >= 0; i--)
     ((int *) t)[i] = ((int *) node)[i];
+  /* Clear any extra bytes.  */
+  for (i = length / sizeof (int) * sizeof (int); i < length; i++)
+    ((char *) t)[i] = ((char *) node)[i];
 
   TREE_CHAIN (t) = 0;
 
+  if (TREE_CODE_CLASS (code) == 'd')
+    DECL_UID (t) = next_decl_uid++;
+  else if (TREE_CODE_CLASS (code) == 't')
+    TYPE_UID (t) = next_type_uid++;
+
   TREE_PERMANENT (t) = (current_obstack == &permanent_obstack);
 
   return t;
@@ -1145,23 +1154,34 @@ real_value_from_int_cst (i)
      tree i;
 {
   REAL_VALUE_TYPE d;
+  REAL_VALUE_TYPE e;
+  /* Some 386 compilers mishandle unsigned int to float conversions,
+     so introduce a temporary variable E to avoid those bugs.  */
+
 #ifdef REAL_ARITHMETIC
-  REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
+  if (! TREE_UNSIGNED (TREE_TYPE (i)))
+    REAL_VALUE_FROM_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
+  else
+    REAL_VALUE_FROM_UNSIGNED_INT (d, TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i));
 #else /* not REAL_ARITHMETIC */
   if (TREE_INT_CST_HIGH (i) < 0 && ! TREE_UNSIGNED (TREE_TYPE (i)))
     {
       d = (double) (~ TREE_INT_CST_HIGH (i));
-      d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
+      = ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
            * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
-      d += (double) (unsigned HOST_WIDE_INT) (~ TREE_INT_CST_LOW (i));
+      d *= e;
+      e = (double) (unsigned HOST_WIDE_INT) (~ TREE_INT_CST_LOW (i));
+      d += e;
       d = (- d - 1.0);
     }
   else
     {
       d = (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (i);
-      d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
+      = ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
            * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
-      d += (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (i);
+      d *= e;
+      e = (double) (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (i);
+      d += e;
     }
 #endif /* not REAL_ARITHMETIC */
   return d;
@@ -1221,6 +1241,7 @@ build_complex (real, imag)
   register tree t = make_node (COMPLEX_CST);
   TREE_REALPART (t) = real;
   TREE_IMAGPART (t) = imag;
+  TREE_TYPE (t) = build_complex_type (TREE_TYPE (real));
   return t;
 }
 
@@ -1680,6 +1701,8 @@ tree
 size_in_bytes (type)
      tree type;
 {
+  tree t;
+
   if (type == error_mark_node)
     return integer_zero_node;
   type = TYPE_MAIN_VARIANT (type);
@@ -1688,8 +1711,11 @@ size_in_bytes (type)
       incomplete_type_error (NULL_TREE, type);
       return integer_zero_node;
     }
-  return size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
-                    size_int (BITS_PER_UNIT));
+  t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
+                 size_int (BITS_PER_UNIT));
+  if (TREE_CODE (t) == INTEGER_CST)
+    force_fit_type (t, 0);
+  return t;
 }
 
 /* Return the size of TYPE (in bytes) as an integer,
@@ -1699,7 +1725,7 @@ int
 int_size_in_bytes (type)
      tree type;
 {
-  int size;
+  unsigned int size;
   if (type == error_mark_node)
     return 0;
   type = TYPE_MAIN_VARIANT (type);
@@ -1707,22 +1733,28 @@ int_size_in_bytes (type)
     return -1;
   if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
     return -1;
+  if (TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0)
+    {
+      tree t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
+                          size_int (BITS_PER_UNIT));
+      return TREE_INT_CST_LOW (t);
+    }
   size = TREE_INT_CST_LOW (TYPE_SIZE (type));
   return (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
 }
-
-/* Return, as an INTEGER_CST node, the number of elements for
-   TYPE (which is an ARRAY_TYPE) minus one. 
-   This counts only elements of the top array.  */
+\f
+/* Return, as a tree node, the number of elements for TYPE (which is an
+   ARRAY_TYPE) minus one. This counts only elements of the top array.  */
 
 tree
 array_type_nelts (type)
      tree type;
 {
   tree index_type = TYPE_DOMAIN (type);
-  return (tree_int_cst_equal (TYPE_MIN_VALUE (index_type), integer_zero_node)
+
+  return (integer_zerop (TYPE_MIN_VALUE (index_type))
          ? TYPE_MAX_VALUE (index_type)
-         : fold (build (MINUS_EXPR, integer_type_node,
+         : fold (build (MINUS_EXPR, TREE_TYPE (TYPE_MAX_VALUE (index_type)),
                         TYPE_MAX_VALUE (index_type),
                         TYPE_MIN_VALUE (index_type))));
 }
@@ -1922,6 +1954,14 @@ stabilize_reference_1 (e)
       return e;
       
     case '2':
+      /* Division is slow and tends to be compiled with jumps,
+        especially the division by powers of 2 that is often
+        found inside of an array reference.  So do it just once.  */
+      if (code == TRUNC_DIV_EXPR || code == TRUNC_MOD_EXPR
+         || code == FLOOR_DIV_EXPR || code == FLOOR_MOD_EXPR
+         || code == CEIL_DIV_EXPR || code == CEIL_MOD_EXPR
+         || code == ROUND_DIV_EXPR || code == ROUND_MOD_EXPR)
+       return save_expr (e);
       /* Recursively stabilize each operand.  */
       result = build_nt (code, stabilize_reference_1 (TREE_OPERAND (e, 0)),
                         stabilize_reference_1 (TREE_OPERAND (e, 1)));
@@ -2240,6 +2280,34 @@ build_type_variant (type, constp, volatilep)
   return t;
 }
 
+/* Give TYPE a new main variant: NEW_MAIN.
+   This is the right thing to do only when something else
+   about TYPE is modified in place.  */
+
+tree
+change_main_variant (type, new_main)
+     tree type, new_main;
+{
+  tree t;
+  tree omain = TYPE_MAIN_VARIANT (type);
+
+  /* Remove TYPE from the TYPE_NEXT_VARIANT chain of its main variant.  */
+  if (TYPE_NEXT_VARIANT (omain) == type)
+    TYPE_NEXT_VARIANT (omain) = TYPE_NEXT_VARIANT (type);
+  else
+    for (t = TYPE_NEXT_VARIANT (omain); t && TYPE_NEXT_VARIANT (t);
+        t = TYPE_NEXT_VARIANT (t))
+      if (TYPE_NEXT_VARIANT (t) == type)
+       {
+         TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (type);
+         break;
+       }
+
+  TYPE_MAIN_VARIANT (type) = new_main;
+  TYPE_NEXT_VARIANT (type) = TYPE_NEXT_VARIANT (new_main);
+  TYPE_NEXT_VARIANT (new_main) = type;
+}
+
 /* Create a new variant of TYPE, equivalent but distinct.
    This is so the caller can modify it.  */
 
@@ -2564,42 +2632,36 @@ simple_cst_equal (t1, t2)
        return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
       return 0;
 
-    case BIT_FIELD_REF:
-      return (simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0))
-             && simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1))
-             && simple_cst_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t2, 2)));
-
     case VAR_DECL:
     case PARM_DECL:
     case CONST_DECL:
     case FUNCTION_DECL:
       return 0;
+    }
 
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-    case MULT_EXPR:
-    case TRUNC_DIV_EXPR:
-    case TRUNC_MOD_EXPR:
-    case LSHIFT_EXPR:
-    case RSHIFT_EXPR:
-      cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-      if (cmp <= 0)
-       return cmp;
-      return simple_cst_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+  /* This general rule works for most tree codes.
+     All exceptions should be handled above.  */
 
-    case NEGATE_EXPR:
-    case ADDR_EXPR:
-    case REFERENCE_EXPR:
-    case INDIRECT_REF:
-      return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
-
-    default:
-#if 0
-      return lang_simple_cst_equal (t1, t2);
-#else
-      return -1;
-#endif
+  switch (TREE_CODE_CLASS (code1))
+    {
+      int i;
+    case '1':
+    case '2':
+    case '<':
+    case 'e':
+    case 'r':
+    case 's':
+      cmp = 1;
+      for (i=0; i<tree_code_length[(int) code1]; ++i)
+       {
+         cmp = simple_cst_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
+         if (cmp <= 0)
+           return cmp;
+       }
+      return cmp;
     }
+
+  return -1;
 }
 \f
 /* Constructors for pointer, array and function types.
@@ -2663,39 +2725,61 @@ build_index_type (maxval)
   TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
   if (TREE_CODE (maxval) == INTEGER_CST)
     {
-      HOST_WIDE_INT maxint = TREE_INT_CST_LOW (maxval);
-      return type_hash_canon (maxint > 0 ? maxint : - maxint, itype);
+      int maxint = (int) TREE_INT_CST_LOW (maxval);
+      /* If the domain should be empty, make sure the maxval
+        remains -1 and is not spoiled by truncation.  */
+      if (INT_CST_LT (maxval, integer_zero_node))
+       {
+         TYPE_MAX_VALUE (itype) = build_int_2 (-1, -1);
+         TREE_TYPE (TYPE_MAX_VALUE (itype)) = sizetype;
+       }
+      return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype);
     }
   else
     return itype;
 }
 
-/* Just like build_index_type, but takes lowval and highval instead
-   of just highval (maxval). */
+/* Create a range of some discrete type TYPE (an INTEGER_TYPE,
+   ENUMERAL_TYPE, BOOLEAN_TYPE, or CHAR_TYPE), with
+   low bound LOWVAL and high bound HIGHVAL.
+   if TYPE==NULL_TREE, sizetype is used. */
 
 tree
-build_index_2_type (lowval,highval)
-     tree lowval, highval;
+build_range_type (type, lowval, highval)
+     tree type, lowval, highval;
 {
   register tree itype = make_node (INTEGER_TYPE);
-  TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
-  TYPE_MIN_VALUE (itype) = convert (sizetype, lowval);
-  TYPE_MAX_VALUE (itype) = convert (sizetype, highval);
-  TYPE_MODE (itype) = TYPE_MODE (sizetype);
-  TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
-  TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
+  TREE_TYPE (itype) = type;
+  if (type == NULL_TREE)
+    type = sizetype;
+  TYPE_PRECISION (itype) = TYPE_PRECISION (type);
+  TYPE_MIN_VALUE (itype) = convert (type, lowval);
+  TYPE_MAX_VALUE (itype) = convert (type, highval);
+  TYPE_MODE (itype) = TYPE_MODE (type);
+  TYPE_SIZE (itype) = TYPE_SIZE (type);
+  TYPE_ALIGN (itype) = TYPE_ALIGN (type);
   if ((TREE_CODE (lowval) == INTEGER_CST)
       && (TREE_CODE (highval) == INTEGER_CST))
     {
       HOST_WIDE_INT highint = TREE_INT_CST_LOW (highval);
       HOST_WIDE_INT lowint = TREE_INT_CST_LOW (lowval);
-      HOST_WIDE_INT maxint = highint - lowint;
-      return type_hash_canon (maxint > 0 ? maxint : - maxint, itype);
+      int maxint = (int) (highint - lowint);
+      return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype);
     }
   else
     return itype;
 }
 
+/* Just like build_index_type, but takes lowval and highval instead
+   of just highval (maxval). */
+
+tree
+build_index_2_type (lowval,highval)
+     tree lowval, highval;
+{
+  return build_range_type (NULL_TREE, lowval, highval);
+}
+
 /* Return nonzero iff ITYPE1 and ITYPE2 are equal (in the LISP sense).
    Needed because when index types are not hashed, equal index types
    built at different times appear distinct, even though structurally,
@@ -2748,11 +2832,22 @@ build_array_type (elt_type, index_type)
   TYPE_DOMAIN (t) = index_type;
 
   if (index_type == 0)
-    return t;
+    {
+      return t;
+    }
 
   hashcode = TYPE_HASH (elt_type) + TYPE_HASH (index_type);
   t = type_hash_canon (hashcode, t);
 
+#if 0 /* This led to crashes, because it could put a temporary node
+        on the TYPE_NEXT_VARIANT chain of a permanent one.  */
+  /* The main variant of an array type should always
+     be an array whose element type is the main variant.  */
+  if (elt_type != TYPE_MAIN_VARIANT (elt_type))
+    change_main_variant (t, build_array_type (TYPE_MAIN_VARIANT (elt_type),
+                                             index_type));
+#endif
+
   if (TYPE_SIZE (t) == 0)
     layout_type (t);
   return t;
@@ -2772,10 +2867,9 @@ build_function_type (value_type, arg_types)
   register tree t;
   int hashcode;
 
-  if (TREE_CODE (value_type) == FUNCTION_TYPE
-      || TREE_CODE (value_type) == ARRAY_TYPE)
+  if (TREE_CODE (value_type) == FUNCTION_TYPE)
     {
-      error ("function return type cannot be function or array");
+      error ("function return type cannot be function");
       value_type = integer_type_node;
     }
 
@@ -2866,10 +2960,9 @@ build_method_type (basetype, type)
   return t;
 }
 
-/* Construct, lay out and return the type of methods belonging to class
-   BASETYPE and whose arguments and values are described by TYPE.
-   If that type exists already, reuse it.
-   TYPE must be a FUNCTION_TYPE node.  */
+/* Construct, lay out and return the type of offsets to a value
+   of type TYPE, within an object of type BASETYPE.
+   If a suitable offset type exists already, reuse it.  */
 
 tree
 build_offset_type (basetype, type)
@@ -3069,7 +3162,14 @@ get_narrower (op, unsignedp_ptr)
            break;
          first = 0;
        }
-      /* A change in nominal type can always be stripped.  */
+      else /* bitschange == 0 */
+       {
+         /* A change in nominal type can always be stripped, but we must
+            preserve the unsignedness.  */
+         if (first)
+           uns = TREE_UNSIGNED (TREE_TYPE (op));
+         first = 0;
+       }
 
       win = op;
     }
@@ -3131,10 +3231,12 @@ int_fits_type_p (c, type)
 {
   if (TREE_UNSIGNED (type))
     return (!INT_CST_LT_UNSIGNED (TYPE_MAX_VALUE (type), c)
-           && !INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type)));
+           && !INT_CST_LT_UNSIGNED (c, TYPE_MIN_VALUE (type))
+           && (TREE_INT_CST_HIGH (c) >= 0 || TREE_UNSIGNED (TREE_TYPE (c))));
   else
     return (!INT_CST_LT (TYPE_MAX_VALUE (type), c)
-           && !INT_CST_LT (c, TYPE_MIN_VALUE (type)));
+           && !INT_CST_LT (c, TYPE_MIN_VALUE (type))
+           && (TREE_INT_CST_HIGH (c) >= 0 || !TREE_UNSIGNED (TREE_TYPE (c))));
 }
 
 /* Return the innermost context enclosing DECL that is
@@ -3172,7 +3274,7 @@ decl_function_context (decl)
 }
 
 /* Return the innermost context enclosing DECL that is
-   a RECORD_TYPE or UNION_TYPE, or zero if none.
+   a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE, or zero if none.
    TYPE_DECLs and FUNCTION_DECLs are transparent to this function.  */
 
 tree
@@ -3184,7 +3286,8 @@ decl_type_context (decl)
   while (context)
     {
       if (TREE_CODE (context) == RECORD_TYPE
-         || TREE_CODE (context) == UNION_TYPE)
+         || TREE_CODE (context) == UNION_TYPE
+         || TREE_CODE (context) == QUAL_UNION_TYPE)
        return context;
       if (TREE_CODE (context) == TYPE_DECL
          || TREE_CODE (context) == FUNCTION_DECL)