]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/tree.c
Merge from trunk.
[thirdparty/gcc.git] / gcc / tree.c
index 97c9c8ac37d0b84cb4ab46937a4424e9d7c6ffd5..1a310e6f1a41ee09f19b16d1a6712c1d4f422e0b 100644 (file)
@@ -33,6 +33,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "flags.h"
 #include "tree.h"
+#include "stor-layout.h"
+#include "calls.h"
+#include "attribs.h"
+#include "varasm.h"
 #include "tm_p.h"
 #include "function.h"
 #include "obstack.h"
@@ -54,7 +58,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-ssa.h"
 #include "cgraph.h"
 #include "tree-phinodes.h"
+#include "stringpool.h"
 #include "tree-ssanames.h"
+#include "expr.h"
 #include "tree-dfa.h"
 #include "params.h"
 #include "pointer-set.h"
@@ -66,6 +72,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "except.h"
 #include "debug.h"
 #include "intl.h"
+#include "wide-int.h"
 
 /* Tree code classes.  */
 
@@ -565,7 +572,7 @@ init_ttree (void)
   int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash,
                                        int_cst_hash_eq, NULL);
 
-  int_cst_node = make_node (INTEGER_CST);
+  int_cst_node = make_int_cst (1, 1);
 
   cl_option_hash_table = htab_create_ggc (64, cl_option_hash_hash,
                                          cl_option_hash_eq, NULL);
@@ -592,7 +599,7 @@ decl_assembler_name (tree decl)
 
 /* Compute the number of bytes occupied by a tree with code CODE.
    This function cannot be used for nodes that have variable sizes,
-   including TREE_VEC, STRING_CST, and CALL_EXPR.  */
+   including TREE_VEC, INTEGER_CST, STRING_CST, and CALL_EXPR.  */
 size_t
 tree_code_size (enum tree_code code)
 {
@@ -640,7 +647,7 @@ tree_code_size (enum tree_code code)
     case tcc_constant:  /* a constant */
       switch (code)
        {
-       case INTEGER_CST:       return sizeof (struct tree_int_cst);
+       case INTEGER_CST:       gcc_unreachable ();
        case REAL_CST:          return sizeof (struct tree_real_cst);
        case FIXED_CST:         return sizeof (struct tree_fixed_cst);
        case COMPLEX_CST:       return sizeof (struct tree_complex);
@@ -687,6 +694,10 @@ tree_size (const_tree node)
   const enum tree_code code = TREE_CODE (node);
   switch (code)
     {
+    case INTEGER_CST:
+      return (sizeof (struct tree_int_cst)
+             + (TREE_INT_CST_EXT_NUNITS (node) - 1) * sizeof (HOST_WIDE_INT));
+
     case TREE_BINFO:
       return (offsetof (struct tree_binfo, base_binfos)
              + vec<tree, va_gc>
@@ -819,8 +830,9 @@ allocate_decl_uid (void)
 
 /* Return a newly allocated node of code CODE.  For decl and type
    nodes, some other fields are initialized.  The rest of the node is
-   initialized to zero.  This function cannot be used for TREE_VEC or
-   OMP_CLAUSE nodes, which is enforced by asserts in tree_code_size.
+   initialized to zero.  This function cannot be used for TREE_VEC,
+   INTEGER_CST or OMP_CLAUSE nodes, which is enforced by asserts in
+   tree_code_size.
 
    Achoo!  I got a code in the node.  */
 
@@ -1008,6 +1020,53 @@ copy_list (tree list)
 }
 
 \f
+/* Return the value that TREE_INT_CST_EXT_NUNITS should have for an
+   INTEGER_CST with value CST and type TYPE.   */
+
+static unsigned int
+get_int_cst_ext_nunits (tree type, const wide_int &cst)
+{
+  gcc_checking_assert (cst.get_precision () == TYPE_PRECISION (type));
+  /* We need an extra zero HWI if CST is an unsigned integer with its
+     upper bit set, and if CST occupies a whole number of HWIs.  */
+  if (TYPE_UNSIGNED (type)
+      && wi::neg_p (cst)
+      && (cst.get_precision () % HOST_BITS_PER_WIDE_INT) == 0)
+    return cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1;
+  return cst.get_len ();
+}
+
+/* Return a new INTEGER_CST with value CST and type TYPE.  */
+
+static tree
+build_new_int_cst (tree type, const wide_int &cst)
+{
+  unsigned int len = cst.get_len ();
+  unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
+  tree nt = make_int_cst (len, ext_len);
+
+  if (len < ext_len)
+    {
+      --ext_len;
+      TREE_INT_CST_ELT (nt, ext_len) = 0;
+      for (unsigned int i = len; i < ext_len; ++i)
+       TREE_INT_CST_ELT (nt, i) = -1;
+    }
+  else if (TYPE_UNSIGNED (type)
+          && cst.get_precision () < len * HOST_BITS_PER_WIDE_INT)
+    {
+      len--;
+      TREE_INT_CST_ELT (nt, len)
+       = zext_hwi (cst.elt (len),
+                   cst.get_precision () % HOST_BITS_PER_WIDE_INT);
+    }
+
+  for (unsigned int i = 0; i < len; i++)
+    TREE_INT_CST_ELT (nt, i) = cst.elt (i);
+  TREE_TYPE (nt) = type;
+  return nt;
+}
+
 /* Create an INT_CST node with a LOW value sign extended to TYPE.  */
 
 tree
@@ -1017,7 +1076,13 @@ build_int_cst (tree type, HOST_WIDE_INT low)
   if (!type)
     type = integer_type_node;
 
-  return double_int_to_tree (type, double_int::from_shwi (low));
+  return wide_int_to_tree (type, wi::shwi (low, TYPE_PRECISION (type)));
+}
+
+tree
+build_int_cstu (tree type, unsigned HOST_WIDE_INT cst)
+{
+  return wide_int_to_tree (type, wi::uhwi (cst, TYPE_PRECISION (type)));
 }
 
 /* Create an INT_CST node with a LOW value sign extended to TYPE.  */
@@ -1026,8 +1091,7 @@ tree
 build_int_cst_type (tree type, HOST_WIDE_INT low)
 {
   gcc_assert (type);
-
-  return double_int_to_tree (type, double_int::from_shwi (low));
+  return wide_int_to_tree (type, wi::shwi (low, TYPE_PRECISION (type)));
 }
 
 /* Constructs tree in type TYPE from with value given by CST.  Signedness
@@ -1036,28 +1100,10 @@ build_int_cst_type (tree type, HOST_WIDE_INT low)
 tree
 double_int_to_tree (tree type, double_int cst)
 {
-  bool sign_extended_type = !TYPE_UNSIGNED (type);
-
-  cst = cst.ext (TYPE_PRECISION (type), !sign_extended_type);
-
-  return build_int_cst_wide (type, cst.low, cst.high);
-}
-
-/* Returns true if CST fits into range of TYPE.  Signedness of CST is assumed
-   to be the same as the signedness of TYPE.  */
-
-bool
-double_int_fits_to_tree_p (const_tree type, double_int cst)
-{
-  bool sign_extended_type = !TYPE_UNSIGNED (type);
-
-  double_int ext
-    = cst.ext (TYPE_PRECISION (type), !sign_extended_type);
-
-  return cst == ext;
+  return wide_int_to_tree (type, widest_int::from (cst, TYPE_SIGN (type)));
 }
 
-/* We force the double_int CST to the range of the type TYPE by sign or
+/* We force the wide_int CST to the range of the type TYPE by sign or
    zero extending it.  OVERFLOWABLE indicates if we are interested in
    overflow of the value, when >0 we are only interested in signed
    overflow, for <0 we are interested in any overflow.  OVERFLOWED
@@ -1068,34 +1114,32 @@ double_int_fits_to_tree_p (const_tree type, double_int cst)
         OVERFLOWED is nonzero,
         or OVERFLOWABLE is >0 and signed overflow occurs
         or OVERFLOWABLE is <0 and any overflow occurs
-   We return a new tree node for the extended double_int.  The node
+   We return a new tree node for the extended wide_int.  The node
    is shared if no overflow flags are set.  */
 
 
 tree
-force_fit_type_double (tree type, double_int cst, int overflowable,
-                      bool overflowed)
+force_fit_type (tree type, const wide_int_ref &cst,
+               int overflowable, bool overflowed)
 {
-  bool sign_extended_type = !TYPE_UNSIGNED (type);
+  signop sign = TYPE_SIGN (type);
 
   /* If we need to set overflow flags, return a new unshared node.  */
-  if (overflowed || !double_int_fits_to_tree_p (type, cst))
+  if (overflowed || !wi::fits_to_tree_p (cst, type))
     {
       if (overflowed
          || overflowable < 0
-         || (overflowable > 0 && sign_extended_type))
+         || (overflowable > 0 && sign == SIGNED))
        {
-         tree t = make_node (INTEGER_CST);
-         TREE_INT_CST (t)
-           = cst.ext (TYPE_PRECISION (type), !sign_extended_type);
-         TREE_TYPE (t) = type;
+         wide_int tmp = wide_int::from (cst, TYPE_PRECISION (type), sign);
+         tree t = build_new_int_cst (type, tmp);
          TREE_OVERFLOW (t) = 1;
          return t;
        }
     }
 
   /* Else build a shared node.  */
-  return double_int_to_tree (type, cst);
+  return wide_int_to_tree (type, cst);
 }
 
 /* These are the hash table functions for the hash table of INTEGER_CST
@@ -1107,9 +1151,13 @@ static hashval_t
 int_cst_hash_hash (const void *x)
 {
   const_tree const t = (const_tree) x;
+  hashval_t code = htab_hash_pointer (TREE_TYPE (t));
+  int i;
 
-  return (TREE_INT_CST_HIGH (t) ^ TREE_INT_CST_LOW (t)
-         ^ htab_hash_pointer (TREE_TYPE (t)));
+  for (i = 0; i < TREE_INT_CST_NUNITS (t); i++)
+    code ^= TREE_INT_CST_ELT (t, i);
+
+  return code;
 }
 
 /* Return nonzero if the value represented by *X (an INTEGER_CST tree node)
@@ -1121,35 +1169,61 @@ int_cst_hash_eq (const void *x, const void *y)
   const_tree const xt = (const_tree) x;
   const_tree const yt = (const_tree) y;
 
-  return (TREE_TYPE (xt) == TREE_TYPE (yt)
-         && TREE_INT_CST_HIGH (xt) == TREE_INT_CST_HIGH (yt)
-         && TREE_INT_CST_LOW (xt) == TREE_INT_CST_LOW (yt));
+  if (TREE_TYPE (xt) != TREE_TYPE (yt)
+      || TREE_INT_CST_NUNITS (xt) != TREE_INT_CST_NUNITS (yt)
+      || TREE_INT_CST_EXT_NUNITS (xt) != TREE_INT_CST_EXT_NUNITS (yt))
+    return false;
+
+  for (int i = 0; i < TREE_INT_CST_NUNITS (xt); i++)
+    if (TREE_INT_CST_ELT (xt, i) != TREE_INT_CST_ELT (yt, i))
+      return false;
+
+  return true;
 }
 
-/* Create an INT_CST node of TYPE and value HI:LOW.
+/* Create an INT_CST node of TYPE and value CST.
    The returned node is always shared.  For small integers we use a
-   per-type vector cache, for larger ones we use a single hash table.  */
+   per-type vector cache, for larger ones we use a single hash table.
+   The value is extended from its precision according to the sign of
+   the type to be a multiple of HOST_BITS_PER_WIDE_INT.  This defines
+   the upper bits and ensures that hashing and value equality based
+   upon the underlying HOST_WIDE_INTs works without masking.  */
 
 tree
-build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
+wide_int_to_tree (tree type, const wide_int_ref &pcst)
 {
   tree t;
   int ix = -1;
   int limit = 0;
 
   gcc_assert (type);
+  unsigned int prec = TYPE_PRECISION (type);
+  signop sgn = TYPE_SIGN (type);
+
+  /* Verify that everything is canonical.  */
+  int l = pcst.get_len ();
+  if (l > 1)
+    {
+      if (pcst.elt (l - 1) == 0)
+       gcc_assert (pcst.elt (l - 2) < 0);
+      if (pcst.elt (l - 1) == (HOST_WIDE_INT) -1)
+       gcc_assert (pcst.elt (l - 2) >= 0);
+    }
+
+  wide_int cst = wide_int::from (pcst, prec, sgn);
+  unsigned int ext_len = get_int_cst_ext_nunits (type, cst);
 
   switch (TREE_CODE (type))
     {
     case NULLPTR_TYPE:
-      gcc_assert (hi == 0 && low == 0);
+      gcc_assert (cst == 0);
       /* Fallthru.  */
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
     case POINTER_BOUNDS_TYPE:
       /* Cache NULL pointer and zero bounds.  */
-      if (!hi && !low)
+      if (cst == 0)
        {
          limit = 1;
          ix = 0;
@@ -1159,27 +1233,45 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
     case BOOLEAN_TYPE:
       /* Cache false or true.  */
       limit = 2;
-      if (!hi && low < 2)
-       ix = low;
+      if (wi::leu_p (cst, 1))
+       ix = cst.to_uhwi ();
       break;
 
     case INTEGER_TYPE:
     case OFFSET_TYPE:
-      if (TYPE_UNSIGNED (type))
+      if (TYPE_SIGN (type) == UNSIGNED)
        {
          /* Cache 0..N */
          limit = INTEGER_SHARE_LIMIT;
-         if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
-           ix = low;
+
+         /* This is a little hokie, but if the prec is smaller than
+            what is necessary to hold INTEGER_SHARE_LIMIT, then the
+            obvious test will not get the correct answer.  */
+         if (prec < HOST_BITS_PER_WIDE_INT)
+           {
+             if (cst.to_uhwi () < (unsigned HOST_WIDE_INT) INTEGER_SHARE_LIMIT)
+               ix = cst.to_uhwi ();
+           }
+         else if (wi::ltu_p (cst, INTEGER_SHARE_LIMIT))
+           ix = cst.to_uhwi ();
        }
       else
        {
          /* Cache -1..N */
          limit = INTEGER_SHARE_LIMIT + 1;
-         if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
-           ix = low + 1;
-         else if (hi == -1 && low == -(unsigned HOST_WIDE_INT)1)
+
+         if (cst == -1)
            ix = 0;
+         else if (!wi::neg_p (cst))
+           {
+             if (prec < HOST_BITS_PER_WIDE_INT)
+               {
+                 if (cst.to_shwi () < INTEGER_SHARE_LIMIT)
+                   ix = cst.to_shwi () + 1;
+               }
+             else if (wi::lts_p (cst, INTEGER_SHARE_LIMIT))
+               ix = cst.to_shwi () + 1;
+           }
        }
       break;
 
@@ -1190,53 +1282,73 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi)
       gcc_unreachable ();
     }
 
-  if (ix >= 0)
+  if (ext_len == 1)
     {
-      /* Look for it in the type's vector of small shared ints.  */
-      if (!TYPE_CACHED_VALUES_P (type))
+      /* We just need to store a single HOST_WIDE_INT.  */
+      HOST_WIDE_INT hwi;
+      if (TYPE_UNSIGNED (type))
+       hwi = cst.to_uhwi ();
+      else
+       hwi = cst.to_shwi ();
+      if (ix >= 0)
        {
-         TYPE_CACHED_VALUES_P (type) = 1;
-         TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
-       }
+         /* Look for it in the type's vector of small shared ints.  */
+         if (!TYPE_CACHED_VALUES_P (type))
+           {
+             TYPE_CACHED_VALUES_P (type) = 1;
+             TYPE_CACHED_VALUES (type) = make_tree_vec (limit);
+           }
 
-      t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
-      if (t)
-       {
-         /* Make sure no one is clobbering the shared constant.  */
-         gcc_assert (TREE_TYPE (t) == type);
-         gcc_assert (TREE_INT_CST_LOW (t) == low);
-         gcc_assert (TREE_INT_CST_HIGH (t) == hi);
+         t = TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix);
+         if (t)
+           /* Make sure no one is clobbering the shared constant.  */
+           gcc_assert (TREE_TYPE (t) == type
+                       && TREE_INT_CST_NUNITS (t) == 1
+                       && TREE_INT_CST_EXT_NUNITS (t) == 1
+                       && TREE_INT_CST_ELT (t, 0) == hwi);
+         else
+           {
+             /* Create a new shared int.  */
+             t = build_new_int_cst (type, cst);
+             TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
+           }
        }
       else
        {
-         /* Create a new shared int.  */
-         t = make_node (INTEGER_CST);
+         /* Use the cache of larger shared ints, using int_cst_node as
+            a temporary.  */
+         void **slot;
 
-         TREE_INT_CST_LOW (t) = low;
-         TREE_INT_CST_HIGH (t) = hi;
-         TREE_TYPE (t) = type;
+         TREE_INT_CST_ELT (int_cst_node, 0) = hwi;
+         TREE_TYPE (int_cst_node) = type;
 
-         TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t;
+         slot = htab_find_slot (int_cst_hash_table, int_cst_node, INSERT);
+         t = (tree) *slot;
+         if (!t)
+           {
+             /* Insert this one into the hash table.  */
+             t = int_cst_node;
+             *slot = t;
+             /* Make a new node for next time round.  */
+             int_cst_node = make_int_cst (1, 1);
+           }
        }
     }
   else
     {
-      /* Use the cache of larger shared ints.  */
+      /* The value either hashes properly or we drop it on the floor
+        for the gc to take care of.  There will not be enough of them
+        to worry about.  */
       void **slot;
 
-      TREE_INT_CST_LOW (int_cst_node) = low;
-      TREE_INT_CST_HIGH (int_cst_node) = hi;
-      TREE_TYPE (int_cst_node) = type;
-
-      slot = htab_find_slot (int_cst_hash_table, int_cst_node, INSERT);
+      tree nt = build_new_int_cst (type, cst);
+      slot = htab_find_slot (int_cst_hash_table, nt, INSERT);
       t = (tree) *slot;
       if (!t)
        {
          /* Insert this one into the hash table.  */
-         t = int_cst_node;
+         t = nt;
          *slot = t;
-         /* Make a new node for next time round.  */
-         int_cst_node = make_node (INTEGER_CST);
        }
     }
 
@@ -1247,23 +1359,22 @@ void
 cache_integer_cst (tree t)
 {
   tree type = TREE_TYPE (t);
-  HOST_WIDE_INT hi = TREE_INT_CST_HIGH (t);
-  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (t);
   int ix = -1;
   int limit = 0;
+  int prec = TYPE_PRECISION (type);
 
   gcc_assert (!TREE_OVERFLOW (t));
 
   switch (TREE_CODE (type))
     {
     case NULLPTR_TYPE:
-      gcc_assert (hi == 0 && low == 0);
+      gcc_assert (integer_zerop (t));
       /* Fallthru.  */
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       /* Cache NULL pointer.  */
-      if (!hi && !low)
+      if (integer_zerop (t))
        {
          limit = 1;
          ix = 0;
@@ -1273,8 +1384,8 @@ cache_integer_cst (tree t)
     case BOOLEAN_TYPE:
       /* Cache false or true.  */
       limit = 2;
-      if (!hi && low < 2)
-       ix = low;
+      if (wi::ltu_p (t, 2))
+       ix = TREE_INT_CST_ELT (t, 0);
       break;
 
     case INTEGER_TYPE:
@@ -1283,17 +1394,35 @@ cache_integer_cst (tree t)
        {
          /* Cache 0..N */
          limit = INTEGER_SHARE_LIMIT;
-         if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
-           ix = low;
+
+         /* This is a little hokie, but if the prec is smaller than
+            what is necessary to hold INTEGER_SHARE_LIMIT, then the
+            obvious test will not get the correct answer.  */
+         if (prec < HOST_BITS_PER_WIDE_INT)
+           {
+             if (tree_to_uhwi (t) < (unsigned HOST_WIDE_INT) INTEGER_SHARE_LIMIT)
+               ix = tree_to_uhwi (t);
+           }
+         else if (wi::ltu_p (t, INTEGER_SHARE_LIMIT))
+           ix = tree_to_uhwi (t);
        }
       else
        {
          /* Cache -1..N */
          limit = INTEGER_SHARE_LIMIT + 1;
-         if (!hi && low < (unsigned HOST_WIDE_INT)INTEGER_SHARE_LIMIT)
-           ix = low + 1;
-         else if (hi == -1 && low == -(unsigned HOST_WIDE_INT)1)
+
+         if (integer_minus_onep (t))
            ix = 0;
+         else if (!wi::neg_p (t))
+           {
+             if (prec < HOST_BITS_PER_WIDE_INT)
+               {
+                 if (tree_to_shwi (t) < INTEGER_SHARE_LIMIT)
+                   ix = tree_to_shwi (t) + 1;
+               }
+             else if (wi::ltu_p (t, INTEGER_SHARE_LIMIT))
+               ix = tree_to_shwi (t) + 1;
+           }
        }
       break;
 
@@ -1325,13 +1454,10 @@ cache_integer_cst (tree t)
       /* If there is already an entry for the number verify it's the
          same.  */
       if (*slot)
-       {
-         gcc_assert (TREE_INT_CST_LOW ((tree)*slot) == low
-                     && TREE_INT_CST_HIGH ((tree)*slot) == hi);
-         return;
-       }
-      /* Otherwise insert this one into the hash table.  */
-      *slot = t;
+       gcc_assert (wi::eq_p (tree (*slot), t));
+      else
+       /* Otherwise insert this one into the hash table.  */
+       *slot = t;
     }
 }
 
@@ -1342,34 +1468,10 @@ cache_integer_cst (tree t)
 tree
 build_low_bits_mask (tree type, unsigned bits)
 {
-  double_int mask;
-
   gcc_assert (bits <= TYPE_PRECISION (type));
 
-  if (bits == TYPE_PRECISION (type)
-      && !TYPE_UNSIGNED (type))
-    /* Sign extended all-ones mask.  */
-    mask = double_int_minus_one;
-  else
-    mask = double_int::mask (bits);
-
-  return build_int_cst_wide (type, mask.low, mask.high);
-}
-
-/* Checks that X is integer constant that can be expressed in (unsigned)
-   HOST_WIDE_INT without loss of precision.  */
-
-bool
-cst_and_fits_in_hwi (const_tree x)
-{
-  if (TREE_CODE (x) != INTEGER_CST)
-    return false;
-
-  if (TYPE_PRECISION (TREE_TYPE (x)) > HOST_BITS_PER_WIDE_INT)
-    return false;
-
-  return (TREE_INT_CST_HIGH (x) == 0
-         || TREE_INT_CST_HIGH (x) == -1);
+  return wide_int_to_tree (type, wi::mask (bits, false,
+                                          TYPE_PRECISION (type)));
 }
 
 /* Build a newly constructed TREE_VEC node of length LEN.  */
@@ -1610,8 +1712,7 @@ real_value_from_int_cst (const_tree type, const_tree i)
   memset (&d, 0, sizeof d);
 
   real_from_integer (&d, type ? TYPE_MODE (type) : VOIDmode,
-                    TREE_INT_CST_LOW (i), TREE_INT_CST_HIGH (i),
-                    TYPE_UNSIGNED (TREE_TYPE (i)));
+                    wide_int (i), TYPE_SIGN (TREE_TYPE (i)));
   return d;
 }
 
@@ -1849,6 +1950,30 @@ build_case_label (tree low_value, tree high_value, tree label_decl)
   return t;
 }
 
+/* Build a newly constructed INTEGER_CST node.  LEN and EXT_LEN are the
+   values of TREE_INT_CST_NUNITS and TREE_INT_CST_EXT_NUNITS respectively.
+   The latter determines the length of the HOST_WIDE_INT vector.  */
+
+tree
+make_int_cst_stat (int len, int ext_len MEM_STAT_DECL)
+{
+  tree t;
+  int length = (ext_len - 1) * sizeof (tree) + sizeof (struct tree_int_cst);
+
+  gcc_assert (len);
+  record_node_allocation_statistics (INTEGER_CST, length);
+
+  t = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
+
+  TREE_SET_CODE (t, INTEGER_CST);
+  TREE_INT_CST_NUNITS (t) = len;
+  TREE_INT_CST_EXT_NUNITS (t) = ext_len;
+
+  TREE_CONSTANT (t) = 1;
+
+  return t;
+}
+
 /* Build a newly constructed TREE_VEC node of length LEN.  */
 
 tree
@@ -1900,8 +2025,7 @@ integer_zerop (const_tree expr)
   switch (TREE_CODE (expr))
     {
     case INTEGER_CST:
-      return (TREE_INT_CST_LOW (expr) == 0
-             && TREE_INT_CST_HIGH (expr) == 0);
+      return wi::eq_p (expr, 0);
     case COMPLEX_CST:
       return (integer_zerop (TREE_REALPART (expr))
              && integer_zerop (TREE_IMAGPART (expr)));
@@ -1929,8 +2053,7 @@ integer_onep (const_tree expr)
   switch (TREE_CODE (expr))
     {
     case INTEGER_CST:
-      return (TREE_INT_CST_LOW (expr) == 1
-             && TREE_INT_CST_HIGH (expr) == 0);
+      return wi::eq_p (wi::to_widest (expr), 1);
     case COMPLEX_CST:
       return (integer_onep (TREE_REALPART (expr))
              && integer_zerop (TREE_IMAGPART (expr)));
@@ -1953,9 +2076,6 @@ integer_onep (const_tree expr)
 int
 integer_all_onesp (const_tree expr)
 {
-  int prec;
-  int uns;
-
   STRIP_NOPS (expr);
 
   if (TREE_CODE (expr) == COMPLEX_CST
@@ -1975,35 +2095,7 @@ integer_all_onesp (const_tree expr)
   else if (TREE_CODE (expr) != INTEGER_CST)
     return 0;
 
-  uns = TYPE_UNSIGNED (TREE_TYPE (expr));
-  if (TREE_INT_CST_LOW (expr) == ~(unsigned HOST_WIDE_INT) 0
-      && TREE_INT_CST_HIGH (expr) == -1)
-    return 1;
-  if (!uns)
-    return 0;
-
-  prec = TYPE_PRECISION (TREE_TYPE (expr));
-  if (prec >= HOST_BITS_PER_WIDE_INT)
-    {
-      HOST_WIDE_INT high_value;
-      int shift_amount;
-
-      shift_amount = prec - HOST_BITS_PER_WIDE_INT;
-
-      /* Can not handle precisions greater than twice the host int size.  */
-      gcc_assert (shift_amount <= HOST_BITS_PER_WIDE_INT);
-      if (shift_amount == HOST_BITS_PER_WIDE_INT)
-       /* Shifting by the host word size is undefined according to the ANSI
-          standard, so we must handle this as a special case.  */
-       high_value = -1;
-      else
-       high_value = ((HOST_WIDE_INT) 1 << shift_amount) - 1;
-
-      return (TREE_INT_CST_LOW (expr) == ~(unsigned HOST_WIDE_INT) 0
-             && TREE_INT_CST_HIGH (expr) == high_value);
-    }
-  else
-    return TREE_INT_CST_LOW (expr) == ((unsigned HOST_WIDE_INT) 1 << prec) - 1;
+  return wi::max_value (TYPE_PRECISION (TREE_TYPE (expr)), UNSIGNED) == expr;
 }
 
 /* Return 1 if EXPR is the integer constant minus one.  */
@@ -2026,9 +2118,6 @@ integer_minus_onep (const_tree expr)
 int
 integer_pow2p (const_tree expr)
 {
-  int prec;
-  unsigned HOST_WIDE_INT high, low;
-
   STRIP_NOPS (expr);
 
   if (TREE_CODE (expr) == COMPLEX_CST
@@ -2039,29 +2128,7 @@ integer_pow2p (const_tree expr)
   if (TREE_CODE (expr) != INTEGER_CST)
     return 0;
 
-  prec = TYPE_PRECISION (TREE_TYPE (expr));
-  high = TREE_INT_CST_HIGH (expr);
-  low = TREE_INT_CST_LOW (expr);
-
-  /* First clear all bits that are beyond the type's precision in case
-     we've been sign extended.  */
-
-  if (prec == HOST_BITS_PER_DOUBLE_INT)
-    ;
-  else if (prec > HOST_BITS_PER_WIDE_INT)
-    high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT));
-  else
-    {
-      high = 0;
-      if (prec < HOST_BITS_PER_WIDE_INT)
-       low &= ~(HOST_WIDE_INT_M1U << prec);
-    }
-
-  if (high == 0 && low == 0)
-    return 0;
-
-  return ((high == 0 && (low & (low - 1)) == 0)
-         || (low == 0 && (high & (high - 1)) == 0));
+  return wi::popcount (expr) == 1;
 }
 
 /* Return 1 if EXPR is an integer constant other than zero or a
@@ -2073,8 +2140,7 @@ integer_nonzerop (const_tree expr)
   STRIP_NOPS (expr);
 
   return ((TREE_CODE (expr) == INTEGER_CST
-          && (TREE_INT_CST_LOW (expr) != 0
-              || TREE_INT_CST_HIGH (expr) != 0))
+          && !wi::eq_p (expr, 0))
          || (TREE_CODE (expr) == COMPLEX_CST
              && (integer_nonzerop (TREE_REALPART (expr))
                  || integer_nonzerop (TREE_IMAGPART (expr)))));
@@ -2095,34 +2161,12 @@ fixed_zerop (const_tree expr)
 int
 tree_log2 (const_tree expr)
 {
-  int prec;
-  HOST_WIDE_INT high, low;
-
   STRIP_NOPS (expr);
 
   if (TREE_CODE (expr) == COMPLEX_CST)
     return tree_log2 (TREE_REALPART (expr));
 
-  prec = TYPE_PRECISION (TREE_TYPE (expr));
-  high = TREE_INT_CST_HIGH (expr);
-  low = TREE_INT_CST_LOW (expr);
-
-  /* First clear all bits that are beyond the type's precision in case
-     we've been sign extended.  */
-
-  if (prec == HOST_BITS_PER_DOUBLE_INT)
-    ;
-  else if (prec > HOST_BITS_PER_WIDE_INT)
-    high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT));
-  else
-    {
-      high = 0;
-      if (prec < HOST_BITS_PER_WIDE_INT)
-       low &= ~(HOST_WIDE_INT_M1U << prec);
-    }
-
-  return (high != 0 ? HOST_BITS_PER_WIDE_INT + exact_log2 (high)
-         : exact_log2 (low));
+  return wi::exact_log2 (expr);
 }
 
 /* Similar, but return the largest integer Y such that 2 ** Y is less
@@ -2131,35 +2175,12 @@ tree_log2 (const_tree expr)
 int
 tree_floor_log2 (const_tree expr)
 {
-  int prec;
-  HOST_WIDE_INT high, low;
-
   STRIP_NOPS (expr);
 
   if (TREE_CODE (expr) == COMPLEX_CST)
     return tree_log2 (TREE_REALPART (expr));
 
-  prec = TYPE_PRECISION (TREE_TYPE (expr));
-  high = TREE_INT_CST_HIGH (expr);
-  low = TREE_INT_CST_LOW (expr);
-
-  /* First clear all bits that are beyond the type's precision in case
-     we've been sign extended.  Ignore if type's precision hasn't been set
-     since what we are doing is setting it.  */
-
-  if (prec == HOST_BITS_PER_DOUBLE_INT || prec == 0)
-    ;
-  else if (prec > HOST_BITS_PER_WIDE_INT)
-    high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT));
-  else
-    {
-      high = 0;
-      if (prec < HOST_BITS_PER_WIDE_INT)
-       low &= ~(HOST_WIDE_INT_M1U << prec);
-    }
-
-  return (high != 0 ? HOST_BITS_PER_WIDE_INT + floor_log2 (high)
-         : floor_log2 (low));
+  return wi::floor_log2 (expr);
 }
 
 /* Return number of known trailing zero bits in EXPR, or, if the value of
@@ -2176,10 +2197,10 @@ tree_ctz (const_tree expr)
   switch (TREE_CODE (expr))
     {
     case INTEGER_CST:
-      ret1 = tree_to_double_int (expr).trailing_zeros ();
+      ret1 = wi::ctz (expr);
       return MIN (ret1, prec);
     case SSA_NAME:
-      ret1 = get_nonzero_bits (expr).trailing_zeros ();
+      ret1 = wi::ctz (get_nonzero_bits (expr));
       return MIN (ret1, prec);
     case PLUS_EXPR:
     case MINUS_EXPR:
@@ -2210,21 +2231,19 @@ tree_ctz (const_tree expr)
       return MIN (ret1 + ret2, prec);
     case LSHIFT_EXPR:
       ret1 = tree_ctz (TREE_OPERAND (expr, 0));
-      if (host_integerp (TREE_OPERAND (expr, 1), 1)
-         && ((unsigned HOST_WIDE_INT) tree_low_cst (TREE_OPERAND (expr, 1), 1)
-             < (unsigned HOST_WIDE_INT) prec))
+      if (tree_fits_uhwi_p (TREE_OPERAND (expr, 1))
+         && (tree_to_uhwi (TREE_OPERAND (expr, 1)) < prec))
        {
-         ret2 = tree_low_cst (TREE_OPERAND (expr, 1), 1);
+         ret2 = tree_to_uhwi (TREE_OPERAND (expr, 1));
          return MIN (ret1 + ret2, prec);
        }
       return ret1;
     case RSHIFT_EXPR:
-      if (host_integerp (TREE_OPERAND (expr, 1), 1)
-         && ((unsigned HOST_WIDE_INT) tree_low_cst (TREE_OPERAND (expr, 1), 1)
-             < (unsigned HOST_WIDE_INT) prec))
+      if (tree_fits_uhwi_p (TREE_OPERAND (expr, 1))
+         && (tree_to_uhwi (TREE_OPERAND (expr, 1)) < prec))
        {
          ret1 = tree_ctz (TREE_OPERAND (expr, 0));
-         ret2 = tree_low_cst (TREE_OPERAND (expr, 1), 1);
+         ret2 = tree_to_uhwi (TREE_OPERAND (expr, 1));
          if (ret1 > ret2)
            return ret1 - ret2;
        }
@@ -2649,14 +2668,11 @@ int_size_in_bytes (const_tree type)
 
   type = TYPE_MAIN_VARIANT (type);
   t = TYPE_SIZE_UNIT (type);
-  if (t == 0
-      || TREE_CODE (t) != INTEGER_CST
-      || TREE_INT_CST_HIGH (t) != 0
-      /* If the result would appear negative, it's too big to represent.  */
-      || (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0)
-    return -1;
 
-  return TREE_INT_CST_LOW (t);
+  if (t && cst_fits_uhwi_p (t))
+    return TREE_INT_CST_LOW (t);
+  else
+    return -1;
 }
 
 /* Return the maximum size of TYPE (in bytes) as a wide integer
@@ -2674,8 +2690,8 @@ max_int_size_in_bytes (const_tree type)
     {
       size_tree = TYPE_ARRAY_MAX_SIZE (type);
 
-      if (size_tree && host_integerp (size_tree, 1))
-       size = tree_low_cst (size_tree, 1);
+      if (size_tree && tree_fits_uhwi_p (size_tree))
+       size = tree_to_uhwi (size_tree);
     }
 
   /* If we still haven't been able to get a size, see if the language
@@ -2685,8 +2701,8 @@ max_int_size_in_bytes (const_tree type)
     {
       size_tree = lang_hooks.types.max_size (type);
 
-      if (size_tree && host_integerp (size_tree, 1))
-       size = tree_low_cst (size_tree, 1);
+      if (size_tree && tree_fits_uhwi_p (size_tree))
+       size = tree_to_uhwi (size_tree);
     }
 
   return size;
@@ -2709,7 +2725,7 @@ bit_position (const_tree field)
 HOST_WIDE_INT
 int_bit_position (const_tree field)
 {
-  return tree_low_cst (bit_position (field), 0);
+  return tree_to_shwi (bit_position (field));
 }
 \f
 /* Return the byte position of FIELD, in bytes from the start of the record.
@@ -2729,7 +2745,7 @@ byte_position (const_tree field)
 HOST_WIDE_INT
 int_byte_position (const_tree field)
 {
-  return tree_low_cst (byte_position (field), 0);
+  return tree_to_shwi (byte_position (field));
 }
 \f
 /* Return the strictest alignment, in bits, that T is known to have.  */
@@ -4305,11 +4321,10 @@ build_simple_mem_ref_loc (location_t loc, tree ptr)
 
 /* Return the constant offset of a MEM_REF or TARGET_MEM_REF tree T.  */
 
-double_int
+offset_int
 mem_ref_offset (const_tree t)
 {
-  tree toff = TREE_OPERAND (t, 1);
-  return tree_to_double_int (toff).sext (TYPE_PRECISION (TREE_TYPE (toff)));
+  return offset_int::from (TREE_OPERAND (t, 1), SIGNED);
 }
 
 /* Return an invariant ADDR_EXPR of type TYPE taking the address of BASE
@@ -4533,6 +4548,8 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
     {
       hashval_t hashcode = 0;
       tree ntype;
+      int i;
+      tree t;
       enum tree_code code = TREE_CODE (ttype);
 
       /* Building a distinct copy of a tagged type is inappropriate; it
@@ -4574,10 +4591,9 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
                                              hashcode);
          break;
        case INTEGER_TYPE:
-         hashcode = iterative_hash_object
-           (TREE_INT_CST_LOW (TYPE_MAX_VALUE (ntype)), hashcode);
-         hashcode = iterative_hash_object
-           (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (ntype)), hashcode);
+         t = TYPE_MAX_VALUE (ntype);
+         for (i = 0; i < TREE_INT_CST_NUNITS (t); i++)
+           hashcode = iterative_hash_object (TREE_INT_CST_ELT (t, i), hashcode);
          break;
        case REAL_TYPE:
        case FIXED_POINT_TYPE:
@@ -5040,7 +5056,7 @@ free_lang_data_in_decl (tree decl)
          DECL_VINDEX referring to itself into a vtable slot number as it
         should.  Happens with functions that are copied and then forgotten
         about.  Just clear it, it won't matter anymore.  */
-      if (DECL_VINDEX (decl) && !host_integerp (DECL_VINDEX (decl), 0))
+      if (DECL_VINDEX (decl) && !tree_fits_shwi_p (DECL_VINDEX (decl)))
        DECL_VINDEX (decl) = NULL_TREE;
     }
   else if (TREE_CODE (decl) == VAR_DECL)
@@ -6120,7 +6136,7 @@ find_atomic_core_type (tree type)
   if (TYPE_SIZE (type) == NULL_TREE)
     return NULL_TREE;
 
-  HOST_WIDE_INT type_size = tree_low_cst (TYPE_SIZE (type), 1);
+  HOST_WIDE_INT type_size = tree_to_uhwi (TYPE_SIZE (type));
   switch (type_size)
     {
     case 8:
@@ -6624,6 +6640,8 @@ type_hash_eq (const void *va, const void *vb)
     case INTEGER_TYPE:
     case REAL_TYPE:
     case BOOLEAN_TYPE:
+      if (TYPE_PRECISION (a->type) != TYPE_PRECISION (b->type))
+       return false;
       return ((TYPE_MAX_VALUE (a->type) == TYPE_MAX_VALUE (b->type)
               || tree_int_cst_equal (TYPE_MAX_VALUE (a->type),
                                      TYPE_MAX_VALUE (b->type)))
@@ -6922,8 +6940,7 @@ tree_int_cst_equal (const_tree t1, const_tree t2)
 
   if (TREE_CODE (t1) == INTEGER_CST
       && TREE_CODE (t2) == INTEGER_CST
-      && TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
-      && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2))
+      && wi::to_widest (t1) == wi::to_widest (t2))
     return 1;
 
   return 0;
@@ -6935,26 +6952,7 @@ tree_int_cst_equal (const_tree t1, const_tree t2)
 int
 tree_int_cst_lt (const_tree t1, const_tree t2)
 {
-  if (t1 == t2)
-    return 0;
-
-  if (TYPE_UNSIGNED (TREE_TYPE (t1)) != TYPE_UNSIGNED (TREE_TYPE (t2)))
-    {
-      int t1_sgn = tree_int_cst_sgn (t1);
-      int t2_sgn = tree_int_cst_sgn (t2);
-
-      if (t1_sgn < t2_sgn)
-       return 1;
-      else if (t1_sgn > t2_sgn)
-       return 0;
-      /* Otherwise, both are non-negative, so we compare them as
-        unsigned just in case one of them would overflow a signed
-        type.  */
-    }
-  else if (!TYPE_UNSIGNED (TREE_TYPE (t1)))
-    return INT_CST_LT (t1, t2);
-
-  return INT_CST_LT_UNSIGNED (t1, t2);
+  return INT_CST_LT (t1, t2);
 }
 
 /* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2.  */
@@ -6962,43 +6960,51 @@ tree_int_cst_lt (const_tree t1, const_tree t2)
 int
 tree_int_cst_compare (const_tree t1, const_tree t2)
 {
-  if (tree_int_cst_lt (t1, t2))
-    return -1;
-  else if (tree_int_cst_lt (t2, t1))
-    return 1;
-  else
-    return 0;
+  return wi::cmps (wi::to_widest (t1), wi::to_widest (t2));
 }
 
-/* Return 1 if T is an INTEGER_CST that can be manipulated efficiently on
-   the host.  If POS is zero, the value can be represented in a single
-   HOST_WIDE_INT.  If POS is nonzero, the value must be non-negative and can
-   be represented in a single unsigned HOST_WIDE_INT.  */
+/* Return true if T is an INTEGER_CST whose numerical value (extended
+   according to TYPE_UNSIGNED) fits in a signed HOST_WIDE_INT.  */
 
-int
-host_integerp (const_tree t, int pos)
+bool
+tree_fits_shwi_p (const_tree t)
 {
-  if (t == NULL_TREE)
-    return 0;
+  return (t != NULL_TREE
+         && TREE_CODE (t) == INTEGER_CST
+         && wi::fits_shwi_p (wi::to_widest (t)));
+}
 
-  return (TREE_CODE (t) == INTEGER_CST
-         && ((TREE_INT_CST_HIGH (t) == 0
-              && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0)
-             || (! pos && TREE_INT_CST_HIGH (t) == -1
-                 && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0
-                 && !TYPE_UNSIGNED (TREE_TYPE (t)))
-             || (pos && TREE_INT_CST_HIGH (t) == 0)));
+/* Return true if T is an INTEGER_CST whose numerical value (extended
+   according to TYPE_UNSIGNED) fits in an unsigned HOST_WIDE_INT.  */
+
+bool
+tree_fits_uhwi_p (const_tree t)
+{
+  return (t != NULL_TREE
+         && TREE_CODE (t) == INTEGER_CST
+         && wi::fits_uhwi_p (wi::to_widest (t)));
 }
 
-/* Return the HOST_WIDE_INT least significant bits of T if it is an
-   INTEGER_CST and there is no overflow.  POS is nonzero if the result must
-   be non-negative.  We must be able to satisfy the above conditions.  */
+/* T is an INTEGER_CST whose numerical value (extended according to
+   TYPE_UNSIGNED) fits in a signed HOST_WIDE_INT.  Return that
+   HOST_WIDE_INT.  */
 
 HOST_WIDE_INT
-tree_low_cst (const_tree t, int pos)
+tree_to_shwi (const_tree t)
+{
+  gcc_assert (tree_fits_shwi_p (t));
+  return TREE_INT_CST_ELT (t, 0);
+}
+
+/* T is an INTEGER_CST whose numerical value (extended according to
+   TYPE_UNSIGNED) fits in an unsigned HOST_WIDE_INT.  Return that
+   HOST_WIDE_INT.  */
+
+unsigned HOST_WIDE_INT
+tree_to_uhwi (const_tree t)
 {
-  gcc_assert (host_integerp (t, pos));
-  return TREE_INT_CST_LOW (t);
+  gcc_assert (tree_fits_uhwi_p (t));
+  return TREE_INT_CST_ELT (t, 0);
 }
 
 /* Return the most significant (sign) bit of T.  */
@@ -7007,17 +7013,8 @@ int
 tree_int_cst_sign_bit (const_tree t)
 {
   unsigned bitno = TYPE_PRECISION (TREE_TYPE (t)) - 1;
-  unsigned HOST_WIDE_INT w;
 
-  if (bitno < HOST_BITS_PER_WIDE_INT)
-    w = TREE_INT_CST_LOW (t);
-  else
-    {
-      w = TREE_INT_CST_HIGH (t);
-      bitno -= HOST_BITS_PER_WIDE_INT;
-    }
-
-  return (w >> bitno) & 1;
+  return wi::extract_uhwi (t, bitno, 1);
 }
 
 /* Return an indication of the sign of the integer constant T.
@@ -7027,11 +7024,11 @@ tree_int_cst_sign_bit (const_tree t)
 int
 tree_int_cst_sgn (const_tree t)
 {
-  if (TREE_INT_CST_LOW (t) == 0 && TREE_INT_CST_HIGH (t) == 0)
+  if (wi::eq_p (t, 0))
     return 0;
   else if (TYPE_UNSIGNED (TREE_TYPE (t)))
     return 1;
-  else if (TREE_INT_CST_HIGH (t) < 0)
+  else if (wi::neg_p (t))
     return -1;
   else
     return 1;
@@ -7041,7 +7038,7 @@ tree_int_cst_sgn (const_tree t)
    signed or unsigned type, UNSIGNEDP says which.  */
 
 unsigned int
-tree_int_cst_min_precision (tree value, bool unsignedp)
+tree_int_cst_min_precision (tree value, signop sgn)
 {
   /* If the value is negative, compute its negative minus 1.  The latter
      adjustment is because the absolute value of the largest negative value
@@ -7059,7 +7056,7 @@ tree_int_cst_min_precision (tree value, bool unsignedp)
   if (integer_zerop (value))
     return 1;
   else
-    return tree_floor_log2 (value) + 1 + !unsignedp;
+    return tree_floor_log2 (value) + 1 + (sgn == SIGNED ? 1 : 0) ;
 }
 
 /* Return truthvalue of whether T1 is the same tree structure as T2.
@@ -7102,8 +7099,7 @@ simple_cst_equal (const_tree t1, const_tree t2)
   switch (code1)
     {
     case INTEGER_CST:
-      return (TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
-             && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2));
+      return wi::to_widest (t1) == wi::to_widest (t2);
 
     case REAL_CST:
       return REAL_VALUES_IDENTICAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));
@@ -7239,7 +7235,7 @@ compare_tree_int (const_tree t, unsigned HOST_WIDE_INT u)
 {
   if (tree_int_cst_sgn (t) < 0)
     return -1;
-  else if (TREE_INT_CST_HIGH (t) != 0)
+  else if (!cst_fits_uhwi_p (t))
     return 1;
   else if (TREE_INT_CST_LOW (t) == u)
     return 0;
@@ -7256,7 +7252,7 @@ compare_tree_int (const_tree t, unsigned HOST_WIDE_INT u)
 bool
 valid_constant_size_p (const_tree size)
 {
-  if (! host_integerp (size, 1)
+  if (! tree_fits_uhwi_p (size)
       || TREE_OVERFLOW (size)
       || tree_int_cst_sign_bit (size) != 0)
     return false;
@@ -7375,8 +7371,9 @@ iterative_hash_expr (const_tree t, hashval_t val)
     /* Alas, constants aren't shared, so we can't rely on pointer
        identity.  */
     case INTEGER_CST:
-      val = iterative_hash_host_wide_int (TREE_INT_CST_LOW (t), val);
-      return iterative_hash_host_wide_int (TREE_INT_CST_HIGH (t), val);
+      for (i = 0; i < TREE_INT_CST_NUNITS (t); i++)
+       val = iterative_hash_host_wide_int (TREE_INT_CST_ELT (t, i), val);
+      return val;
     case REAL_CST:
       {
        unsigned int val2 = real_hash (TREE_REAL_CST_PTR (t));
@@ -7660,8 +7657,8 @@ build_nonstandard_integer_type (unsigned HOST_WIDE_INT precision,
     fixup_signed_type (itype);
 
   ret = itype;
-  if (host_integerp (TYPE_MAX_VALUE (itype), 1))
-    ret = type_hash_canon (tree_low_cst (TYPE_MAX_VALUE (itype), 1), itype);
+  if (tree_fits_uhwi_p (TYPE_MAX_VALUE (itype)))
+    ret = type_hash_canon (tree_to_uhwi (TYPE_MAX_VALUE (itype)), itype);
   if (precision <= MAX_INT_CACHED_PREC)
     nonstandard_integer_type_cache[precision + unsignedp] = ret;
 
@@ -8497,10 +8494,10 @@ get_narrower (tree op, int *unsignedp_ptr)
       && TREE_CODE (TREE_TYPE (op)) != FIXED_POINT_TYPE
       /* Ensure field is laid out already.  */
       && DECL_SIZE (TREE_OPERAND (op, 1)) != 0
-      && host_integerp (DECL_SIZE (TREE_OPERAND (op, 1)), 1))
+      && tree_fits_uhwi_p (DECL_SIZE (TREE_OPERAND (op, 1))))
     {
       unsigned HOST_WIDE_INT innerprec
-       = tree_low_cst (DECL_SIZE (TREE_OPERAND (op, 1)), 1);
+       = tree_to_uhwi (DECL_SIZE (TREE_OPERAND (op, 1)));
       int unsignedp = (DECL_UNSIGNED (TREE_OPERAND (op, 1))
                       || TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op, 1))));
       tree type = lang_hooks.types.type_for_size (innerprec, unsignedp);
@@ -8535,11 +8532,8 @@ bool
 int_fits_type_p (const_tree c, const_tree type)
 {
   tree type_low_bound, type_high_bound;
-  bool ok_for_low_bound, ok_for_high_bound, unsc;
-  double_int dc, dd;
-
-  dc = tree_to_double_int (c);
-  unsc = TYPE_UNSIGNED (TREE_TYPE (c));
+  bool ok_for_low_bound, ok_for_high_bound;
+  signop sgn_c = TYPE_SIGN (TREE_TYPE (c));
 
 retry:
   type_low_bound = TYPE_MIN_VALUE (type);
@@ -8548,7 +8542,7 @@ retry:
   /* If at least one bound of the type is a constant integer, we can check
      ourselves and maybe make a decision. If no such decision is possible, but
      this type is a subtype, try checking against that.  Otherwise, use
-     double_int_fits_to_tree_p, which checks against the precision.
+     fits_to_tree_p, which checks against the precision.
 
      Compute the status for each possibly constant bound, and return if we see
      one does not match. Use ok_for_xxx_bound for this purpose, assigning -1
@@ -8558,18 +8552,7 @@ retry:
   /* Check if c >= type_low_bound.  */
   if (type_low_bound && TREE_CODE (type_low_bound) == INTEGER_CST)
     {
-      dd = tree_to_double_int (type_low_bound);
-      if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_low_bound)))
-       {
-         int c_neg = (!unsc && dc.is_negative ());
-         int t_neg = (unsc && dd.is_negative ());
-
-         if (c_neg && !t_neg)
-           return false;
-         if ((c_neg || !t_neg) && dc.ult (dd))
-           return false;
-       }
-      else if (dc.cmp (dd, unsc) < 0)
+      if (INT_CST_LT (c, type_low_bound))
        return false;
       ok_for_low_bound = true;
     }
@@ -8579,18 +8562,7 @@ retry:
   /* Check if c <= type_high_bound.  */
   if (type_high_bound && TREE_CODE (type_high_bound) == INTEGER_CST)
     {
-      dd = tree_to_double_int (type_high_bound);
-      if (unsc != TYPE_UNSIGNED (TREE_TYPE (type_high_bound)))
-       {
-         int c_neg = (!unsc && dc.is_negative ());
-         int t_neg = (unsc && dd.is_negative ());
-
-         if (t_neg && !c_neg)
-           return false;
-         if ((t_neg || !c_neg) && dc.ugt (dd))
-           return false;
-       }
-      else if (dc.cmp (dd, unsc) > 0)
+      if (INT_CST_LT (type_high_bound, c))
        return false;
       ok_for_high_bound = true;
     }
@@ -8604,7 +8576,7 @@ retry:
   /* Perform some generic filtering which may allow making a decision
      even if the bounds are not constant.  First, negative integers
      never fit in unsigned types, */
-  if (TYPE_UNSIGNED (type) && !unsc && dc.is_negative ())
+  if (TYPE_UNSIGNED (type) && sgn_c == SIGNED && wi::neg_p (c))
     return false;
 
   /* Second, narrower types always fit in wider ones.  */
@@ -8612,16 +8584,21 @@ retry:
     return true;
 
   /* Third, unsigned integers with top bit set never fit signed types.  */
-  if (! TYPE_UNSIGNED (type) && unsc)
+  if (!TYPE_UNSIGNED (type) && sgn_c == UNSIGNED)
     {
-      int prec = GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (c))) - 1;
-      if (prec < HOST_BITS_PER_WIDE_INT)
+      int prec = GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (c))) - 1;
+      if (prec < TYPE_PRECISION (TREE_TYPE (c)))
        {
-         if (((((unsigned HOST_WIDE_INT) 1) << prec) & dc.low) != 0)
+         /* When a tree_cst is converted to a wide-int, the precision
+            is taken from the type.  However, if the precision of the
+            mode underneath the type is smaller than that, it is
+            possible that the value will not fit.  The test below
+            fails if any bit is set between the sign bit of the
+            underlying mode and the top bit of the type.  */
+         if (wi::ne_p (wi::zext (c, prec - 1), c))
            return false;
-        }
-      else if (((((unsigned HOST_WIDE_INT) 1)
-                << (prec - HOST_BITS_PER_WIDE_INT)) & dc.high) != 0)
+       }
+      else if (wi::neg_p (c))
        return false;
     }
 
@@ -8636,8 +8613,8 @@ retry:
       goto retry;
     }
 
-  /* Or to double_int_fits_to_tree_p, if nothing else.  */
-  return double_int_fits_to_tree_p (type, dc);
+  /* Or to fits_to_tree_p, if nothing else.  */
+  return wi::fits_to_tree_p (c, type);
 }
 
 /* Stores bounds of an integer TYPE in MIN and MAX.  If TYPE has non-constant
@@ -8650,33 +8627,25 @@ get_type_static_bounds (const_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));
+    wi::to_mpz (TYPE_MIN_VALUE (type), min, TYPE_SIGN (type));
   else
     {
       if (TYPE_UNSIGNED (type))
        mpz_set_ui (min, 0);
       else
        {
-         double_int mn;
-         mn = double_int::mask (TYPE_PRECISION (type) - 1);
-         mn = (mn + double_int_one).sext (TYPE_PRECISION (type));
-         mpz_set_double_int (min, mn, false);
+         wide_int mn = wi::min_value (TYPE_PRECISION (type), SIGNED);
+         wi::to_mpz (mn, min, SIGNED);
        }
     }
 
   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));
+    wi::to_mpz (TYPE_MAX_VALUE (type), max, TYPE_SIGN (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);
+      wide_int mn = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
+      wi::to_mpz (mn, max, TYPE_SIGN (type));
     }
 }
 
@@ -9341,6 +9310,18 @@ tree_contains_struct_check_failed (const_tree node,
 }
 
 
+/* Similar to above, except that the check is for the bounds of a TREE_VEC's
+   (dynamically sized) vector.  */
+
+void
+tree_int_cst_elt_check_failed (int idx, int len, const char *file, int line,
+                              const char *function)
+{
+  internal_error
+    ("tree check: accessed elt %d of tree_int_cst with %d elts in %s, at %s:%d",
+     idx + 1, len, function, trim_filename (file), line);
+}
+
 /* Similar to above, except that the check is for the bounds of a TREE_VEC's
    (dynamically sized) vector.  */
 
@@ -9591,13 +9572,11 @@ build_common_tree_nodes (bool signed_char, bool short_double)
 #endif
 
   /* Define a boolean type.  This type only represents boolean values but
-     may be larger than char depending on the value of BOOL_TYPE_SIZE.
-     Front ends which want to override this size (i.e. Java) can redefine
-     boolean_type_node before calling build_common_tree_nodes_2.  */
+     may be larger than char depending on the value of BOOL_TYPE_SIZE.  */
   boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE);
   TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
-  TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
   TYPE_PRECISION (boolean_type_node) = 1;
+  TYPE_MAX_VALUE (boolean_type_node) = build_int_cst (boolean_type_node, 1);
 
   /* Define what type to use for size_t.  */
   if (strcmp (SIZE_TYPE, "unsigned int") == 0)
@@ -10494,8 +10473,7 @@ int_cst_value (const_tree x)
   unsigned HOST_WIDE_INT val = TREE_INT_CST_LOW (x);
 
   /* Make sure the sign-extended value will fit in a HOST_WIDE_INT.  */
-  gcc_assert (TREE_INT_CST_HIGH (x) == 0
-             || TREE_INT_CST_HIGH (x) == -1);
+  gcc_assert (cst_fits_shwi_p (x));
 
   if (bits < HOST_BITS_PER_WIDE_INT)
     {
@@ -10519,12 +10497,16 @@ widest_int_cst_value (const_tree x)
 
 #if HOST_BITS_PER_WIDEST_INT > HOST_BITS_PER_WIDE_INT
   gcc_assert (HOST_BITS_PER_WIDEST_INT >= HOST_BITS_PER_DOUBLE_INT);
-  val |= (((unsigned HOST_WIDEST_INT) TREE_INT_CST_HIGH (x))
-         << HOST_BITS_PER_WIDE_INT);
+  gcc_assert (TREE_INT_CST_NUNITS (x) == 2);
+  
+  if (TREE_INT_CST_NUNITS (x) == 1)
+    val = HOST_WIDE_INT (val);
+  else
+    val |= (((unsigned HOST_WIDEST_INT) TREE_INT_CST_ELT (x, 1))
+           << HOST_BITS_PER_WIDE_INT);
 #else
   /* Make sure the sign-extended value will fit in a HOST_WIDE_INT.  */
-  gcc_assert (TREE_INT_CST_HIGH (x) == 0
-             || TREE_INT_CST_HIGH (x) == -1);
+  gcc_assert (TREE_INT_CST_NUNITS (x) == 1);
 #endif
 
   if (bits < HOST_BITS_PER_WIDEST_INT)
@@ -10609,7 +10591,6 @@ truth_type_for (tree type)
 tree
 upper_bound_in_type (tree outer, tree inner)
 {
-  double_int high;
   unsigned int det = 0;
   unsigned oprec = TYPE_PRECISION (outer);
   unsigned iprec = TYPE_PRECISION (inner);
@@ -10653,21 +10634,8 @@ upper_bound_in_type (tree outer, tree inner)
       gcc_unreachable ();
     }
 
-  /* Compute 2^^prec - 1.  */
-  if (prec <= HOST_BITS_PER_WIDE_INT)
-    {
-      high.high = 0;
-      high.low = ((~(unsigned HOST_WIDE_INT) 0)
-           >> (HOST_BITS_PER_WIDE_INT - prec));
-    }
-  else
-    {
-      high.high = ((~(unsigned HOST_WIDE_INT) 0)
-           >> (HOST_BITS_PER_DOUBLE_INT - prec));
-      high.low = ~(unsigned HOST_WIDE_INT) 0;
-    }
-
-  return double_int_to_tree (outer, high);
+  return wide_int_to_tree (outer, 
+                          wi::mask (prec, false, TYPE_PRECISION (outer)));
 }
 
 /* Returns the smallest value obtainable by casting something in INNER type to
@@ -10676,7 +10644,6 @@ upper_bound_in_type (tree outer, tree inner)
 tree
 lower_bound_in_type (tree outer, tree inner)
 {
-  double_int low;
   unsigned oprec = TYPE_PRECISION (outer);
   unsigned iprec = TYPE_PRECISION (inner);
 
@@ -10687,7 +10654,7 @@ lower_bound_in_type (tree outer, tree inner)
         contains all values of INNER type.  In particular, both INNER
         and OUTER types have zero in common.  */
       || (oprec > iprec && TYPE_UNSIGNED (inner)))
-    low.low = low.high = 0;
+    return build_int_cst (outer, 0);
   else
     {
       /* If we are widening a signed type to another signed type, we
@@ -10695,21 +10662,10 @@ lower_bound_in_type (tree outer, tree inner)
         precision or narrowing to a signed type, we want to obtain
         -2^(oprec-1).  */
       unsigned prec = oprec > iprec ? iprec : oprec;
-
-      if (prec <= HOST_BITS_PER_WIDE_INT)
-       {
-         low.high = ~(unsigned HOST_WIDE_INT) 0;
-         low.low = (~(unsigned HOST_WIDE_INT) 0) << (prec - 1);
-       }
-      else
-       {
-         low.high = ((~(unsigned HOST_WIDE_INT) 0)
-               << (prec - HOST_BITS_PER_WIDE_INT - 1));
-         low.low = 0;
-       }
+      return wide_int_to_tree (outer, 
+                              wi::mask (prec - 1, true,
+                                        TYPE_PRECISION (outer)));
     }
-
-  return double_int_to_tree (outer, low);
 }
 
 /* Return nonzero if two operands that are suitable for PHI nodes are
@@ -10728,42 +10684,12 @@ operand_equal_for_phi_arg_p (const_tree arg0, const_tree arg1)
   return operand_equal_p (arg0, arg1, 0);
 }
 
-/* Returns number of zeros at the end of binary representation of X.
-
-   ??? Use ffs if available?  */
+/* Returns number of zeros at the end of binary representation of X.  */
 
 tree
 num_ending_zeros (const_tree x)
 {
-  unsigned HOST_WIDE_INT fr, nfr;
-  unsigned num, abits;
-  tree type = TREE_TYPE (x);
-
-  if (TREE_INT_CST_LOW (x) == 0)
-    {
-      num = HOST_BITS_PER_WIDE_INT;
-      fr = TREE_INT_CST_HIGH (x);
-    }
-  else
-    {
-      num = 0;
-      fr = TREE_INT_CST_LOW (x);
-    }
-
-  for (abits = HOST_BITS_PER_WIDE_INT / 2; abits; abits /= 2)
-    {
-      nfr = fr >> abits;
-      if (nfr << abits == fr)
-       {
-         num += abits;
-         fr = nfr;
-       }
-    }
-
-  if (num > TYPE_PRECISION (type))
-    num = TYPE_PRECISION (type);
-
-  return build_int_cst_type (type, num);
+  return build_int_cst (TREE_TYPE (x), wi::ctz (x));
 }
 
 
@@ -11923,7 +11849,7 @@ get_binfo_at_offset (tree binfo, HOST_WIDE_INT offset, tree expected_type)
            continue;
 
          pos = int_bit_position (fld);
-         size = tree_low_cst (DECL_SIZE (fld), 1);
+         size = tree_to_uhwi (DECL_SIZE (fld));
          if (pos <= offset && (pos + size) > offset)
            break;
        }
@@ -12257,8 +12183,7 @@ drop_tree_overflow (tree t)
 
   /* For tree codes with a sharing machinery re-build the result.  */
   if (TREE_CODE (t) == INTEGER_CST)
-    return build_int_cst_wide (TREE_TYPE (t),
-                              TREE_INT_CST_LOW (t), TREE_INT_CST_HIGH (t));
+    return wide_int_to_tree (TREE_TYPE (t), t);
 
   /* Otherwise, as all tcc_constants are possibly shared, copy the node
      and drop the flag.  */
@@ -12267,4 +12192,32 @@ drop_tree_overflow (tree t)
   return t;
 }
 
+/* Given a memory reference expression T, return its base address.
+   The base address of a memory reference expression is the main
+   object being referenced.  For instance, the base address for
+   'array[i].fld[j]' is 'array'.  You can think of this as stripping
+   away the offset part from a memory address.
+
+   This function calls handled_component_p to strip away all the inner
+   parts of the memory reference until it reaches the base object.  */
+
+tree
+get_base_address (tree t)
+{
+  while (handled_component_p (t))
+    t = TREE_OPERAND (t, 0);
+
+  if ((TREE_CODE (t) == MEM_REF
+       || TREE_CODE (t) == TARGET_MEM_REF)
+      && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
+    t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
+
+  /* ???  Either the alias oracle or all callers need to properly deal
+     with WITH_SIZE_EXPRs before we can look through those.  */
+  if (TREE_CODE (t) == WITH_SIZE_EXPR)
+    return NULL_TREE;
+
+  return t;
+}
+
 #include "gt-tree.h"