diff mbox

wide-int, gimple

Message ID 6B2EE613-1012-4B93-82A4-B0DEC2639301@comcast.net
State New
Headers show

Commit Message

Mike Stump Nov. 23, 2013, 7:21 p.m. UTC
Richi has asked the we break the wide-int patch so that the individual port and front end maintainers can review their parts without have to go through the entire patch.    This patch covers the gimple code.

Ok?
* gimple.c
	(preprocess_case_label_vec_for_gimple): Use wide-int interfaces.
	* gimple-fold.c
	(get_base_constructor): Use wide-int interfaces.
	(fold_array_ctor_reference): Likewise.
	(fold_nonarray_ctor_reference): Likewise.
	(fold_const_aggregate_ref_1): Likewise.
	(gimple_val_nonnegative_real_p): Likewise.
	(gimple_fold_indirect_ref): Likewise.
	* gimple-pretty-print.c
	(dump_ssaname_info): Use wide-int interfaces.
	* gimple-ssa-strength-reduction.c: Include wide-int-print.h.
	(struct slsr_cand_d): Change index to be widest_int.
	(struct incr_info_d): Change incr to be widest_int.
	(alloc_cand_and_find_basis): Use wide-int interfaces.
	(slsr_process_phi): Likewise.
	(backtrace_base_for_ref): Likewise.  Return a widest_int.
	(restructure_reference): Take a widest_int instead of a double_int.
	(slsr_process_ref): Use wide-int interfaces.
	(create_mul_ssa_cand): Likewise.
	(create_mul_imm_cand): Likewise.
	(create_add_ssa_cand): Likewise.
	(create_add_imm_cand): Take a widest_int instead of a double_int.
	(slsr_process_add): Use wide-int interfaces.
	(slsr_process_cast): Likewise.
	(slsr_process_copy): Likewise.
	(dump_candidate): Likewise.
	(dump_incr_vec): Likewise.
	(replace_ref): Likewise.
	(cand_increment): Likewise.  Return a widest_int.
	(cand_abs_increment): Likewise.
	(replace_mult_candidate): Take a widest_int instead of a double_int.
	(replace_unconditional_candidate): Use wide-int interfaces.
	(incr_vec_index): Take a widest_int instead of a double_int.
	(create_add_on_incoming_edge): Likewise.
	(create_phi_basis): Use wide-int interfaces.
	(replace_conditional_candidate): Likewise.
	(record_increment): Take a widest_int instead of a double_int.
	(record_phi_increments): Use wide-int interfaces.
	(phi_incr_cost): Take a widest_int instead of a double_int.
	(lowest_cost_path): Likewise.
	(total_savings): Likewise.
	(analyze_increments): Use wide-int interfaces.
	(ncd_with_phi): Take a widest_int instead of a double_int.
	(ncd_of_cand_and_phis): Likewise.
	(nearest_common_dominator_for_cands): Likewise.
	(insert_initializers): Use wide-int interfaces.
	(all_phi_incrs_profitable): Likewise.
	(replace_one_candidate): Likewise.
	(replace_profitable_candidates): Likewise.
	* value-prof.c
	(gimple_divmod_fixed_value_transform): Use wide-int interfaces.
	(gimple_stringops_transform): Likewise.
diff mbox

Patch

diff --git a/gcc/gimple.c b/gcc/gimple.c
index 67730bc..25f1296 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -2795,11 +2795,7 @@  preprocess_case_label_vec_for_gimple (vec<tree> labels,
 		  low = CASE_HIGH (labels[i - 1]);
 		  if (!low)
 		    low = CASE_LOW (labels[i - 1]);
-		  if ((TREE_INT_CST_LOW (low) + 1
-		       != TREE_INT_CST_LOW (high))
-		      || (TREE_INT_CST_HIGH (low)
-			  + (TREE_INT_CST_LOW (high) == 0)
-			  != TREE_INT_CST_HIGH (high)))
+		  if (wi::add (low, 1) != high)
 		    break;
 		}
 	      if (i == len)
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 91214bc..2163187 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2724,7 +2724,7 @@  get_base_constructor (tree base, HOST_WIDE_INT *bit_offset,
 	{
 	  if (!tree_fits_shwi_p (TREE_OPERAND (base, 1)))
 	    return NULL_TREE;
-	  *bit_offset += (mem_ref_offset (base).low
+	  *bit_offset += (mem_ref_offset (base).to_short_addr ()
 			  * BITS_PER_UNIT);
 	}
 
@@ -2819,9 +2819,10 @@  fold_array_ctor_reference (tree type, tree ctor,
 {
   unsigned HOST_WIDE_INT cnt;
   tree cfield, cval;
-  double_int low_bound, elt_size;
-  double_int index, max_index;
-  double_int access_index;
+  offset_int low_bound;
+  offset_int elt_size;
+  offset_int index, max_index;
+  offset_int access_index;
   tree domain_type = NULL_TREE, index_type = NULL_TREE;
   HOST_WIDE_INT inner_offset;
 
@@ -2833,31 +2834,29 @@  fold_array_ctor_reference (tree type, tree ctor,
       /* Static constructors for variably sized objects makes no sense.  */
       gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
       index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
-      low_bound = tree_to_double_int (TYPE_MIN_VALUE (domain_type));
+      low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
     }
   else
-    low_bound = double_int_zero;
+    low_bound = 0;
   /* Static constructors for variably sized objects makes no sense.  */
   gcc_assert (TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))))
 	      == INTEGER_CST);
-  elt_size =
-    tree_to_double_int (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));
-
+  elt_size = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ctor))));
 
   /* We can handle only constantly sized accesses that are known to not
      be larger than size of array element.  */
   if (!TYPE_SIZE_UNIT (type)
       || TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
-      || elt_size.slt (tree_to_double_int (TYPE_SIZE_UNIT (type))))
+      || wi::lts_p (elt_size, wi::to_offset (TYPE_SIZE_UNIT (type))))
     return NULL_TREE;
 
   /* Compute the array index we look for.  */
-  access_index = double_int::from_uhwi (offset / BITS_PER_UNIT)
-		 .udiv (elt_size, TRUNC_DIV_EXPR);
+  access_index = wi::udiv_trunc (offset_int (offset / BITS_PER_UNIT),
+				 elt_size);
   access_index += low_bound;
   if (index_type)
-    access_index = access_index.ext (TYPE_PRECISION (index_type),
-				     TYPE_UNSIGNED (index_type));
+    access_index = wi::ext (access_index, TYPE_PRECISION (index_type),
+			    TYPE_SIGN (index_type));
 
   /* And offset within the access.  */
   inner_offset = offset % (elt_size.to_uhwi () * BITS_PER_UNIT);
@@ -2867,9 +2866,10 @@  fold_array_ctor_reference (tree type, tree ctor,
   if (inner_offset + size > elt_size.to_uhwi () * BITS_PER_UNIT)
     return NULL_TREE;
 
-  index = low_bound - double_int_one;
+  index = low_bound - 1;
   if (index_type)
-    index = index.ext (TYPE_PRECISION (index_type), TYPE_UNSIGNED (index_type));
+    index = wi::ext (index, TYPE_PRECISION (index_type),
+		     TYPE_SIGN (index_type));
 
   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
     {
@@ -2879,26 +2879,26 @@  fold_array_ctor_reference (tree type, tree ctor,
       if (cfield)
 	{
 	  if (TREE_CODE (cfield) == INTEGER_CST)
-	    max_index = index = tree_to_double_int (cfield);
+	    max_index = index = wi::to_offset (cfield);
 	  else
 	    {
 	      gcc_assert (TREE_CODE (cfield) == RANGE_EXPR);
-	      index = tree_to_double_int (TREE_OPERAND (cfield, 0));
-	      max_index = tree_to_double_int (TREE_OPERAND (cfield, 1));
+	      index = wi::to_offset (TREE_OPERAND (cfield, 0));
+	      max_index = wi::to_offset (TREE_OPERAND (cfield, 1));
 	    }
 	}
       else
 	{
-	  index += double_int_one;
+	  index += 1;
 	  if (index_type)
-	    index = index.ext (TYPE_PRECISION (index_type),
-			       TYPE_UNSIGNED (index_type));
+	    index = wi::ext (index, TYPE_PRECISION (index_type),
+			     TYPE_SIGN (index_type));
 	  max_index = index;
 	}
 
       /* Do we have match?  */
-      if (access_index.cmp (index, 1) >= 0
-	  && access_index.cmp (max_index, 1) <= 0)
+      if (wi::cmpu (access_index, index) >= 0
+	  && wi::cmpu (access_index, max_index) <= 0)
 	return fold_ctor_reference (type, cval, inner_offset, size,
 				    from_decl);
     }
@@ -2925,10 +2925,9 @@  fold_nonarray_ctor_reference (tree type, tree ctor,
       tree byte_offset = DECL_FIELD_OFFSET (cfield);
       tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
       tree field_size = DECL_SIZE (cfield);
-      double_int bitoffset;
-      double_int byte_offset_cst = tree_to_double_int (byte_offset);
-      double_int bits_per_unit_cst = double_int::from_uhwi (BITS_PER_UNIT);
-      double_int bitoffset_end, access_end;
+      offset_int bitoffset;
+      offset_int byte_offset_cst = wi::to_offset (byte_offset);
+      offset_int bitoffset_end, access_end;
 
       /* Variable sized objects in static constructors makes no sense,
 	 but field_size can be NULL for flexible array members.  */
@@ -2939,30 +2938,29 @@  fold_nonarray_ctor_reference (tree type, tree ctor,
 		      : TREE_CODE (TREE_TYPE (cfield)) == ARRAY_TYPE));
 
       /* Compute bit offset of the field.  */
-      bitoffset = tree_to_double_int (field_offset)
-		  + byte_offset_cst * bits_per_unit_cst;
+      bitoffset = (wi::to_offset (field_offset)
+		   + byte_offset_cst * BITS_PER_UNIT);
       /* Compute bit offset where the field ends.  */
       if (field_size != NULL_TREE)
-	bitoffset_end = bitoffset + tree_to_double_int (field_size);
+	bitoffset_end = bitoffset + wi::to_offset (field_size);
       else
-	bitoffset_end = double_int_zero;
+	bitoffset_end = 0;
 
-      access_end = double_int::from_uhwi (offset)
-		   + double_int::from_uhwi (size);
+      access_end = offset_int (offset) + size;
 
       /* Is there any overlap between [OFFSET, OFFSET+SIZE) and
 	 [BITOFFSET, BITOFFSET_END)?  */
-      if (access_end.cmp (bitoffset, 0) > 0
+      if (wi::cmps (access_end, bitoffset) > 0
 	  && (field_size == NULL_TREE
-	      || double_int::from_uhwi (offset).slt (bitoffset_end)))
+	      || wi::lts_p (offset, bitoffset_end)))
 	{
-	  double_int inner_offset = double_int::from_uhwi (offset) - bitoffset;
+	  offset_int inner_offset = offset_int (offset) - bitoffset;
 	  /* We do have overlap.  Now see if field is large enough to
 	     cover the access.  Give up for accesses spanning multiple
 	     fields.  */
-	  if (access_end.cmp (bitoffset_end, 0) > 0)
+	  if (wi::cmps (access_end, bitoffset_end) > 0)
 	    return NULL_TREE;
-	  if (double_int::from_uhwi (offset).slt (bitoffset))
+	  if (wi::lts_p (offset, bitoffset))
 	    return NULL_TREE;
 	  return fold_ctor_reference (type, cval,
 				      inner_offset.to_uhwi (), size,
@@ -3052,38 +3050,42 @@  fold_const_aggregate_ref_1 (tree t, tree (*valueize) (tree))
 	  && (idx = (*valueize) (TREE_OPERAND (t, 1)))
 	  && TREE_CODE (idx) == INTEGER_CST)
 	{
-	  tree low_bound, unit_size;
-	  double_int doffset;
+	  tree low_bound = array_ref_low_bound (t);
+	  tree unit_size = array_ref_element_size (t);
 
 	  /* If the resulting bit-offset is constant, track it.  */
-	  if ((low_bound = array_ref_low_bound (t),
-	       TREE_CODE (low_bound) == INTEGER_CST)
-	      && (unit_size = array_ref_element_size (t),
-		  tree_fits_uhwi_p (unit_size))
-	      && (doffset = (TREE_INT_CST (idx) - TREE_INT_CST (low_bound))
-			    .sext (TYPE_PRECISION (TREE_TYPE (idx))),
-		  doffset.fits_shwi ()))
+	  if (TREE_CODE (low_bound) == INTEGER_CST
+	      && tree_fits_uhwi_p (unit_size))
 	    {
-	      offset = doffset.to_shwi ();
-	      offset *= tree_to_uhwi (unit_size);
-	      offset *= BITS_PER_UNIT;
-
-	      base = TREE_OPERAND (t, 0);
-	      ctor = get_base_constructor (base, &offset, valueize);
-	      /* Empty constructor.  Always fold to 0.  */
-	      if (ctor == error_mark_node)
-		return build_zero_cst (TREE_TYPE (t));
-	      /* Out of bound array access.  Value is undefined,
-		 but don't fold.  */
-	      if (offset < 0)
-		return NULL_TREE;
-	      /* We can not determine ctor.  */
-	      if (!ctor)
-		return NULL_TREE;
-	      return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
-					  tree_to_uhwi (unit_size)
-					  * BITS_PER_UNIT,
-					  base);
+	      offset_int woffset
+		= wi::sext (wi::to_offset (idx) - wi::to_offset (low_bound),
+			    TYPE_PRECISION (TREE_TYPE (idx)));
+
+	      if (wi::fits_shwi_p (woffset))
+		{
+		  offset = woffset.to_shwi ();
+		  /* TODO: This code seems wrong, multiply then check
+		     to see if it fits.  */
+		  offset *= tree_to_uhwi (unit_size);
+		  offset *= BITS_PER_UNIT;
+
+		  base = TREE_OPERAND (t, 0);
+		  ctor = get_base_constructor (base, &offset, valueize);
+		  /* Empty constructor.  Always fold to 0.  */
+		  if (ctor == error_mark_node)
+		    return build_zero_cst (TREE_TYPE (t));
+		  /* Out of bound array access.  Value is undefined,
+		     but don't fold.  */
+		  if (offset < 0)
+		    return NULL_TREE;
+		  /* We can not determine ctor.  */
+		  if (!ctor)
+		    return NULL_TREE;
+		  return fold_ctor_reference (TREE_TYPE (t), ctor, offset,
+					      tree_to_uhwi (unit_size)
+					      * BITS_PER_UNIT,
+					      base);
+		}
 	    }
 	}
       /* Fallthru.  */
@@ -3319,7 +3321,7 @@  gimple_val_nonnegative_real_p (tree val)
 		  if ((n & 1) == 0)
 		    {
 		      REAL_VALUE_TYPE cint;
-		      real_from_integer (&cint, VOIDmode, n, n < 0 ? -1 : 0, 0);
+		      real_from_integer (&cint, VOIDmode, n, SIGNED);
 		      if (real_identical (&c, &cint))
 			return true;
 		    }
@@ -3432,9 +3434,7 @@  gimple_fold_indirect_ref (tree t)
 	  || DECL_P (TREE_OPERAND (addr, 0)))
 	return fold_build2 (MEM_REF, type,
 			    addr,
-			    build_int_cst_wide (ptype,
-						TREE_INT_CST_LOW (off),
-						TREE_INT_CST_HIGH (off)));
+			    wide_int_to_tree (ptype, off));
     }
 
   /* *(foo *)fooarrptr => (*fooarrptr)[0] */
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 4529e79..e078634 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1754,7 +1754,7 @@  dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
   if (!POINTER_TYPE_P (TREE_TYPE (node))
       && SSA_NAME_RANGE_INFO (node))
     {
-      double_int min, max, nonzero_bits;
+      widest_int min, max, nonzero_bits;
       value_range_type range_type = get_range_info (node, &min, &max);
 
       if (range_type == VR_VARYING)
@@ -1763,22 +1763,18 @@  dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
 	{
 	  pp_printf (buffer, "# RANGE ");
 	  pp_printf (buffer, "%s[", range_type == VR_RANGE ? "" : "~");
-	  pp_double_int (buffer, min, TYPE_UNSIGNED (TREE_TYPE (node)));
+	  pp_wide_int (buffer, min, TYPE_SIGN (TREE_TYPE (node)));
 	  pp_printf (buffer, ", ");
-	  pp_double_int (buffer, max, TYPE_UNSIGNED (TREE_TYPE (node)));
+	  pp_wide_int (buffer, max, TYPE_SIGN (TREE_TYPE (node)));
 	  pp_printf (buffer, "]");
 	}
       nonzero_bits = get_nonzero_bits (node);
-      if (nonzero_bits != double_int_minus_one
+      if (nonzero_bits != -1
 	  && (nonzero_bits
-	      != double_int::mask (TYPE_PRECISION (TREE_TYPE (node)))))
+	      != wi::mask <widest_int> (TYPE_PRECISION (TREE_TYPE (node)), false)))
 	{
 	  pp_string (buffer, " NONZERO ");
-	  sprintf (pp_buffer (buffer)->digit_buffer,
-		   HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-		   (unsigned HOST_WIDE_INT) nonzero_bits.high,
-		   nonzero_bits.low);
-	  pp_string (buffer, pp_buffer (buffer)->digit_buffer);
+	  pp_wide_int (buffer, nonzero_bits, UNSIGNED);
 	}
       newline_and_indent (buffer, spc);
     }
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index 3ac9e4d..b9fc936 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -58,6 +58,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "hash-table.h"
 #include "tree-ssa-address.h"
+#include "wide-int-print.h"
 
 /* Information about a strength reduction candidate.  Each statement
    in the candidate table represents an expression of one of the
@@ -239,7 +240,7 @@  struct slsr_cand_d
   tree stride;
 
   /* The index constant i.  */
-  double_int index;
+  widest_int index;
 
   /* The type of the candidate.  This is normally the type of base_expr,
      but casts may have occurred when combining feeding instructions.
@@ -314,7 +315,7 @@  typedef const struct cand_chain_d *const_cand_chain_t;
 struct incr_info_d
 {
   /* The increment that relates a candidate to its basis.  */
-  double_int incr;
+  widest_int incr;
 
   /* How many times the increment occurs in the candidate tree.  */
   unsigned count;
@@ -563,7 +564,7 @@  record_potential_basis (slsr_cand_t c)
 
 static slsr_cand_t
 alloc_cand_and_find_basis (enum cand_kind kind, gimple gs, tree base, 
-			   double_int index, tree stride, tree ctype,
+			   const widest_int &index, tree stride, tree ctype,
 			   unsigned savings)
 {
   slsr_cand_t c = (slsr_cand_t) obstack_alloc (&cand_obstack,
@@ -754,8 +755,8 @@  slsr_process_phi (gimple phi, bool speed)
      CAND_PHI.  */
   base_type = TREE_TYPE (arg0_base);
 
-  c = alloc_cand_and_find_basis (CAND_PHI, phi, arg0_base, double_int_zero,
-				 integer_one_node, base_type, savings);
+  c = alloc_cand_and_find_basis (CAND_PHI, phi, arg0_base,
+				 0, integer_one_node, base_type, savings);
 
   /* Add the candidate to the statement-candidate mapping.  */
   add_cand_for_stmt (phi, c);
@@ -772,7 +773,7 @@  slsr_process_phi (gimple phi, bool speed)
    int (i * S).
    Otherwise, just return double int zero.  */
 
-static double_int
+static widest_int
 backtrace_base_for_ref (tree *pbase)
 {
   tree base_in = *pbase;
@@ -788,19 +789,19 @@  backtrace_base_for_ref (tree *pbase)
     base_in = get_unwidened (base_in, NULL_TREE);
 
   if (TREE_CODE (base_in) != SSA_NAME)
-    return tree_to_double_int (integer_zero_node);
+    return 0;
 
   base_cand = base_cand_from_table (base_in);
 
   while (base_cand && base_cand->kind != CAND_PHI)
     {
       if (base_cand->kind == CAND_ADD
-	  && base_cand->index.is_one ()
+	  && base_cand->index == 1
 	  && TREE_CODE (base_cand->stride) == INTEGER_CST)
 	{
 	  /* X = B + (1 * S), S is integer constant.  */
 	  *pbase = base_cand->base_expr;
-	  return tree_to_double_int (base_cand->stride);
+	  return wi::to_widest (base_cand->stride);
 	}
       else if (base_cand->kind == CAND_ADD
 	       && TREE_CODE (base_cand->stride) == INTEGER_CST
@@ -817,7 +818,7 @@  backtrace_base_for_ref (tree *pbase)
 	base_cand = NULL;
     }
 
-  return tree_to_double_int (integer_zero_node);
+  return 0;
 }
 
 /* Look for the following pattern:
@@ -847,38 +848,35 @@  backtrace_base_for_ref (tree *pbase)
     *PINDEX:   C1 + (C2 * C3) + C4 + (C5 * C3)  */
 
 static bool
-restructure_reference (tree *pbase, tree *poffset, double_int *pindex,
+restructure_reference (tree *pbase, tree *poffset, widest_int *pindex,
 		       tree *ptype)
 {
   tree base = *pbase, offset = *poffset;
-  double_int index = *pindex;
-  double_int bpu = double_int::from_uhwi (BITS_PER_UNIT);
-  tree mult_op0, mult_op1, t1, t2, type;
-  double_int c1, c2, c3, c4, c5;
+  widest_int index = *pindex;
+  tree mult_op0, t1, t2, type;
+  widest_int c1, c2, c3, c4, c5;
 
   if (!base
       || !offset
       || TREE_CODE (base) != MEM_REF
       || TREE_CODE (offset) != MULT_EXPR
       || TREE_CODE (TREE_OPERAND (offset, 1)) != INTEGER_CST
-      || !index.umod (bpu, FLOOR_MOD_EXPR).is_zero ())
+      || wi::umod_floor (index, BITS_PER_UNIT) != 0)
     return false;
 
   t1 = TREE_OPERAND (base, 0);
-  c1 = mem_ref_offset (base);
+  c1 = widest_int::from (mem_ref_offset (base), SIGNED);
   type = TREE_TYPE (TREE_OPERAND (base, 1));
 
   mult_op0 = TREE_OPERAND (offset, 0);
-  mult_op1 = TREE_OPERAND (offset, 1);
-
-  c3 = tree_to_double_int (mult_op1);
+  c3 = wi::to_widest (TREE_OPERAND (offset, 1));
 
   if (TREE_CODE (mult_op0) == PLUS_EXPR)
 
     if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
       {
 	t2 = TREE_OPERAND (mult_op0, 0);
-	c2 = tree_to_double_int (TREE_OPERAND (mult_op0, 1));
+	c2 = wi::to_widest (TREE_OPERAND (mult_op0, 1));
       }
     else
       return false;
@@ -888,7 +886,7 @@  restructure_reference (tree *pbase, tree *poffset, double_int *pindex,
     if (TREE_CODE (TREE_OPERAND (mult_op0, 1)) == INTEGER_CST)
       {
 	t2 = TREE_OPERAND (mult_op0, 0);
-	c2 = -tree_to_double_int (TREE_OPERAND (mult_op0, 1));
+	c2 = -wi::to_widest (TREE_OPERAND (mult_op0, 1));
       }
     else
       return false;
@@ -896,15 +894,15 @@  restructure_reference (tree *pbase, tree *poffset, double_int *pindex,
   else
     {
       t2 = mult_op0;
-      c2 = double_int_zero;
+      c2 = 0;
     }
 
-  c4 = index.udiv (bpu, FLOOR_DIV_EXPR);
+  c4 = wi::udiv_floor (index, BITS_PER_UNIT);
   c5 = backtrace_base_for_ref (&t2);
 
   *pbase = t1;
   *poffset = fold_build2 (MULT_EXPR, sizetype, fold_convert (sizetype, t2),
-			  double_int_to_tree (sizetype, c3));
+			  wide_int_to_tree (sizetype, c3));
   *pindex = c1 + c2 * c3 + c4 + c5 * c3;
   *ptype = type;
 
@@ -921,7 +919,6 @@  slsr_process_ref (gimple gs)
   HOST_WIDE_INT bitsize, bitpos;
   enum machine_mode mode;
   int unsignedp, volatilep;
-  double_int index;
   slsr_cand_t c;
 
   if (gimple_vdef (gs))
@@ -937,7 +934,7 @@  slsr_process_ref (gimple gs)
 
   base = get_inner_reference (ref_expr, &bitsize, &bitpos, &offset, &mode,
 			      &unsignedp, &volatilep, false);
-  index = double_int::from_uhwi (bitpos);
+  widest_int index = bitpos;
 
   if (!restructure_reference (&base, &offset, &index, &type))
     return;
@@ -958,7 +955,7 @@  static slsr_cand_t
 create_mul_ssa_cand (gimple gs, tree base_in, tree stride_in, bool speed)
 {
   tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
-  double_int index;
+  widest_int index;
   unsigned savings = 0;
   slsr_cand_t c;
   slsr_cand_t base_cand = base_cand_from_table (base_in);
@@ -990,7 +987,7 @@  create_mul_ssa_cand (gimple gs, tree base_in, tree stride_in, bool speed)
 	     ============================
 	     X = B + ((i' * S) * Z)  */
 	  base = base_cand->base_expr;
-	  index = base_cand->index * tree_to_double_int (base_cand->stride);
+	  index = base_cand->index * wi::to_widest (base_cand->stride);
 	  stride = stride_in;
 	  ctype = base_cand->cand_type;
 	  if (has_single_use (base_in))
@@ -1009,7 +1006,7 @@  create_mul_ssa_cand (gimple gs, tree base_in, tree stride_in, bool speed)
       /* No interpretations had anything useful to propagate, so
 	 produce X = (Y + 0) * Z.  */
       base = base_in;
-      index = double_int_zero;
+      index = 0;
       stride = stride_in;
       ctype = TREE_TYPE (base_in);
     }
@@ -1028,7 +1025,7 @@  static slsr_cand_t
 create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
 {
   tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
-  double_int index, temp;
+  widest_int index, temp;
   unsigned savings = 0;
   slsr_cand_t c;
   slsr_cand_t base_cand = base_cand_from_table (base_in);
@@ -1046,9 +1043,8 @@  create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
 	     X = (B + i') * (S * c)  */
 	  base = base_cand->base_expr;
 	  index = base_cand->index;
-	  temp = tree_to_double_int (base_cand->stride)
-		 * tree_to_double_int (stride_in);
-	  stride = double_int_to_tree (TREE_TYPE (stride_in), temp);
+	  temp = wi::to_widest (base_cand->stride) * wi::to_widest (stride_in);
+	  stride = wide_int_to_tree (TREE_TYPE (stride_in), temp);
 	  ctype = base_cand->cand_type;
 	  if (has_single_use (base_in))
 	    savings = (base_cand->dead_savings 
@@ -1069,7 +1065,7 @@  create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
 		       + stmt_cost (base_cand->cand_stmt, speed));
 	}
       else if (base_cand->kind == CAND_ADD
-	       && base_cand->index.is_one ()
+	       && base_cand->index == 1
 	       && TREE_CODE (base_cand->stride) == INTEGER_CST)
 	{
 	  /* Y = B + (1 * S), S constant
@@ -1077,7 +1073,7 @@  create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
 	     ===========================
 	     X = (B + S) * c  */
 	  base = base_cand->base_expr;
-	  index = tree_to_double_int (base_cand->stride);
+	  index = wi::to_widest (base_cand->stride);
 	  stride = stride_in;
 	  ctype = base_cand->cand_type;
 	  if (has_single_use (base_in))
@@ -1096,7 +1092,7 @@  create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
       /* No interpretations had anything useful to propagate, so
 	 produce X = (Y + 0) * c.  */
       base = base_in;
-      index = double_int_zero;
+      index = 0;
       stride = stride_in;
       ctype = TREE_TYPE (base_in);
     }
@@ -1159,7 +1155,7 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
 		     bool subtract_p, bool speed)
 {
   tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL;
-  double_int index;
+  widest_int index;
   unsigned savings = 0;
   slsr_cand_t c;
   slsr_cand_t base_cand = base_cand_from_table (base_in);
@@ -1170,7 +1166,7 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
   while (addend_cand && !base && addend_cand->kind != CAND_PHI)
     {
       if (addend_cand->kind == CAND_MULT
-	  && addend_cand->index.is_zero ()
+	  && addend_cand->index == 0
 	  && TREE_CODE (addend_cand->stride) == INTEGER_CST)
 	{
 	  /* Z = (B + 0) * S, S constant
@@ -1178,7 +1174,7 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
 	     ===========================
 	     X = Y + ((+/-1 * S) * B)  */
 	  base = base_in;
-	  index = tree_to_double_int (addend_cand->stride);
+	  index = wi::to_widest (addend_cand->stride);
 	  if (subtract_p)
 	    index = -index;
 	  stride = addend_cand->base_expr;
@@ -1197,7 +1193,7 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
   while (base_cand && !base && base_cand->kind != CAND_PHI)
     {
       if (base_cand->kind == CAND_ADD
-	  && (base_cand->index.is_zero ()
+	  && (base_cand->index == 0
 	      || operand_equal_p (base_cand->stride,
 				  integer_zero_node, 0)))
 	{
@@ -1206,7 +1202,7 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
 	     ============================
 	     X = B + (+/-1 * Z)  */
 	  base = base_cand->base_expr;
-	  index = subtract_p ? double_int_minus_one : double_int_one;
+	  index = subtract_p ? -1 : 1;
 	  stride = addend_in;
 	  ctype = base_cand->cand_type;
 	  if (has_single_use (base_in))
@@ -1220,7 +1216,7 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
 	  while (subtrahend_cand && !base && subtrahend_cand->kind != CAND_PHI)
 	    {
 	      if (subtrahend_cand->kind == CAND_MULT
-		  && subtrahend_cand->index.is_zero ()
+		  && subtrahend_cand->index == 0
 		  && TREE_CODE (subtrahend_cand->stride) == INTEGER_CST)
 		{
 		  /* Z = (B + 0) * S, S constant
@@ -1228,7 +1224,7 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
 		     ===========================
 		     Value:  X = Y + ((-1 * S) * B)  */
 		  base = base_in;
-		  index = tree_to_double_int (subtrahend_cand->stride);
+		  index = wi::to_widest (subtrahend_cand->stride);
 		  index = -index;
 		  stride = subtrahend_cand->base_expr;
 		  ctype = TREE_TYPE (base_in);
@@ -1255,7 +1251,7 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
       /* No interpretations had anything useful to propagate, so
 	 produce X = Y + (1 * Z).  */
       base = base_in;
-      index = subtract_p ? double_int_minus_one : double_int_one;
+      index = subtract_p ? -1 : 1;
       stride = addend_in;
       ctype = TREE_TYPE (base_in);
     }
@@ -1270,22 +1266,23 @@  create_add_ssa_cand (gimple gs, tree base_in, tree addend_in,
    about BASE_IN into the new candidate.  Return the new candidate.  */
 
 static slsr_cand_t
-create_add_imm_cand (gimple gs, tree base_in, double_int index_in, bool speed)
+create_add_imm_cand (gimple gs, tree base_in, const widest_int &index_in,
+		     bool speed)
 {
   enum cand_kind kind = CAND_ADD;
   tree base = NULL_TREE, stride = NULL_TREE, ctype = NULL_TREE;
-  double_int index, multiple;
+  widest_int index, multiple;
   unsigned savings = 0;
   slsr_cand_t c;
   slsr_cand_t base_cand = base_cand_from_table (base_in);
 
   while (base_cand && !base && base_cand->kind != CAND_PHI)
     {
-      bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (base_cand->stride));
+      signop sign = TYPE_SIGN (TREE_TYPE (base_cand->stride));
 
       if (TREE_CODE (base_cand->stride) == INTEGER_CST
-	  && index_in.multiple_of (tree_to_double_int (base_cand->stride),
-				   unsigned_p, &multiple))
+	  && wi::multiple_of_p (index_in, wi::to_widest (base_cand->stride),
+				sign, &multiple))
 	{
 	  /* Y = (B + i') * S, S constant, c = kS for some integer k
 	     X = Y + c
@@ -1370,10 +1367,8 @@  slsr_process_add (gimple gs, tree rhs1, tree rhs2, bool speed)
     }
   else
     {
-      double_int index;
-
       /* Record an interpretation for the add-immediate.  */
-      index = tree_to_double_int (rhs2);
+      widest_int index = wi::to_widest (rhs2);
       if (subtract_p)
 	index = -index;
 
@@ -1521,10 +1516,10 @@  slsr_process_cast (gimple gs, tree rhs1, bool speed)
 	 The first of these is somewhat arbitrary, but the choice of
 	 1 for the stride simplifies the logic for propagating casts
 	 into their uses.  */
-      c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, double_int_zero,
-				     integer_one_node, ctype, 0);
-      c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, double_int_zero,
-				      integer_one_node, ctype, 0);
+      c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1,
+				     0, integer_one_node, ctype, 0);
+      c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1,
+				      0, integer_one_node, ctype, 0);
       c->next_interp = c2->cand_num;
     }
 
@@ -1578,10 +1573,10 @@  slsr_process_copy (gimple gs, tree rhs1, bool speed)
 	 The first of these is somewhat arbitrary, but the choice of
 	 1 for the stride simplifies the logic for propagating casts
 	 into their uses.  */
-      c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1, double_int_zero,
-				     integer_one_node, TREE_TYPE (rhs1), 0);
-      c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1, double_int_zero,
-				      integer_one_node, TREE_TYPE (rhs1), 0);
+      c = alloc_cand_and_find_basis (CAND_ADD, gs, rhs1,
+				     0, integer_one_node, TREE_TYPE (rhs1), 0);
+      c2 = alloc_cand_and_find_basis (CAND_MULT, gs, rhs1,
+				      0, integer_one_node, TREE_TYPE (rhs1), 0);
       c->next_interp = c2->cand_num;
     }
 
@@ -1698,7 +1693,7 @@  dump_candidate (slsr_cand_t c)
       fputs ("     MULT : (", dump_file);
       print_generic_expr (dump_file, c->base_expr, 0);
       fputs (" + ", dump_file);
-      dump_double_int (dump_file, c->index, false);
+      print_decs (c->index, dump_file);
       fputs (") * ", dump_file);
       print_generic_expr (dump_file, c->stride, 0);
       fputs (" : ", dump_file);
@@ -1707,7 +1702,7 @@  dump_candidate (slsr_cand_t c)
       fputs ("     ADD  : ", dump_file);
       print_generic_expr (dump_file, c->base_expr, 0);
       fputs (" + (", dump_file);
-      dump_double_int (dump_file, c->index, false);
+      print_decs (c->index, dump_file);
       fputs (" * ", dump_file);
       print_generic_expr (dump_file, c->stride, 0);
       fputs (") : ", dump_file);
@@ -1718,7 +1713,7 @@  dump_candidate (slsr_cand_t c)
       fputs (" + (", dump_file);
       print_generic_expr (dump_file, c->stride, 0);
       fputs (") + ", dump_file);
-      dump_double_int (dump_file, c->index, false);
+      print_decs (c->index, dump_file);
       fputs (" : ", dump_file);
       break;
     case CAND_PHI:
@@ -1797,7 +1792,7 @@  dump_incr_vec (void)
       for (i = 0; i < incr_vec_len; i++)
 	{
 	  fprintf (dump_file, "%3d  increment:   ", i);
-	  dump_double_int (dump_file, incr_vec[i].incr, false);
+	  print_decs (incr_vec[i].incr, dump_file);
 	  fprintf (dump_file, "\n     count:       %d", incr_vec[i].count);
 	  fprintf (dump_file, "\n     cost:        %d", incr_vec[i].cost);
 	  fputs ("\n     initializer: ", dump_file);
@@ -1828,7 +1823,7 @@  replace_ref (tree *expr, slsr_cand_t c)
   add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr),
 			  c->base_expr, c->stride);
   mem_ref = fold_build2 (MEM_REF, acc_type, add_expr,
-			 double_int_to_tree (c->cand_type, c->index));
+			 wide_int_to_tree (c->cand_type, c->index));
 
   /* Gimplify the base addressing expression for the new MEM_REF tree.  */
   gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
@@ -1883,7 +1878,7 @@  phi_dependent_cand_p (slsr_cand_t c)
 /* Calculate the increment required for candidate C relative to 
    its basis.  */
 
-static double_int
+static widest_int
 cand_increment (slsr_cand_t c)
 {
   slsr_cand_t basis;
@@ -1906,12 +1901,12 @@  cand_increment (slsr_cand_t c)
    for this candidate, return the absolute value of that increment
    instead.  */
 
-static inline double_int
+static inline widest_int
 cand_abs_increment (slsr_cand_t c)
 {
-  double_int increment = cand_increment (c);
+  widest_int increment = cand_increment (c);
 
-  if (!address_arithmetic_p && increment.is_negative ())
+  if (!address_arithmetic_p && wi::neg_p (increment))
     increment = -increment;
 
   return increment;
@@ -1930,7 +1925,7 @@  cand_already_replaced (slsr_cand_t c)
    replace_conditional_candidate.  */
 
 static void
-replace_mult_candidate (slsr_cand_t c, tree basis_name, double_int bump)
+replace_mult_candidate (slsr_cand_t c, tree basis_name, widest_int bump)
 {
   tree target_type = TREE_TYPE (gimple_assign_lhs (c->cand_stmt));
   enum tree_code cand_code = gimple_assign_rhs_code (c->cand_stmt);
@@ -1940,7 +1935,7 @@  replace_mult_candidate (slsr_cand_t c, tree basis_name, double_int bump)
      in this case.  This does not affect siblings or dependents
      of C.  Restriction to signed HWI is conservative for unsigned
      types but allows for safe negation without twisted logic.  */
-  if (bump.fits_shwi ()
+  if (wi::fits_shwi_p (bump)
       && bump.to_shwi () != HOST_WIDE_INT_MIN
       /* It is not useful to replace casts, copies, or adds of
 	 an SSA name and a constant.  */
@@ -1958,13 +1953,13 @@  replace_mult_candidate (slsr_cand_t c, tree basis_name, double_int bump)
 	 types, introduce a cast.  */
       if (!useless_type_conversion_p (target_type, TREE_TYPE (basis_name)))
 	basis_name = introduce_cast_before_cand (c, target_type, basis_name);
-      if (bump.is_negative ())
+      if (wi::neg_p (bump))
 	{
 	  code = MINUS_EXPR;
 	  bump = -bump;
 	}
 
-      bump_tree = double_int_to_tree (target_type, bump);
+      bump_tree = wide_int_to_tree (target_type, bump);
 
       if (dump_file && (dump_flags & TDF_DETAILS))
 	{
@@ -1972,7 +1967,7 @@  replace_mult_candidate (slsr_cand_t c, tree basis_name, double_int bump)
 	  print_gimple_stmt (dump_file, c->cand_stmt, 0, 0);
 	}
 
-      if (bump.is_zero ())
+      if (bump == 0)
 	{
 	  tree lhs = gimple_assign_lhs (c->cand_stmt);
 	  gimple copy_stmt = gimple_build_assign (lhs, basis_name);
@@ -2033,14 +2028,12 @@  static void
 replace_unconditional_candidate (slsr_cand_t c)
 {
   slsr_cand_t basis;
-  double_int stride, bump;
 
   if (cand_already_replaced (c))
     return;
 
   basis = lookup_cand (c->basis);
-  stride = tree_to_double_int (c->stride);
-  bump = cand_increment (c) * stride;
+  widest_int bump = cand_increment (c) * wi::to_widest (c->stride);
 
   replace_mult_candidate (c, gimple_assign_lhs (basis->cand_stmt), bump);
 }
@@ -2050,7 +2043,7 @@  replace_unconditional_candidate (slsr_cand_t c)
    MAX_INCR_VEC_LEN increments have been found.  */
 
 static inline int
-incr_vec_index (double_int increment)
+incr_vec_index (widest_int increment)
 {
   unsigned i;
   
@@ -2070,7 +2063,7 @@  incr_vec_index (double_int increment)
 
 static tree
 create_add_on_incoming_edge (slsr_cand_t c, tree basis_name,
-			     double_int increment, edge e, location_t loc,
+			     widest_int increment, edge e, location_t loc,
 			     bool known_stride)
 {
   basic_block insert_bb;
@@ -2081,7 +2074,7 @@  create_add_on_incoming_edge (slsr_cand_t c, tree basis_name,
   /* If the add candidate along this incoming edge has the same
      index as C's hidden basis, the hidden basis represents this
      edge correctly.  */
-  if (increment.is_zero ())
+  if (increment == 0)
     return basis_name;
 
   basis_type = TREE_TYPE (basis_name);
@@ -2091,21 +2084,21 @@  create_add_on_incoming_edge (slsr_cand_t c, tree basis_name,
     {
       tree bump_tree;
       enum tree_code code = PLUS_EXPR;
-      double_int bump = increment * tree_to_double_int (c->stride);
-      if (bump.is_negative ())
+      widest_int bump = increment * wi::to_widest (c->stride);
+      if (wi::neg_p (bump))
 	{
 	  code = MINUS_EXPR;
 	  bump = -bump;
 	}
 
-      bump_tree = double_int_to_tree (basis_type, bump);
+      bump_tree = wide_int_to_tree (basis_type, bump);
       new_stmt = gimple_build_assign_with_ops (code, lhs, basis_name,
 					       bump_tree);
     }
   else
     {
       int i;
-      bool negate_incr = (!address_arithmetic_p && increment.is_negative ());
+      bool negate_incr = (!address_arithmetic_p && wi::neg_p (increment));
       i = incr_vec_index (negate_incr ? -increment : increment);
       gcc_assert (i >= 0);
 
@@ -2115,10 +2108,10 @@  create_add_on_incoming_edge (slsr_cand_t c, tree basis_name,
 	  new_stmt = gimple_build_assign_with_ops (code, lhs, basis_name,
 						   incr_vec[i].initializer);
 	}
-      else if (increment.is_one ())
+      else if (increment == 1)
 	new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, lhs, basis_name,
 						 c->stride);
-      else if (increment.is_minus_one ())
+      else if (increment == -1)
 	new_stmt = gimple_build_assign_with_ops (MINUS_EXPR, lhs, basis_name,
 						 c->stride);
       else
@@ -2179,11 +2172,11 @@  create_phi_basis (slsr_cand_t c, gimple from_phi, tree basis_name,
       /* If the phi argument is the base name of the CAND_PHI, then
 	 this incoming arc should use the hidden basis.  */
       if (operand_equal_p (arg, phi_cand->base_expr, 0))
-	if (basis->index.is_zero ())
+	if (basis->index == 0)
 	  feeding_def = gimple_assign_lhs (basis->cand_stmt);
 	else
 	  {
-	    double_int incr = -basis->index;
+	    widest_int incr = -basis->index;
 	    feeding_def = create_add_on_incoming_edge (c, basis_name, incr,
 						       e, loc, known_stride);
 	  }
@@ -2200,7 +2193,7 @@  create_phi_basis (slsr_cand_t c, gimple from_phi, tree basis_name,
 	  else
 	    {
 	      slsr_cand_t arg_cand = base_cand_from_table (arg);
-	      double_int diff = arg_cand->index - basis->index;
+	      widest_int diff = arg_cand->index - basis->index;
 	      feeding_def = create_add_on_incoming_edge (c, basis_name, diff,
 							 e, loc, known_stride);
 	    }
@@ -2246,7 +2239,6 @@  replace_conditional_candidate (slsr_cand_t c)
   tree basis_name, name;
   slsr_cand_t basis;
   location_t loc;
-  double_int stride, bump;
 
   /* Look up the LHS SSA name from C's basis.  This will be the 
      RHS1 of the adds we will introduce to create new phi arguments.  */
@@ -2259,8 +2251,7 @@  replace_conditional_candidate (slsr_cand_t c)
   name = create_phi_basis (c, lookup_cand (c->def_phi)->cand_stmt,
 			   basis_name, loc, KNOWN_STRIDE);
   /* Replace C with an add of the new basis phi and a constant.  */
-  stride = tree_to_double_int (c->stride);
-  bump = c->index * stride;
+  widest_int bump = c->index * wi::to_widest (c->stride);
 
   replace_mult_candidate (c, name, bump);
 }
@@ -2392,14 +2383,14 @@  count_candidates (slsr_cand_t c)
    candidates with the same increment, also record T_0 for subsequent use.  */
 
 static void
-record_increment (slsr_cand_t c, double_int increment, bool is_phi_adjust)
+record_increment (slsr_cand_t c, widest_int increment, bool is_phi_adjust)
 {
   bool found = false;
   unsigned i;
 
   /* Treat increments that differ only in sign as identical so as to
      share initializers, unless we are generating pointer arithmetic.  */
-  if (!address_arithmetic_p && increment.is_negative ())
+  if (!address_arithmetic_p && wi::neg_p (increment))
     increment = -increment;
 
   for (i = 0; i < incr_vec_len; i++)
@@ -2443,8 +2434,8 @@  record_increment (slsr_cand_t c, double_int increment, bool is_phi_adjust)
       if (c->kind == CAND_ADD
 	  && !is_phi_adjust
 	  && c->index == increment
-	  && (increment.sgt (double_int_one)
-	      || increment.slt (double_int_minus_one))
+	  && (wi::gts_p (increment, 1)
+	      || wi::lts_p (increment, -1))
 	  && (gimple_assign_rhs_code (c->cand_stmt) == PLUS_EXPR
 	      || gimple_assign_rhs_code (c->cand_stmt) == POINTER_PLUS_EXPR))
 	{
@@ -2502,7 +2493,7 @@  record_phi_increments (slsr_cand_t basis, gimple phi)
 	  else
 	    {
 	      slsr_cand_t arg_cand = base_cand_from_table (arg);
-	      double_int diff = arg_cand->index - basis->index;
+	      widest_int diff = arg_cand->index - basis->index;
 	      record_increment (arg_cand, diff, PHI_ADJUST);
 	    }
 	}
@@ -2553,7 +2544,7 @@  record_increments (slsr_cand_t c)
    uses.  */
 
 static int
-phi_incr_cost (slsr_cand_t c, double_int incr, gimple phi, int *savings)
+phi_incr_cost (slsr_cand_t c, const widest_int &incr, gimple phi, int *savings)
 {
   unsigned i;
   int cost = 0;
@@ -2578,7 +2569,7 @@  phi_incr_cost (slsr_cand_t c, double_int incr, gimple phi, int *savings)
 	  else
 	    {
 	      slsr_cand_t arg_cand = base_cand_from_table (arg);
-	      double_int diff = arg_cand->index - basis->index;
+	      widest_int diff = arg_cand->index - basis->index;
 
 	      if (incr == diff)
 		{
@@ -2643,10 +2634,10 @@  optimize_cands_for_speed_p (slsr_cand_t c)
 
 static int
 lowest_cost_path (int cost_in, int repl_savings, slsr_cand_t c,
-		  double_int incr, bool count_phis)
+		  const widest_int &incr, bool count_phis)
 {
   int local_cost, sib_cost, savings = 0;
-  double_int cand_incr = cand_abs_increment (c);
+  widest_int cand_incr = cand_abs_increment (c);
 
   if (cand_already_replaced (c))
     local_cost = cost_in;
@@ -2689,11 +2680,11 @@  lowest_cost_path (int cost_in, int repl_savings, slsr_cand_t c,
    would go dead.  */
 
 static int
-total_savings (int repl_savings, slsr_cand_t c, double_int incr,
+total_savings (int repl_savings, slsr_cand_t c, const widest_int &incr,
 	       bool count_phis)
 {
   int savings = 0;
-  double_int cand_incr = cand_abs_increment (c);
+  widest_int cand_incr = cand_abs_increment (c);
 
   if (incr == cand_incr && !cand_already_replaced (c))
     savings += repl_savings + c->dead_savings;
@@ -2743,7 +2734,7 @@  analyze_increments (slsr_cand_t first_dep, enum machine_mode mode, bool speed)
       /* If somehow this increment is bigger than a HWI, we won't
 	 be optimizing candidates that use it.  And if the increment
 	 has a count of zero, nothing will be done with it.  */
-      if (!incr_vec[i].incr.fits_shwi () || !incr_vec[i].count)
+      if (!wi::fits_shwi_p (incr_vec[i].incr) || !incr_vec[i].count)
 	incr_vec[i].cost = COST_INFINITE;
 
       /* Increments of 0, 1, and -1 are always profitable to replace,
@@ -2897,7 +2888,7 @@  ncd_for_two_cands (basic_block bb1, basic_block bb2,
    candidates, return the earliest candidate in the block in *WHERE.  */
 
 static basic_block
-ncd_with_phi (slsr_cand_t c, double_int incr, gimple phi,
+ncd_with_phi (slsr_cand_t c, const widest_int &incr, gimple phi,
 	      basic_block ncd, slsr_cand_t *where)
 {
   unsigned i;
@@ -2917,7 +2908,7 @@  ncd_with_phi (slsr_cand_t c, double_int incr, gimple phi,
 	  else 
 	    {
 	      slsr_cand_t arg_cand = base_cand_from_table (arg);
-	      double_int diff = arg_cand->index - basis->index;
+	      widest_int diff = arg_cand->index - basis->index;
 
 	      if ((incr == diff) || (!address_arithmetic_p && incr == -diff))
 		ncd = ncd_for_two_cands (ncd, gimple_bb (arg_cand->cand_stmt),
@@ -2936,7 +2927,7 @@  ncd_with_phi (slsr_cand_t c, double_int incr, gimple phi,
    return the earliest candidate in the block in *WHERE.  */
 
 static basic_block
-ncd_of_cand_and_phis (slsr_cand_t c, double_int incr, slsr_cand_t *where)
+ncd_of_cand_and_phis (slsr_cand_t c, const widest_int &incr, slsr_cand_t *where)
 {
   basic_block ncd = NULL;
 
@@ -2961,7 +2952,7 @@  ncd_of_cand_and_phis (slsr_cand_t c, double_int incr, slsr_cand_t *where)
    *WHERE.  */
 
 static basic_block
-nearest_common_dominator_for_cands (slsr_cand_t c, double_int incr,
+nearest_common_dominator_for_cands (slsr_cand_t c, const widest_int &incr,
 				    slsr_cand_t *where)
 {
   basic_block sib_ncd = NULL, dep_ncd = NULL, this_ncd = NULL, ncd;
@@ -3037,13 +3028,13 @@  insert_initializers (slsr_cand_t c)
       slsr_cand_t where = NULL;
       gimple init_stmt;
       tree stride_type, new_name, incr_tree;
-      double_int incr = incr_vec[i].incr;
+      widest_int incr = incr_vec[i].incr;
 
       if (!profitable_increment_p (i)
-	  || incr.is_one ()
-	  || (incr.is_minus_one ()
+	  || incr == 1
+	  || (incr == -1
 	      && gimple_assign_rhs_code (c->cand_stmt) != POINTER_PLUS_EXPR)
-	  || incr.is_zero ())
+	  || incr == 0)
 	continue;
 
       /* We may have already identified an existing initializer that
@@ -3072,7 +3063,7 @@  insert_initializers (slsr_cand_t c)
 
       /* Create the initializer and insert it in the latest possible
 	 dominating position.  */
-      incr_tree = double_int_to_tree (stride_type, incr);
+      incr_tree = wide_int_to_tree (stride_type, incr);
       init_stmt = gimple_build_assign_with_ops (MULT_EXPR, new_name,
 						c->stride, incr_tree);
       if (where)
@@ -3129,9 +3120,9 @@  all_phi_incrs_profitable (slsr_cand_t c, gimple phi)
 	    {
 	      int j;
 	      slsr_cand_t arg_cand = base_cand_from_table (arg);
-	      double_int increment = arg_cand->index - basis->index;
+	      widest_int increment = arg_cand->index - basis->index;
 
-	      if (!address_arithmetic_p && increment.is_negative ())
+	      if (!address_arithmetic_p && wi::neg_p (increment))
 		increment = -increment;
 
 	      j = incr_vec_index (increment);
@@ -3142,7 +3133,7 @@  all_phi_incrs_profitable (slsr_cand_t c, gimple phi)
 			   c->cand_num);
 		  print_gimple_stmt (dump_file, phi, 0, 0);
 		  fputs ("    increment: ", dump_file);
-		  dump_double_int (dump_file, increment, false);
+		  print_decs (increment, dump_file);
 		  if (j < 0)
 		    fprintf (dump_file,
 			     "\n  Not replaced; incr_vec overflow.\n");
@@ -3237,7 +3228,7 @@  replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
   tree orig_rhs1, orig_rhs2;
   tree rhs2;
   enum tree_code orig_code, repl_code;
-  double_int cand_incr;
+  widest_int cand_incr;
 
   orig_code = gimple_assign_rhs_code (c->cand_stmt);
   orig_rhs1 = gimple_assign_rhs1 (c->cand_stmt);
@@ -3285,7 +3276,7 @@  replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
      from the basis name, or an add of the stride to the basis
      name, respectively.  It may be necessary to introduce a
      cast (or reuse an existing cast).  */
-  else if (cand_incr.is_one ())
+  else if (cand_incr == 1)
     {
       tree stride_type = TREE_TYPE (c->stride);
       tree orig_type = TREE_TYPE (orig_rhs2);
@@ -3300,7 +3291,7 @@  replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
 					      c);
     }
 
-  else if (cand_incr.is_minus_one ())
+  else if (cand_incr == -1)
     {
       tree stride_type = TREE_TYPE (c->stride);
       tree orig_type = TREE_TYPE (orig_rhs2);
@@ -3327,7 +3318,7 @@  replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
 	fputs ("  (duplicate, not actually replacing)\n", dump_file);
     }
 
-  else if (cand_incr.is_zero ())
+  else if (cand_incr == 0)
     {
       tree lhs = gimple_assign_lhs (c->cand_stmt);
       tree lhs_type = TREE_TYPE (lhs);
@@ -3377,7 +3368,7 @@  replace_profitable_candidates (slsr_cand_t c)
 {
   if (!cand_already_replaced (c))
     {
-      double_int increment = cand_abs_increment (c);
+      widest_int increment = cand_abs_increment (c);
       enum tree_code orig_code = gimple_assign_rhs_code (c->cand_stmt);
       int i;
 
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 2fe12b6..cfa752f 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -831,9 +831,17 @@  gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
   else
     prob = 0;
 
-  tree_val = build_int_cst_wide (get_gcov_type (),
-				 (unsigned HOST_WIDE_INT) val,
-				 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
+  if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT))
+    tree_val = build_int_cst (get_gcov_type (), val);
+  else
+    {
+      HOST_WIDE_INT a[2];
+      a[0] = (unsigned HOST_WIDE_INT) val;
+      a[1] = val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1;
+
+      tree_val = wide_int_to_tree (get_gcov_type (), wide_int::from_array (a, 2,
+	TYPE_PRECISION (get_gcov_type ()), false));
+    }
   result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
 
   if (dump_file)
@@ -1742,9 +1750,18 @@  gimple_stringops_transform (gimple_stmt_iterator *gsi)
     default:
       gcc_unreachable ();
     }
-  tree_val = build_int_cst_wide (get_gcov_type (),
-				 (unsigned HOST_WIDE_INT) val,
-				 val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
+  if (sizeof (gcov_type) == sizeof (HOST_WIDE_INT))
+    tree_val = build_int_cst (get_gcov_type (), val);
+  else
+    {
+      HOST_WIDE_INT a[2];
+      a[0] = (unsigned HOST_WIDE_INT) val;
+      a[1] = val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1;
+
+      tree_val = wide_int_to_tree (get_gcov_type (), wide_int::from_array (a, 2,
+	TYPE_PRECISION (get_gcov_type ()), false));
+    }
+
   if (dump_file)
     {
       fprintf (dump_file, "Single value %i stringop transformation on ",