OSDN Git Service

(fold, COND_EXPR case): All simplified results
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 45b917d..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[];
 
@@ -908,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;
@@ -987,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;
@@ -1151,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;
@@ -1227,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;
 }
 
@@ -1727,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))));
 }
@@ -1939,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)));
@@ -2257,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.  */
 
@@ -2688,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))
     {
@@ -2714,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,
@@ -2766,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;
@@ -2790,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;
     }
 
@@ -3086,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;
     }
@@ -3191,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
@@ -3203,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)