OSDN Git Service

(fold, COND_EXPR case): All simplified results
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index f2ea2e4..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
@@ -914,11 +910,7 @@ make_node (code)
       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;
@@ -993,6 +985,11 @@ copy_node (node)
 
   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;
@@ -1157,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;
@@ -1233,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;
 }
 
@@ -1704,14 +1713,15 @@ size_in_bytes (type)
     }
   t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type),
                  size_int (BITS_PER_UNIT));
-  force_fit_type (t);
+  if (TREE_CODE (t) == INTEGER_CST)
+    force_fit_type (t, 0);
   return t;
 }
 
 /* Return the size of TYPE (in bytes) as an integer,
    or return -1 if the size can vary.  */
 
-unsigned int
+int
 int_size_in_bytes (type)
      tree type;
 {
@@ -1732,19 +1742,19 @@ int_size_in_bytes (type)
   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))));
 }
@@ -1944,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)));
@@ -2262,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.  */
 
@@ -2586,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));
-
-    case NEGATE_EXPR:
-    case ADDR_EXPR:
-    case REFERENCE_EXPR:
-    case INDIRECT_REF:
-      return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
+  /* This general rule works for most tree codes.
+     All exceptions should be handled above.  */
 
-    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.
@@ -2699,20 +2739,25 @@ build_index_type (maxval)
     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))
     {
@@ -2725,6 +2770,16 @@ build_index_2_type (lowval,highval)
     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,
@@ -2777,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;
@@ -2801,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;
     }
 
@@ -2895,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)
@@ -3098,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;
     }
@@ -3203,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
@@ -3215,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)