OSDN Git Service

* double-int.c (mpz_set_double_int): Moved from
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index 6824c14..472477c 100644 (file)
@@ -66,7 +66,9 @@ const char *const tree_code_class_strings[] =
   "unary",
   "binary",
   "statement",
+  "vl_exp",
   "expression",
+  "gimple_stmt"
 };
 
 /* obstack.[ch] explicitly declined to prototype this.  */
@@ -144,20 +146,13 @@ static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
 static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) 
      htab_t value_expr_for_decl;
 
-static GTY ((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map)))
+static GTY ((if_marked ("tree_priority_map_marked_p"), 
+            param_is (struct tree_priority_map)))
   htab_t init_priority_for_decl;
 
 static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
   htab_t restrict_base_for_decl;
 
-struct tree_int_map GTY(())
-{
-  tree from;
-  unsigned short to;
-};
-static unsigned int tree_int_map_hash (const void *);
-static int tree_int_map_eq (const void *, const void *);
-static int tree_int_map_marked_p (const void *);
 static void set_type_quals (tree, int);
 static int type_hash_eq (const void *, const void *);
 static hashval_t type_hash_hash (const void *);
@@ -173,7 +168,7 @@ static unsigned int attribute_hash_list (tree, hashval_t);
 tree global_trees[TI_MAX];
 tree integer_types[itk_none];
 
-unsigned char tree_contains_struct[256][64];
+unsigned char tree_contains_struct[MAX_TREE_CODES][64];
 
 /* Number of operands for each OpenMP clause.  */
 unsigned const char omp_clause_num_ops[] =
@@ -226,8 +221,8 @@ init_ttree (void)
 
   value_expr_for_decl = htab_create_ggc (512, tree_map_hash,
                                         tree_map_eq, 0);
-  init_priority_for_decl = htab_create_ggc (512, tree_int_map_hash,
-                                           tree_int_map_eq, 0);
+  init_priority_for_decl = htab_create_ggc (512, tree_priority_map_hash,
+                                           tree_priority_map_eq, 0);
   restrict_base_for_decl = htab_create_ggc (256, tree_map_hash,
                                            tree_map_eq, 0);
 
@@ -345,8 +340,8 @@ decl_assembler_name_equal (tree decl, tree asmname)
 }
 
 /* Compute the number of bytes occupied by a tree with code CODE.
-   This function cannot be used for TREE_VEC, PHI_NODE, or STRING_CST
-   codes, which are of variable length.  */
+   This function cannot be used for nodes that have variable sizes,
+   including TREE_VEC, PHI_NODE, STRING_CST, and CALL_EXPR.  */
 size_t
 tree_code_size (enum tree_code code)
 {
@@ -394,7 +389,7 @@ tree_code_size (enum tree_code code)
     case tcc_unary:       /* a unary arithmetic expression */
     case tcc_binary:      /* a binary arithmetic expression */
       return (sizeof (struct tree_exp)
-             + (TREE_CODE_LENGTH (code) - 1) * sizeof (char *));
+             + (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));
 
     case tcc_gimple_stmt:
       return (sizeof (struct gimple_stmt)
@@ -442,7 +437,7 @@ tree_code_size (enum tree_code code)
 }
 
 /* Compute the number of bytes occupied by NODE.  This routine only
-   looks at TREE_CODE, except for PHI_NODE and TREE_VEC nodes.  */
+   looks at TREE_CODE, except for those nodes that have variable sizes.  */
 size_t
 tree_size (tree node)
 {
@@ -459,7 +454,7 @@ tree_size (tree node)
 
     case TREE_VEC:
       return (sizeof (struct tree_vec)
-             + (TREE_VEC_LENGTH (node) - 1) * sizeof(char *));
+             + (TREE_VEC_LENGTH (node) - 1) * sizeof (tree));
 
     case STRING_CST:
       return TREE_STRING_LENGTH (node) + offsetof (struct tree_string, str) + 1;
@@ -470,7 +465,11 @@ tree_size (tree node)
                * sizeof (tree));
 
     default:
-      return tree_code_size (code);
+      if (TREE_CODE_CLASS (code) == tcc_vl_exp)
+       return (sizeof (struct tree_exp)
+               + (VL_EXP_OPERAND_LENGTH (node) - 1) * sizeof (tree));
+      else
+       return tree_code_size (code);
     }
 }
 
@@ -1898,14 +1897,11 @@ expr_align (tree t)
       align1 = TYPE_ALIGN (TREE_TYPE (t));
       return MAX (align0, align1);
 
-    case MODIFY_EXPR:
-      /* FIXME tuples: It is unclear to me if this function, which
-         is only called from ADA, is called on gimple or non gimple
-         trees.  Let's assume it's from gimple trees unless we hit
-         this abort.  */
+    case GIMPLE_MODIFY_STMT:
+      /* We should never ask for the alignment of a gimple statement.  */
       gcc_unreachable ();
 
-    case SAVE_EXPR:         case COMPOUND_EXPR:       case GIMPLE_MODIFY_STMT:
+    case SAVE_EXPR:         case COMPOUND_EXPR:       case MODIFY_EXPR:
     case INIT_EXPR:         case TARGET_EXPR:         case WITH_CLEANUP_EXPR:
     case CLEANUP_POINT_EXPR:
       /* These don't change the alignment of an object.  */
@@ -2174,6 +2170,7 @@ tree_node_structure (tree t)
     case tcc_binary:
     case tcc_expression:
     case tcc_statement:
+    case tcc_vl_exp:
       return TS_EXP;
     case tcc_gimple_stmt:
       return TS_GIMPLE_STATEMENT;
@@ -2255,9 +2252,6 @@ contains_placeholder_p (tree exp)
                  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
                  || CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
 
-       case CALL_EXPR:
-         return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
-
        default:
          break;
        }
@@ -2273,6 +2267,22 @@ contains_placeholder_p (tree exp)
          return 0;
        }
 
+    case tcc_vl_exp:
+      switch (code)
+       {
+       case CALL_EXPR:
+         {
+           tree arg;
+           call_expr_arg_iterator iter;
+           FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
+             if (CONTAINS_PLACEHOLDER_P (arg))
+               return 1;
+           return 0;
+         }
+       default:
+         return 0;
+       }
+
     default:
       return 0;
     }
@@ -2480,6 +2490,27 @@ substitute_in_expr (tree exp, tree f, tree r)
          }
        break;
 
+      case tcc_vl_exp:
+       {
+         tree copy = NULL_TREE;
+         int i;
+         int n = TREE_OPERAND_LENGTH (exp);
+         for (i = 1; i < n; i++)
+           {
+             tree op = TREE_OPERAND (exp, i);
+             tree newop = SUBSTITUTE_IN_EXPR (op, f, r);
+             if (newop != op)
+               {
+                 copy = copy_node (exp);
+                 TREE_OPERAND (copy, i) = newop;
+               }
+           }
+         if (copy)
+           new = fold (copy);
+         else
+           return exp;
+       }
+
       default:
        gcc_unreachable ();
       }
@@ -2511,6 +2542,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
                  : (REFERENCE_CLASS_P (elt)
                     || UNARY_CLASS_P (elt)
                     || BINARY_CLASS_P (elt)
+                    || VL_EXP_CLASS_P (elt)
                     || EXPRESSION_CLASS_P (elt))
                  ? TREE_OPERAND (elt, 0) : 0))
        if (TYPE_MAIN_VARIANT (TREE_TYPE (elt)) == need_type)
@@ -2523,6 +2555,7 @@ substitute_placeholder_in_expr (tree exp, tree obj)
                  : (REFERENCE_CLASS_P (elt)
                     || UNARY_CLASS_P (elt)
                     || BINARY_CLASS_P (elt)
+                    || VL_EXP_CLASS_P (elt)
                     || EXPRESSION_CLASS_P (elt))
                  ? TREE_OPERAND (elt, 0) : 0))
        if (POINTER_TYPE_P (TREE_TYPE (elt))
@@ -2610,6 +2643,28 @@ substitute_placeholder_in_expr (tree exp, tree obj)
          }
        break;
 
+      case tcc_vl_exp:
+       {
+         tree copy = NULL_TREE;
+         int i;
+         int n = TREE_OPERAND_LENGTH (exp);
+         for (i = 1; i < n; i++)
+           {
+             tree op = TREE_OPERAND (exp, i);
+             tree newop = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
+             if (newop != op)
+               {
+                 if (!copy)
+                   copy = copy_node (exp);
+                 TREE_OPERAND (copy, i) = newop;
+               }
+           }
+         if (copy)
+           return fold (copy);
+         else
+           return exp;
+       }
+
       default:
        gcc_unreachable ();
       }
@@ -2735,6 +2790,7 @@ stabilize_reference_1 (tree e)
     case tcc_statement:
     case tcc_expression:
     case tcc_reference:
+    case tcc_vl_exp:
       /* If the expression has side-effects, then encase it in a SAVE_EXPR
         so that it will only be evaluated once.  */
       /* The reference (r) and comparison (<) classes could be handled as
@@ -2931,7 +2987,6 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL)
 #else
   SET_EXPR_LOCUS (t, NULL);
 #endif
-  TREE_COMPLEXITY (t) = 0;
   TREE_OPERAND (t, 0) = node;
   TREE_BLOCK (t) = NULL_TREE;
   if (node && !TYPE_P (node))
@@ -3005,16 +3060,14 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
 
   gcc_assert (TREE_CODE_LENGTH (code) == 2);
 
-  if (code == MODIFY_EXPR && cfun && cfun->gimplified)
-    {
-      /* We should be talking GIMPLE_MODIFY_STMT by now.  */
-      gcc_unreachable ();
-    }
-
-  /* FIXME tuples: For now let's be lazy; later we must rewrite all
-     build2 calls to build2_gimple calls.  */
-  if (TREE_CODE_CLASS (code) == tcc_gimple_stmt)
-    return build2_gimple (code, arg0, arg1);
+#if 1
+  /* FIXME tuples: Statement's aren't expressions!  */
+  if (code == GIMPLE_MODIFY_STMT)
+    return build_gimple_modify_stmt_stat (arg0, arg1 PASS_MEM_STAT);
+#else
+  /* Must use build_gimple_modify_stmt to construct GIMPLE_MODIFY_STMTs.  */
+  gcc_assert (code != GIMPLE_MODIFY_STMT);
+#endif
 
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
@@ -3047,31 +3100,18 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL)
 }
 
 
-/* Similar as build2_stat, but for GIMPLE tuples.  For convenience's sake,
-   arguments and return type are trees.  */
+/* Build a GIMPLE_MODIFY_STMT node.  This tree code doesn't have a
+   type, so we can't use build2 (a.k.a. build2_stat).  */
 
 tree
-build2_gimple_stat (enum tree_code code, tree arg0, tree arg1 MEM_STAT_DECL)
+build_gimple_modify_stmt_stat (tree arg0, tree arg1 MEM_STAT_DECL)
 {
-  bool side_effects;
   tree t;
 
-  gcc_assert (TREE_CODE_LENGTH (code) == 2);
-
-  t = make_node_stat (code PASS_MEM_STAT);
-
-  side_effects = TREE_SIDE_EFFECTS (t);
-
+  t = make_node_stat (GIMPLE_MODIFY_STMT PASS_MEM_STAT);
   /* ?? We don't care about setting flags for tuples...  */
   GIMPLE_STMT_OPERAND (t, 0) = arg0;
   GIMPLE_STMT_OPERAND (t, 1) = arg1;
-
-  /* ...except perhaps side_effects and volatility.  ?? */
-  TREE_SIDE_EFFECTS (t) = side_effects;
-  TREE_THIS_VOLATILE (t) = (TREE_CODE_CLASS (code) == tcc_reference
-                           && arg0 && TREE_THIS_VOLATILE (arg0));
-
-
   return t;
 }
 
@@ -3083,36 +3123,26 @@ build3_stat (enum tree_code code, tree tt, tree arg0, tree arg1,
   tree t;
 
   gcc_assert (TREE_CODE_LENGTH (code) == 3);
+  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
 
   t = make_node_stat (code PASS_MEM_STAT);
   TREE_TYPE (t) = tt;
 
-  side_effects = TREE_SIDE_EFFECTS (t);
+  /* As a special exception, if COND_EXPR has NULL branches, we
+     assume that it is a gimple statement and always consider
+     it to have side effects.  */
+  if (code == COND_EXPR
+      && tt == void_type_node
+      && arg1 == NULL_TREE
+      && arg2 == NULL_TREE)
+    side_effects = true;
+  else
+    side_effects = TREE_SIDE_EFFECTS (t);
 
   PROCESS_ARG(0);
   PROCESS_ARG(1);
   PROCESS_ARG(2);
 
-  if (code == CALL_EXPR && !side_effects)
-    {
-      tree node;
-      int i;
-
-      /* Calls have side-effects, except those to const or
-        pure functions.  */
-      i = call_expr_flags (t);
-      if (!(i & (ECF_CONST | ECF_PURE)))
-       side_effects = 1;
-
-      /* And even those have side-effects if their arguments do.  */
-      else for (node = arg1; node; node = TREE_CHAIN (node))
-       if (TREE_SIDE_EFFECTS (TREE_VALUE (node)))
-         {
-           side_effects = 1;
-           break;
-         }
-    }
-
   TREE_SIDE_EFFECTS (t) = side_effects;
   TREE_THIS_VOLATILE (t)
     = (TREE_CODE_CLASS (code) == tcc_reference
@@ -3218,6 +3248,8 @@ build_nt (enum tree_code code, ...)
   int i;
   va_list p;
 
+  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
   va_start (p, code);
 
   t = make_node (code);
@@ -3229,6 +3261,23 @@ build_nt (enum tree_code code, ...)
   va_end (p);
   return t;
 }
+
+/* Similar to build_nt, but for creating a CALL_EXPR object with
+   ARGLIST passed as a list.  */
+
+tree
+build_nt_call_list (tree fn, tree arglist)
+{
+  tree t;
+  int i;
+
+  t = build_vl_exp (CALL_EXPR, list_length (arglist) + 3);
+  CALL_EXPR_FN (t) = fn;
+  CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+  for (i = 0; arglist; arglist = TREE_CHAIN (arglist), i++)
+    CALL_EXPR_ARG (t, i) = TREE_VALUE (arglist);
+  return t;
+}
 \f
 /* Create a DECL_... node of code CODE, name NAME and data type TYPE.
    We do NOT enter this node in any sort of symbol table.
@@ -4125,6 +4174,15 @@ build_distinct_type_copy (tree type)
   TYPE_MAIN_VARIANT (t) = t;
   TYPE_NEXT_VARIANT (t) = 0;
   
+  /* VRP assumes that TREE_TYPE (TYPE_MIN_VALUE (type)) == type.  */
+  if (INTEGRAL_TYPE_P (t) || SCALAR_FLOAT_TYPE_P (t))
+    {
+      if (TYPE_MIN_VALUE (t) != NULL_TREE)
+       TYPE_MIN_VALUE (t) = fold_convert (t, TYPE_MIN_VALUE (t));
+      if (TYPE_MAX_VALUE (t) != NULL_TREE)
+       TYPE_MAX_VALUE (t) = fold_convert (t, TYPE_MAX_VALUE (t));
+    }
+
   return t;
 }
 
@@ -4156,18 +4214,18 @@ build_variant_type_copy (tree type)
 /* Return true if the from tree in both tree maps are equal.  */
 
 int
-tree_map_eq (const void *va, const void *vb)
+tree_map_base_eq (const void *va, const void *vb)
 {
-  const struct tree_map  *a = va, *b = vb;
+  const struct tree_map_base  *a = va, *b = vb;
   return (a->from == b->from);
 }
 
 /* Hash a from tree in a tree_map.  */
 
 unsigned int
-tree_map_hash (const void *item)
+tree_map_base_hash (const void *item)
 {
-  return (((const struct tree_map *) item)->hash);
+  return htab_hash_pointer (((const struct tree_map_base *)item)->from);
 }
 
 /* Return true if this tree map structure is marked for garbage collection
@@ -4175,70 +4233,97 @@ tree_map_hash (const void *item)
    structure goes away when the from tree goes away.  */
 
 int
-tree_map_marked_p (const void *p)
+tree_map_base_marked_p (const void *p)
 {
-  tree from = ((struct tree_map *) p)->from;
+  return ggc_marked_p (((struct tree_map_base *) p)->from);
+}
 
-  return ggc_marked_p (from);
+unsigned int
+tree_map_hash (const void *item)
+{
+  return (((const struct tree_map *) item)->hash);
 }
 
-/* Return true if the trees in the tree_int_map *'s VA and VB are equal.  */
+/* Return the initialization priority for DECL.  */
 
-static int
-tree_int_map_eq (const void *va, const void *vb)
+priority_type
+decl_init_priority_lookup (tree decl)
 {
-  const struct tree_int_map  *a = va, *b = vb;
-  return (a->from == b->from);
+  struct tree_priority_map *h;
+  struct tree_map_base in;
+
+  gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+  gcc_assert (TREE_CODE (decl) == VAR_DECL
+             ? DECL_HAS_INIT_PRIORITY_P (decl)
+             : DECL_STATIC_CONSTRUCTOR (decl));
+  in.from = decl;
+  h = htab_find (init_priority_for_decl, &in);
+  return h ? h->init : DEFAULT_INIT_PRIORITY;
 }
 
-/* Hash a from tree in the tree_int_map * ITEM.  */
+/* Return the finalization priority for DECL.  */
 
-static unsigned int
-tree_int_map_hash (const void *item)
+priority_type
+decl_fini_priority_lookup (tree decl)
 {
-  return htab_hash_pointer (((const struct tree_int_map *)item)->from);
+  struct tree_priority_map *h;
+  struct tree_map_base in;
+
+  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+  gcc_assert (DECL_STATIC_DESTRUCTOR (decl));
+  in.from = decl;
+  h = htab_find (init_priority_for_decl, &in);
+  return h ? h->fini : DEFAULT_INIT_PRIORITY;
 }
 
-/* Return true if this tree int map structure is marked for garbage collection
-   purposes.  We simply return true if the from tree_int_map *P's from tree is marked, so that this
-   structure goes away when the from tree goes away.  */
+/* Return the initialization and finalization priority information for
+   DECL.  If there is no previous priority information, a freshly
+   allocated structure is returned.  */
 
-static int
-tree_int_map_marked_p (const void *p)
+static struct tree_priority_map *
+decl_priority_info (tree decl)
 {
-  tree from = ((struct tree_int_map *) p)->from;
+  struct tree_priority_map in;
+  struct tree_priority_map *h;
+  void **loc;
 
-  return ggc_marked_p (from);
+  in.base.from = decl;
+  loc = htab_find_slot (init_priority_for_decl, &in, INSERT);
+  h = *loc;
+  if (!h)
+    {
+      h = GGC_CNEW (struct tree_priority_map);
+      *loc = h;
+      h->base.from = decl;
+      h->init = DEFAULT_INIT_PRIORITY;
+      h->fini = DEFAULT_INIT_PRIORITY;
+    }
+
+  return h;
 }
-/* Lookup an init priority for FROM, and return it if we find one.  */
 
-unsigned short
-decl_init_priority_lookup (tree from)
+/* Set the initialization priority for DECL to PRIORITY.  */
+
+void
+decl_init_priority_insert (tree decl, priority_type priority)
 {
-  struct tree_int_map *h, in;
-  in.from = from;
+  struct tree_priority_map *h;
 
-  h = htab_find_with_hash (init_priority_for_decl, 
-                          &in, htab_hash_pointer (from));
-  if (h)
-    return h->to;
-  return 0;
-}
+  gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
+  h = decl_priority_info (decl);
+  h->init = priority;
+}  
 
-/* Insert a mapping FROM->TO in the init priority hashtable.  */
+/* Set the finalization priority for DECL to PRIORITY.  */
 
 void
-decl_init_priority_insert (tree from, unsigned short to)
+decl_fini_priority_insert (tree decl, priority_type priority)
 {
-  struct tree_int_map *h;
-  void **loc;
+  struct tree_priority_map *h;
 
-  h = ggc_alloc (sizeof (struct tree_int_map));
-  h->from = from;
-  h->to = to;
-  loc = htab_find_slot_with_hash (init_priority_for_decl, h, 
-                                 htab_hash_pointer (from), INSERT);
-  *(struct tree_int_map **) loc = h;
+  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
+  h = decl_priority_info (decl);
+  h->fini = priority;
 }  
 
 /* Look up a restrict qualified base decl for FROM.  */
@@ -4249,7 +4334,7 @@ decl_restrict_base_lookup (tree from)
   struct tree_map *h;
   struct tree_map in;
 
-  in.from = from;
+  in.base.from = from;
   h = htab_find_with_hash (restrict_base_for_decl, &in,
                           htab_hash_pointer (from));
   return h ? h->to : NULL_TREE;
@@ -4265,7 +4350,7 @@ decl_restrict_base_insert (tree from, tree to)
 
   h = ggc_alloc (sizeof (struct tree_map));
   h->hash = htab_hash_pointer (from);
-  h->from = from;
+  h->base.from = from;
   h->to = to;
   loc = htab_find_slot_with_hash (restrict_base_for_decl, h, h->hash, INSERT);
   *(struct tree_map **) loc = h;
@@ -4313,7 +4398,7 @@ tree
 decl_debug_expr_lookup (tree from)
 {
   struct tree_map *h, in;
-  in.from = from;
+  in.base.from = from;
 
   h = htab_find_with_hash (debug_expr_for_decl, &in, htab_hash_pointer (from));
   if (h)
@@ -4331,7 +4416,7 @@ decl_debug_expr_insert (tree from, tree to)
 
   h = ggc_alloc (sizeof (struct tree_map));
   h->hash = htab_hash_pointer (from);
-  h->from = from;
+  h->base.from = from;
   h->to = to;
   loc = htab_find_slot_with_hash (debug_expr_for_decl, h, h->hash, INSERT);
   *(struct tree_map **) loc = h;
@@ -4343,7 +4428,7 @@ tree
 decl_value_expr_lookup (tree from)
 {
   struct tree_map *h, in;
-  in.from = from;
+  in.base.from = from;
 
   h = htab_find_with_hash (value_expr_for_decl, &in, htab_hash_pointer (from));
   if (h)
@@ -4361,7 +4446,7 @@ decl_value_expr_insert (tree from, tree to)
 
   h = ggc_alloc (sizeof (struct tree_map));
   h->hash = htab_hash_pointer (from);
-  h->from = from;
+  h->base.from = from;
   h->to = to;
   loc = htab_find_slot_with_hash (value_expr_for_decl, h, h->hash, INSERT);
   *(struct tree_map **) loc = h;
@@ -4925,11 +5010,26 @@ simple_cst_equal (tree t1, tree t2)
       return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
 
     case CALL_EXPR:
-      cmp = simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
+      cmp = simple_cst_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2));
       if (cmp <= 0)
        return cmp;
-      return
-       simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+      if (call_expr_nargs (t1) != call_expr_nargs (t2))
+       return 0;
+      {
+       tree arg1, arg2;
+       call_expr_arg_iterator iter1, iter2;
+       for (arg1 = first_call_expr_arg (t1, &iter1),
+              arg2 = first_call_expr_arg (t2, &iter2);
+            arg1 && arg2;
+            arg1 = next_call_expr_arg (&iter1),
+              arg2 = next_call_expr_arg (&iter2))
+         {
+           cmp = simple_cst_equal (arg1, arg2);
+           if (cmp <= 0)
+             return cmp;
+         }
+       return arg1 == arg2;
+      }
 
     case TARGET_EXPR:
       /* Special case: if either target is an unallocated VAR_DECL,
@@ -5193,7 +5293,7 @@ iterative_hash_expr (tree t, hashval_t val)
              val = iterative_hash_hashval_t (two, val);
            }
          else
-           for (i = TREE_CODE_LENGTH (code) - 1; i >= 0; --i)
+           for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
              val = iterative_hash_expr (TREE_OPERAND (t, i), val);
        }
       return val;
@@ -5744,7 +5844,7 @@ build_complex_type (tree component_type)
        name = 0;
 
       if (name != 0)
-       TYPE_NAME (t) = get_identifier (name);
+       TYPE_NAME (t) = build_decl (TYPE_DECL, get_identifier (name), t);
     }
 
   return build_qualified_type (t, TYPE_QUALS (component_type));
@@ -6038,6 +6138,47 @@ int_fits_type_p (tree c, tree type)
   return !fit_double_type (low, high, &low, &high, type);
 }
 
+/* Stores bounds of an integer TYPE in MIN and MAX.  If TYPE has non-constant
+   bounds or is a POINTER_TYPE, the maximum and/or minimum values that can be
+   represented (assuming two's-complement arithmetic) within the bit
+   precision of the type are returned instead.  */
+
+void
+get_type_static_bounds (tree type, mpz_t min, mpz_t max)
+{
+  if (!POINTER_TYPE_P (type) && TYPE_MIN_VALUE (type)
+      && TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
+    mpz_set_double_int (min, tree_to_double_int (TYPE_MIN_VALUE (type)),
+                       TYPE_UNSIGNED (type));
+  else
+    {
+      if (TYPE_UNSIGNED (type))
+       mpz_set_ui (min, 0);
+      else
+       {
+         double_int mn;
+         mn = double_int_mask (TYPE_PRECISION (type) - 1);
+         mn = double_int_sext (double_int_add (mn, double_int_one),
+                               TYPE_PRECISION (type));
+         mpz_set_double_int (min, mn, false);
+       }
+    }
+
+  if (!POINTER_TYPE_P (type) && TYPE_MAX_VALUE (type) 
+      && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
+    mpz_set_double_int (max, tree_to_double_int (TYPE_MAX_VALUE (type)),
+                       TYPE_UNSIGNED (type));
+  else
+    {
+      if (TYPE_UNSIGNED (type))
+       mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type)),
+                           true);
+      else
+       mpz_set_double_int (max, double_int_mask (TYPE_PRECISION (type) - 1),
+                           true);
+    }
+}
+
 /* Subprogram of following function.  Called by walk_tree.
 
    Return *TP if it is an automatic variable or parameter of the
@@ -6255,7 +6396,7 @@ get_callee_fndecl (tree call)
 
   /* The first operand to the CALL is the address of the function
      called.  */
-  addr = TREE_OPERAND (call, 0);
+  addr = CALL_EXPR_FN (call);
 
   STRIP_NOPS (addr);
 
@@ -6415,7 +6556,7 @@ get_file_function_name (const char *type)
       clean_symbol_name (q);
 
       sprintf (q + len, "_%08X_%08X", crc32_string (0, name),
-              crc32_string (0, flag_random_seed));
+              crc32_string (0, get_random_seed (false)));
 
       p = q;
     }
@@ -6643,7 +6784,7 @@ tree_contains_struct_check_failed (const tree node,
                                   const char *function)
 {
   internal_error
-    ("tree check: expected tree that contains %qs structure, have %qs  in %s, at %s:%d",
+    ("tree check: expected tree that contains %qs structure, have %qs in %s, at %s:%d",
      TS_ENUM_NAME(en),
      tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
 }
@@ -6674,15 +6815,16 @@ phi_node_elt_check_failed (int idx, int len, const char *file, int line,
 }
 
 /* Similar to above, except that the check is for the bounds of the operand
-   vector of an expression node.  */
+   vector of an expression node EXP.  */
 
 void
-tree_operand_check_failed (int idx, enum tree_code code, const char *file,
+tree_operand_check_failed (int idx, tree exp, const char *file,
                           int line, const char *function)
 {
+  int code = TREE_CODE (exp);
   internal_error
     ("tree check: accessed operand %d of %s with %d operands in %s, at %s:%d",
-     idx + 1, tree_code_name[code], TREE_CODE_LENGTH (code),
+     idx + 1, tree_code_name[code], TREE_OPERAND_LENGTH (exp),
      function, trim_filename (file), line);
 }
 
@@ -6921,21 +7063,10 @@ build_common_tree_nodes_2 (int short_double)
   TYPE_MODE (dfloat128_type_node) = TDmode;
   dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
 
-  complex_integer_type_node = make_node (COMPLEX_TYPE);
-  TREE_TYPE (complex_integer_type_node) = integer_type_node;
-  layout_type (complex_integer_type_node);
-
-  complex_float_type_node = make_node (COMPLEX_TYPE);
-  TREE_TYPE (complex_float_type_node) = float_type_node;
-  layout_type (complex_float_type_node);
-
-  complex_double_type_node = make_node (COMPLEX_TYPE);
-  TREE_TYPE (complex_double_type_node) = double_type_node;
-  layout_type (complex_double_type_node);
-
-  complex_long_double_type_node = make_node (COMPLEX_TYPE);
-  TREE_TYPE (complex_long_double_type_node) = long_double_type_node;
-  layout_type (complex_long_double_type_node);
+  complex_integer_type_node = build_complex_type (integer_type_node);
+  complex_float_type_node = build_complex_type (float_type_node);
+  complex_double_type_node = build_complex_type (double_type_node);
+  complex_long_double_type_node = build_complex_type (long_double_type_node);
 
   {
     tree t = targetm.build_builtin_va_list ();
@@ -7146,11 +7277,18 @@ tree
 reconstruct_complex_type (tree type, tree bottom)
 {
   tree inner, outer;
-
-  if (POINTER_TYPE_P (type))
+  
+  if (TREE_CODE (type) == POINTER_TYPE)
     {
       inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
-      outer = build_pointer_type (inner);
+      outer = build_pointer_type_for_mode (inner, TYPE_MODE (type),
+                                          TYPE_REF_CAN_ALIAS_ALL (type));
+    }
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
+    {
+      inner = reconstruct_complex_type (TREE_TYPE (type), bottom);
+      outer = build_reference_type_for_mode (inner, TYPE_MODE (type),
+                                            TYPE_REF_CAN_ALIAS_ALL (type));
     }
   else if (TREE_CODE (type) == ARRAY_TYPE)
     {
@@ -7314,6 +7452,149 @@ build_omp_clause (enum omp_clause_code code)
   return t;
 }
 
+/* Set various status flags when building a CALL_EXPR object T.  */
+
+static void
+process_call_operands (tree t)
+{
+  bool side_effects;
+
+  side_effects = TREE_SIDE_EFFECTS (t);
+  if (!side_effects)
+    {
+      int i, n;
+      n = TREE_OPERAND_LENGTH (t);
+      for (i = 1; i < n; i++)
+       {
+         tree op = TREE_OPERAND (t, i);
+         if (op && TREE_SIDE_EFFECTS (op))
+           {
+             side_effects = 1;
+             break;
+           }
+       }
+    }
+  if (!side_effects)
+    {
+      int i;
+
+      /* Calls have side-effects, except those to const or
+        pure functions.  */
+      i = call_expr_flags (t);
+      if (!(i & (ECF_CONST | ECF_PURE)))
+       side_effects = 1;
+    }
+  TREE_SIDE_EFFECTS (t) = side_effects;
+}
+
+/* Build a tcc_vl_exp object with code CODE and room for LEN operands.  LEN
+   includes the implicit operand count in TREE_OPERAND 0, and so must be >= 1.
+   Except for the CODE and operand count field, other storage for the
+   object is initialized to zeros.  */
+
+tree
+build_vl_exp_stat (enum tree_code code, int len MEM_STAT_DECL)
+{
+  tree t;
+  int length = (len - 1) * sizeof (tree) + sizeof (struct tree_exp);
+
+  gcc_assert (TREE_CODE_CLASS (code) == tcc_vl_exp);
+  gcc_assert (len >= 1);
+
+#ifdef GATHER_STATISTICS
+  tree_node_counts[(int) e_kind]++;
+  tree_node_sizes[(int) e_kind] += length;
+#endif
+
+  t = ggc_alloc_zone_pass_stat (length, &tree_zone);
+
+  memset (t, 0, length);
+
+  TREE_SET_CODE (t, code);
+
+  /* Can't use TREE_OPERAND to store the length because if checking is
+     enabled, it will try to check the length before we store it.  :-P  */
+  t->exp.operands[0] = build_int_cst (sizetype, len);
+
+  return t;
+}
+
+
+/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE
+   and FN and a null static chain slot.  ARGLIST is a TREE_LIST of the
+   arguments.  */
+
+tree
+build_call_list (tree return_type, tree fn, tree arglist)
+{
+  tree t;
+  int i;
+
+  t = build_vl_exp (CALL_EXPR, list_length (arglist) + 3);
+  TREE_TYPE (t) = return_type;
+  CALL_EXPR_FN (t) = fn;
+  CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+  for (i = 0; arglist; arglist = TREE_CHAIN (arglist), i++)
+    CALL_EXPR_ARG (t, i) = TREE_VALUE (arglist);
+  process_call_operands (t);
+  return t;
+}
+
+/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
+   FN and a null static chain slot.  NARGS is the number of call arguments
+   which are specified as "..." arguments.  */
+
+tree
+build_call_nary (tree return_type, tree fn, int nargs, ...)
+{
+  tree ret;
+  va_list args;
+  va_start (args, nargs);
+  ret = build_call_valist (return_type, fn, nargs, args);
+  va_end (args);
+  return ret;
+}
+
+/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
+   FN and a null static chain slot.  NARGS is the number of call arguments
+   which are specified as a va_list ARGS.  */
+
+tree
+build_call_valist (tree return_type, tree fn, int nargs, va_list args)
+{
+  tree t;
+  int i;
+
+  t = build_vl_exp (CALL_EXPR, nargs + 3);
+  TREE_TYPE (t) = return_type;
+  CALL_EXPR_FN (t) = fn;
+  CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+  for (i = 0; i < nargs; i++)
+    CALL_EXPR_ARG (t, i) = va_arg (args, tree);
+  process_call_operands (t);
+  return t;
+}
+
+/* Build a CALL_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE and
+   FN and a null static chain slot.  NARGS is the number of call arguments
+   which are specified as a tree array ARGS.  */
+
+tree
+build_call_array (tree return_type, tree fn, int nargs, tree *args)
+{
+  tree t;
+  int i;
+
+  t = build_vl_exp (CALL_EXPR, nargs + 3);
+  TREE_TYPE (t) = return_type;
+  CALL_EXPR_FN (t) = fn;
+  CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+  for (i = 0; i < nargs; i++)
+    CALL_EXPR_ARG (t, i) = args[i];
+  process_call_operands (t);
+  return t;
+}
+
 
 /* Returns true if it is possible to prove that the index of
    an array access REF (an ARRAY_REF expression) falls into the
@@ -7376,17 +7657,6 @@ range_in_array_bounds_p (tree ref)
   return true;
 }
 
-/* Return true if T (assumed to be a DECL) is a global variable.  */
-
-bool
-is_global_var (tree t)
-{
-  if (MTAG_P (t))
-    return (TREE_STATIC (t) || MTAG_GLOBAL (t));
-  else
-    return (TREE_STATIC (t) || DECL_EXTERNAL (t));
-}
-
 /* Return true if T (assumed to be a DECL) must be assigned a memory
    location.  */
 
@@ -7716,10 +7986,12 @@ walk_type_fields (tree type, walk_tree_fn func, void *data,
       break;
 
     case ARRAY_TYPE:
-      /* Don't follow this nodes's type if a pointer for fear that we'll
-        have infinite recursion.  Those types are uninteresting anyway.  */
-      if (!POINTER_TYPE_P (TREE_TYPE (type))
-         && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE)
+      /* Don't follow this nodes's type if a pointer for fear that
+        we'll have infinite recursion.  If we have a PSET, then we
+        need not fear.  */
+      if (pset
+         || (!POINTER_TYPE_P (TREE_TYPE (type))
+             && TREE_CODE (TREE_TYPE (type)) != OFFSET_TYPE))
        WALK_SUBTREE (TREE_TYPE (type));
       WALK_SUBTREE (TYPE_DOMAIN (type));
       break;
@@ -7997,7 +8269,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
          int i, len;
 
          /* Walk over all the sub-trees of this operand.  */
-         len = TREE_CODE_LENGTH (code);
+         len = TREE_OPERAND_LENGTH (*tp);
 
          /* Go through the subtrees.  We need to do this in forward order so
             that the scope of a FOR_EXPR is handled properly.  */
@@ -8090,4 +8362,19 @@ generic_tree_type (tree node)
   return &TREE_TYPE (node);
 }
 
+/* Build and return a TREE_LIST of arguments in the CALL_EXPR exp.
+   FIXME: don't use this function.  It exists for compatibility with
+   the old representation of CALL_EXPRs where a list was used to hold the
+   arguments.  Places that currently extract the arglist from a CALL_EXPR
+   ought to be rewritten to use the CALL_EXPR itself.  */
+tree
+call_expr_arglist (tree exp)
+{
+  tree arglist = NULL_TREE;
+  int i;
+  for (i = call_expr_nargs (exp) - 1; i >= 0; i--)
+    arglist = tree_cons (NULL_TREE, CALL_EXPR_ARG (exp, i), arglist);
+  return arglist;
+}
+
 #include "gt-tree.h"