gcc/

	* gimple-ssa-evrp-analyze.c
	(evrp_range_analyzer::try_find_new_range): Adjust for value_range API.
	(evrp_range_analyzer::set_ssa_range_info): Same.
	(evrp_range_analyzer::record_ranges_from_phis): Same.
	(evrp_range_analyzer::record_ranges_from_stmt): Same.
	* gimple-ssa-evrp.c (evrp_dom_walker::before_dom_children): Same.
	* gimple-ssa-sprintf.c (get_int_range): Same.
	(format_integer): Same.
	(sprintf_dom_walker::handle_gimple_call): Same.
	* ipa-cp.c (ipcp_vr_lattice::meet_with_1): Same.
	(ipcp_vr_lattice::top_p): Same.
	(ipcp_vr_lattice::bottom_p): Same.
	(ipcp_vr_lattice::set_to_bottom): Same.
	(ipa_vr_operation_and_type_effects): Same.
	(propagate_vr_across_jump_function): Same.
	(ipcp_store_vr_results): Same.
	* ipa-prop.c (struct ipa_vr_ggc_hash_traits): Same.
	(ipa_print_node_jump_functions_for_edge): Same.
	(ipa_get_value_range): Same.
	(ipa_compute_jump_functions_for_edge): Same.
	(ipa_write_jump_function): Same.
	* tree-ssa-dom.c (simplify_stmt_for_jump_threading): Same.
	* tree-ssa-threadedge.c (record_temporary_equivalences_from_phis):
	Same.
	* vr-values.c (set_value_range_to_nonnegative): Same.
	(set_value_range_to_truthvalue): Same.
	(vr_values::get_value_range): Same.
	(vr_values::set_defs_to_varying): Same.
	(vr_values::update_value_range): Same.
	(symbolic_range_based_on_p): Same.
	(vr_values::op_with_boolean_value_range_p): Same.
	(vr_values::extract_range_for_var_from_comparison_expr): Same.
	(vr_values::extract_range_from_ssa_name): Same.
	(vr_values::extract_range_from_binary_expr): Same.
	(vr_values::extract_range_from_unary_expr): Same.
	(vr_values::extract_range_from_cond_expr): Same.
	(vr_values::extract_range_from_comparison): Same.
	(vr_values::check_for_binary_op_overflow): Same.
	(vr_values::extract_range_basic): Same.
	(vr_values::extract_range_from_assignment): Same.
	(compare_ranges): Same.
	(compare_range_with_value): Same.
	(vr_values::adjust_range_with_scev): Same.
	(vrp_valueize): Same.
	(vrp_valueize_1): Same.
	(vr_values::get_vr_for_comparison): Same.
	(vr_values::compare_name_with_value): Same.
	(vr_values::compare_names): Same.
	(vr_values::vrp_evaluate_conditional): Same.
	(find_case_label_ranges): Same.
	(vr_values::vrp_visit_switch_stmt): Same.
	(vr_values::extract_range_from_phi_node): Same.
	(vr_values::simplify_div_or_mod_using_ranges): Same.
	(vr_values::simplify_bit_ops_using_ranges): Same.
	(test_for_singularity): Same.
	(range_fits_type_p): Same.
	(vr_values::simplify_cond_using_ranges_1): Same.
	(vr_values::simplify_switch_using_ranges): Same.
	(vr_values::simplify_float_conversion_using_ranges): Same.
	(vr_values::two_valued_val_range_p): Same.
	(vr_values::add_equivalence): Rewrite to return adjusted value
	instead of setting a pointer.
	* vr-values.h (vr_values::add_equivalence): Adjust to return
	value.
	(VR_INITIALIZER): Remove.
	* tree-vrp.c (value_range::set): New.
	(value_range::value_range): New.
	(value_range::copy_with_equiv_update): New.
	(value_range::check): New.
	(value_range::equal_p): New.
	(value_range::ignore_equivs_equal_p): New.
	(value_range::operator==): New.
	(value_range::operator!=): New.
	(value_range::symbolic_p): New.
	(value_range::numeric_p): New.
	(value_range::set_undefined): New.
	(value_range::set_varying): New.
	(value_range::may_contain_p): New.
	(value_range::equiv_free): New.
	(value_range::equiv_copy): New.
	(value_range::equiv_clear): New.
	(value_range::equiv_and): New.
	(value_range::equiv_ior): New.
	(value_range::singleton): New.
	(value_range::union_): New.
	(value_range::intersect): New.
	(value_range::dump): New.
	(set_value_range_to_undefined): New.
	(set_value_range_to_varying): New.
	(value_range::set_and_canonicalize): New.
	(set_value_range): Adjust for value_range API.
	(set_and_canonicalize_value_range): Same.
	(copy_value_range): Same.
	(set_value_range_to_nonnull): Same.
	(set_value_range_to_null): Same.
	(range_is_null): Same.
	(range_is_nonnull): Same.
	(range_int_cst_p): Same.
	(range_int_cst_singleton_p): Same.
	(symbolic_range_p): Same.
	(range_includes_zero_p): Same.
	(value_range_constant_singleton): Same.
	(vrp_set_zero_nonzero_bits): Same.
	(ranges_from_anti_range): Same.
	(extract_range_into_wide_ints): Same.
	(extract_range_from_multiplicative_op): Same.
	(set_value_range_with_overflow): Same.
	(extract_range_from_binary_expr_1): Same.
	(extract_range_from_unary_expr): Same.
	(dump_value_range): Same.
	(debug_value_range): Same.
	(vrp_prop::check_array_ref): Same.
	(vrp_prop::check_mem_ref): Same.
	(vrp_prop::vrp_initialize): Same.
	(vrp_prop::visit_stmt): Same.
	(intersect_ranges): Same.
	(vrp_prop::visit_phi): Same.
	(vrp_prop::vrp_finalize): Same.
	(determine_value_range_1): Same.
	(determine_value_range): Same.
	(vrp_intersect_ranges_1): Rename to...
	(vrp_intersect_1): this.
	(vrp_intersect_ranges): Rename to...
	(vrp_intersect): ...this.
	(vrp_meet_1): Rename to...
	(vrp_union_1): ...this.
	(vrp_meet): Rename to...
	(vrp_union): ...this.
	* tree-vrp.h (struct value_range): Rewrite into a proper class.
	(value_range::vrtype): New.
	(value_range::type): New.
	(value_range::equiv): New.
	(value_range::min): New.
	(value_range::max): New.
	(value_range::varying_p): New.
	(value_range::undefined_p): New.
	(value_range::set_equiv): New.
	(value_range::null_p): New.

diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index e9afa80e191..e3695432c88 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -82,7 +82,7 @@ value_range *
 evrp_range_analyzer::try_find_new_range (tree name,
 				    tree op, tree_code code, tree limit)
 {
-  value_range vr = VR_INITIALIZER;
+  value_range vr (TREE_TYPE (name));
   value_range *old_vr = get_value_range (name);
 
   /* Discover VR when condition is true.  */
@@ -90,11 +90,11 @@ evrp_range_analyzer::try_find_new_range (tree name,
 							 limit, &vr);
   /* If we found any usable VR, set the VR to ssa_name and create a
      PUSH old value in the stack with the old VR.  */
-  if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
+  if (!vr.undefined_p () && !vr.varying_p ())
     {
-      if (old_vr->type == vr.type
-	  && vrp_operand_equal_p (old_vr->min, vr.min)
-	  && vrp_operand_equal_p (old_vr->max, vr.max))
+      if (old_vr->vrtype () == vr.vrtype ()
+	  && vrp_operand_equal_p (old_vr->min (), vr.min ())
+	  && vrp_operand_equal_p (old_vr->max (), vr.max ()))
 	return NULL;
       value_range *new_vr = vr_values->allocate_value_range ();
       *new_vr = vr;
@@ -110,13 +110,10 @@ evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range *vr)
   /* Set the SSA with the value range.  */
   if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
     {
-      if ((vr->type == VR_RANGE
-	   || vr->type == VR_ANTI_RANGE)
-	  && (TREE_CODE (vr->min) == INTEGER_CST)
-	  && (TREE_CODE (vr->max) == INTEGER_CST))
-	set_range_info (lhs, vr->type,
-			wi::to_wide (vr->min),
-			wi::to_wide (vr->max));
+      if (vr->numeric_p ())
+	set_range_info (lhs, vr->vrtype (),
+			wi::to_wide (vr->min ()),
+			wi::to_wide (vr->max ()));
     }
   else if (POINTER_TYPE_P (TREE_TYPE (lhs))
 	   && range_includes_zero_p (vr) == 0)
@@ -241,13 +238,13 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
       if (virtual_operand_p (lhs))
 	continue;
 
-      value_range vr_result = VR_INITIALIZER;
+      value_range vr_result (TREE_TYPE (lhs));
       bool interesting = stmt_interesting_for_vrp (phi);
       if (!has_unvisited_preds && interesting)
 	vr_values->extract_range_from_phi_node (phi, &vr_result);
       else
 	{
-	  set_value_range_to_varying (&vr_result);
+	  set_value_range_to_varying (&vr_result, TREE_TYPE (lhs));
 	  /* When we have an unvisited executable predecessor we can't
 	     use PHI arg ranges which may be still UNDEFINED but have
 	     to use VARYING for them.  But we can still resort to
@@ -284,7 +281,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
   else if (stmt_interesting_for_vrp (stmt))
     {
       edge taken_edge;
-      value_range vr = VR_INITIALIZER;
+      value_range vr;
       vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
       if (output)
 	{
@@ -315,7 +312,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
 		 bitmaps.  Ugh.  */
 	      value_range *new_vr = vr_values->allocate_value_range ();
 	      *new_vr = vr;
-	      new_vr->equiv = NULL;
+	      new_vr->set_equiv (NULL);
 	      push_value_range (output, new_vr);
 	    }
 	}
diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index 50e8adc1aad..b075c1051d8 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -161,8 +161,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
 	      value_range *vr = evrp_range_analyzer.get_value_range (output);
 
 	      /* Mark stmts whose output we fully propagate for removal.  */
-	      if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
-		  && (val = value_range_constant_singleton (vr))
+	      if ((val = value_range_constant_singleton (vr))
 		  && may_propagate_copy (output, val)
 		  && !stmt_could_throw_p (stmt)
 		  && !gimple_has_side_effects (stmt))
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 471bfc45eb8..5bc5607c92f 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -1052,9 +1052,7 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
 	{
 	  /* Try to determine the range of values of the integer argument.  */
 	  value_range *vr = vr_values->get_value_range (arg);
-	  if (vr->type == VR_RANGE
-	      && TREE_CODE (vr->min) == INTEGER_CST
-	      && TREE_CODE (vr->max) == INTEGER_CST)
+	  if (range_int_cst_p (vr))
 	    {
 	      HOST_WIDE_INT type_min
 		= (TYPE_UNSIGNED (argtype)
@@ -1063,8 +1061,8 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
 
 	      HOST_WIDE_INT type_max = tree_to_uhwi (TYPE_MAX_VALUE (argtype));
 
-	      *pmin = TREE_INT_CST_LOW (vr->min);
-	      *pmax = TREE_INT_CST_LOW (vr->max);
+	      *pmin = TREE_INT_CST_LOW (vr->min ());
+	      *pmax = TREE_INT_CST_LOW (vr->max ());
 
 	      if (*pmin < *pmax)
 		{
@@ -1354,12 +1352,10 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values)
       /* Try to determine the range of values of the integer argument
 	 (range information is not available for pointers).  */
       value_range *vr = vr_values->get_value_range (arg);
-      if (vr->type == VR_RANGE
-	  && TREE_CODE (vr->min) == INTEGER_CST
-	  && TREE_CODE (vr->max) == INTEGER_CST)
+      if (range_int_cst_p (vr))
 	{
-	  argmin = vr->min;
-	  argmax = vr->max;
+	  argmin = vr->min ();
+	  argmax = vr->max ();
 
 	  /* Set KNOWNRANGE if the argument is in a known subrange
 	     of the directive's type and neither width nor precision
@@ -1372,12 +1368,11 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values)
 	  res.argmin = argmin;
 	  res.argmax = argmax;
 	}
-      else if (vr->type == VR_ANTI_RANGE)
+      else if (vr->vrtype () == VR_ANTI_RANGE)
 	{
 	  /* Handle anti-ranges if/when bug 71690 is resolved.  */
 	}
-      else if (vr->type == VR_VARYING
-	       || vr->type == VR_UNDEFINED)
+      else if (vr->varying_p () || vr->undefined_p ())
 	{
 	  /* The argument here may be the result of promoting the actual
 	     argument to int.  Try to determine the type of the actual
@@ -3903,12 +3898,10 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi)
 	     and use the greater of the two at level 1 and the smaller
 	     of them at level 2.  */
 	  value_range *vr = evrp_range_analyzer.get_value_range (size);
-	  if (vr->type == VR_RANGE
-	      && TREE_CODE (vr->min) == INTEGER_CST
-	      && TREE_CODE (vr->max) == INTEGER_CST)
+	  if (range_int_cst_p (vr))
 	    dstsize = (warn_level < 2
-		       ? TREE_INT_CST_LOW (vr->max)
-		       : TREE_INT_CST_LOW (vr->min));
+		       ? TREE_INT_CST_LOW (vr->max ())
+		       : TREE_INT_CST_LOW (vr->min ()));
 
 	  /* The destination size is not constant.  If the function is
 	     bounded (e.g., snprintf) a lower bound of zero doesn't
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 27ae8e0fe27..3223f32a073 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -314,7 +314,7 @@ public:
   inline bool set_to_bottom ();
   bool meet_with (const value_range *p_vr);
   bool meet_with (const ipcp_vr_lattice &other);
-  void init () { m_vr.type = VR_UNDEFINED; }
+  void init () { gcc_assert (m_vr.undefined_p ()); }
   void print (FILE * f);
 
 private:
@@ -914,28 +914,21 @@ ipcp_vr_lattice::meet_with (const value_range *p_vr)
   return meet_with_1 (p_vr);
 }
 
-/* Meet the current value of the lattice with value ranfge described by
-   OTHER_VR lattice.  */
+/* Meet the current value of the lattice with value range described by
+   OTHER_VR lattice.  Return TRUE if anything changed.  */
 
 bool
 ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
 {
-  tree min = m_vr.min, max = m_vr.max;
-  value_range_type type = m_vr.type;
-
   if (bottom_p ())
     return false;
 
-  if (other_vr->type == VR_VARYING)
+  if (other_vr->varying_p ())
     return set_to_bottom ();
 
-  vrp_meet (&m_vr, other_vr);
-  if (type != m_vr.type
-      || min != m_vr.min
-      || max != m_vr.max)
-    return true;
-  else
-    return false;
+  value_range save (m_vr);
+  m_vr.union_ (other_vr);
+  return !m_vr.ignore_equivs_equal_p (save);
 }
 
 /* Return true if value range information in the lattice is yet unknown.  */
@@ -943,7 +936,7 @@ ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
 bool
 ipcp_vr_lattice::top_p () const
 {
-  return m_vr.type == VR_UNDEFINED;
+  return m_vr.undefined_p ();
 }
 
 /* Return true if value range information in the lattice is known to be
@@ -952,7 +945,7 @@ ipcp_vr_lattice::top_p () const
 bool
 ipcp_vr_lattice::bottom_p () const
 {
-  return m_vr.type == VR_VARYING;
+  return m_vr.varying_p ();
 }
 
 /* Set value range information in the lattice to bottom.  Return true if it
@@ -961,9 +954,10 @@ ipcp_vr_lattice::bottom_p () const
 bool
 ipcp_vr_lattice::set_to_bottom ()
 {
-  if (m_vr.type == VR_VARYING)
+  if (m_vr.varying_p ())
     return false;
-  m_vr.type = VR_VARYING;
+  /* ?? Use any type for VARYING for now.  */
+  m_vr.set_varying (integer_type_node);
   return true;
 }
 
@@ -1882,12 +1876,11 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr,
 				   enum tree_code operation,
 				   tree dst_type, tree src_type)
 {
-  memset (dst_vr, 0, sizeof (*dst_vr));
+  *dst_vr = value_range ();
   extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
-  if (dst_vr->type == VR_RANGE || dst_vr->type == VR_ANTI_RANGE)
-    return true;
-  else
+  if (dst_vr->varying_p () || dst_vr->undefined_p ())
     return false;
+  return true;
 }
 
 /* Propagate value range across jump function JFUNC that is associated with
@@ -1940,11 +1933,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
 	  if (TREE_OVERFLOW_P (val))
 	    val = drop_tree_overflow (val);
 
-	  value_range tmpvr;
-	  memset (&tmpvr, 0, sizeof (tmpvr));
-	  tmpvr.type = VR_RANGE;
-	  tmpvr.min = val;
-	  tmpvr.max = val;
+	  value_range tmpvr (VR_RANGE, TREE_TYPE (val), val, val);
 	  return dest_lat->meet_with (&tmpvr);
 	}
     }
@@ -1953,7 +1942,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
   if (jfunc->m_vr
       && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
 					    param_type,
-					    TREE_TYPE (jfunc->m_vr->min)))
+					    jfunc->m_vr->type ()))
     return dest_lat->meet_with (&vr);
   else
     return dest_lat->set_to_bottom ();
@@ -5028,9 +5017,9 @@ ipcp_store_vr_results (void)
 	      && !plats->m_value_range.top_p ())
 	    {
 	      vr.known = true;
-	      vr.type = plats->m_value_range.m_vr.type;
-	      vr.min = wi::to_wide (plats->m_value_range.m_vr.min);
-	      vr.max = wi::to_wide (plats->m_value_range.m_vr.max);
+	      vr.type = plats->m_value_range.m_vr.vrtype ();
+	      vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
+	      vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
 	    }
 	  else
 	    {
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 8b19fe3f391..ceecce1241f 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -113,16 +113,16 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
   static hashval_t
   hash (const value_range *p)
     {
-      gcc_checking_assert (!p->equiv);
-      inchash::hash hstate (p->type);
-      hstate.add_ptr (p->min);
-      hstate.add_ptr (p->max);
+      gcc_checking_assert (!p->equiv ());
+      inchash::hash hstate (p->vrtype ());
+      hstate.add_ptr (p->min ());
+      hstate.add_ptr (p->max ());
       return hstate.end ();
     }
   static bool
   equal (const value_range *a, const value_range *b)
     {
-      return a->type == b->type && a->min == b->min && a->max == b->max;
+      return a->ignore_equivs_equal_p (*b);
     }
   static void
   mark_empty (value_range *&p)
@@ -398,10 +398,10 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 	{
 	  fprintf (f, "         VR  ");
 	  fprintf (f, "%s[",
-		   (jump_func->m_vr->type == VR_ANTI_RANGE) ? "~" : "");
-	  print_decs (wi::to_wide (jump_func->m_vr->min), f);
+		   (jump_func->m_vr->vrtype () == VR_ANTI_RANGE) ? "~" : "");
+	  print_decs (wi::to_wide (jump_func->m_vr->min ()), f);
 	  fprintf (f, ", ");
-	  print_decs (wi::to_wide (jump_func->m_vr->max), f);
+	  print_decs (wi::to_wide (jump_func->m_vr->max ()), f);
 	  fprintf (f, "]\n");
 	}
       else
@@ -1791,11 +1791,7 @@ ipa_get_value_range (value_range *tmp)
 static value_range *
 ipa_get_value_range (enum value_range_type type, tree min, tree max)
 {
-  value_range tmp;
-  tmp.type = type;
-  tmp.min = min;
-  tmp.max = max;
-  tmp.equiv = NULL;
+  value_range tmp (type, TREE_TYPE (min), min, max);
   return ipa_get_value_range (&tmp);
 }
 
@@ -1890,16 +1886,13 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	      && (type = get_range_info (arg, &min, &max))
 	      && (type == VR_RANGE || type == VR_ANTI_RANGE))
 	    {
-	      value_range tmpvr,resvr;
-
-	      tmpvr.type = type;
-	      tmpvr.min = wide_int_to_tree (TREE_TYPE (arg), min);
-	      tmpvr.max = wide_int_to_tree (TREE_TYPE (arg), max);
-	      tmpvr.equiv = NULL;
-	      memset (&resvr, 0, sizeof (resvr));
+	      value_range resvr;
+	      value_range tmpvr (type, TREE_TYPE (arg),
+				 wide_int_to_tree (TREE_TYPE (arg), min),
+				 wide_int_to_tree (TREE_TYPE (arg), max));
 	      extract_range_from_unary_expr (&resvr, NOP_EXPR, param_type,
 					     &tmpvr, TREE_TYPE (arg));
-	      if (resvr.type == VR_RANGE || resvr.type == VR_ANTI_RANGE)
+	      if (!resvr.undefined_p () && !resvr.varying_p ())
 		ipa_set_jfunc_vr (jfunc, &resvr);
 	      else
 		gcc_assert (!jfunc->m_vr);
@@ -4126,9 +4119,9 @@ ipa_write_jump_function (struct output_block *ob,
   if (jump_func->m_vr)
     {
       streamer_write_enum (ob->main_stream, value_rang_type,
-			   VR_LAST, jump_func->m_vr->type);
-      stream_write_tree (ob, jump_func->m_vr->min, true);
-      stream_write_tree (ob, jump_func->m_vr->max, true);
+			   VR_LAST, jump_func->m_vr->vrtype ());
+      stream_write_tree (ob, jump_func->m_vr->min (), true);
+      stream_write_tree (ob, jump_func->m_vr->max (), true);
     }
 }
 
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index f7cc034b26e..cb74ed15d72 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -882,25 +882,27 @@ simplify_stmt_for_jump_threading (gimple *stmt,
 	return NULL_TREE;
 
       value_range *vr = x_vr_values->get_value_range (op);
-      if ((vr->type != VR_RANGE && vr->type != VR_ANTI_RANGE)
-	  || symbolic_range_p (vr))
+      if (vr->undefined_p ()
+	  || vr->varying_p ()
+	  || vr->symbolic_p ())
 	return NULL_TREE;
 
-      if (vr->type == VR_RANGE)
+      if (vr->vrtype () == VR_RANGE)
 	{
 	  size_t i, j;
 
-	  find_case_label_range (switch_stmt, vr->min, vr->max, &i, &j);
+	  find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j);
 
 	  if (i == j)
 	    {
 	      tree label = gimple_switch_label (switch_stmt, i);
+	      tree singleton;
 
 	      if (CASE_HIGH (label) != NULL_TREE
-		  ? (tree_int_cst_compare (CASE_LOW (label), vr->min) <= 0
-		     && tree_int_cst_compare (CASE_HIGH (label), vr->max) >= 0)
-		  : (tree_int_cst_equal (CASE_LOW (label), vr->min)
-		     && tree_int_cst_equal (vr->min, vr->max)))
+		  ? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0
+		     && tree_int_cst_compare (CASE_HIGH (label), vr->max ()) >= 0)
+		  : ((singleton = vr->singleton ())
+		     && tree_int_cst_equal (CASE_LOW (label), singleton)))
 		return label;
 
 	      if (i > j)
@@ -908,7 +910,7 @@ simplify_stmt_for_jump_threading (gimple *stmt,
 	    }
 	}
 
-      if (vr->type == VR_ANTI_RANGE)
+      if (vr->vrtype () == VR_ANTI_RANGE)
           {
             unsigned n = gimple_switch_num_labels (switch_stmt);
             tree min_label = gimple_switch_label (switch_stmt, 1);
@@ -917,10 +919,10 @@ simplify_stmt_for_jump_threading (gimple *stmt,
             /* The default label will be taken only if the anti-range of the
                operand is entirely outside the bounds of all the (non-default)
                case labels.  */
-            if (tree_int_cst_compare (vr->min, CASE_LOW (min_label)) <= 0
+            if (tree_int_cst_compare (vr->min (), CASE_LOW (min_label)) <= 0
                 && (CASE_HIGH (max_label) != NULL_TREE
-                    ? tree_int_cst_compare (vr->max, CASE_HIGH (max_label)) >= 0
-                    : tree_int_cst_compare (vr->max, CASE_LOW (max_label)) >= 0))
+                    ? tree_int_cst_compare (vr->max (), CASE_HIGH (max_label)) >= 0
+                    : tree_int_cst_compare (vr->max (), CASE_LOW (max_label)) >= 0))
             return gimple_switch_label (switch_stmt, 0);
           }
 	return NULL_TREE;
@@ -936,11 +938,12 @@ simplify_stmt_for_jump_threading (gimple *stmt,
 	{
 	  edge dummy_e;
 	  tree dummy_tree;
-	  value_range new_vr = VR_INITIALIZER;
+	  value_range new_vr;
 	  x_vr_values->extract_range_from_stmt (stmt, &dummy_e,
 					      &dummy_tree, &new_vr);
-	  if (range_int_cst_singleton_p (&new_vr))
-	    return new_vr.min;
+	  tree singleton;
+	  if ((singleton = new_vr.singleton ()))
+	    return singleton;
 	}
     }
   return NULL;
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index a2304493495..9f510730aed 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -166,7 +166,7 @@ record_temporary_equivalences_from_phis (edge e,
 	     away in the VR stack.  */
 	  vr_values *vr_values = evrp_range_analyzer->get_vr_values ();
 	  value_range *new_vr = vr_values->allocate_value_range ();
-	  memset (new_vr, 0, sizeof (value_range));
+	  *new_vr = value_range ();
 
 	  /* There are three cases to consider:
 
@@ -183,7 +183,7 @@ record_temporary_equivalences_from_phis (edge e,
 	  else if (TREE_CODE (src) == INTEGER_CST)
 	    set_value_range_to_value (new_vr, src,  NULL);
 	  else
-	    set_value_range_to_varying (new_vr);
+	    set_value_range_to_varying (new_vr, TREE_TYPE (src));
 
 	  /* This is a temporary range for DST, so push it.  */
 	  evrp_range_analyzer->push_value_range (dst, new_vr);
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index cbc2ea2f26b..555f515f609 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -73,6 +73,248 @@ along with GCC; see the file COPYING3.  If not see
    for still active basic-blocks.  */
 static sbitmap *live;
 
+static void vrp_union (value_range *, const value_range *);
+static void vrp_intersect (value_range *, const value_range *);
+
+/* Initialize value_range.  */
+
+void
+value_range::set (enum value_range_type vrtype, tree type,
+		  tree min, tree max, bitmap equiv)
+{
+  m_type = type;
+  m_vrtype = vrtype;
+  m_min = min;
+  m_max = max;
+
+  /* Since updating the equivalence set involves deep copying the
+     bitmaps, only do it if absolutely necessary.
+
+     All equivalence bitmaps are allocated from the same obstack.  So
+     we can use the obstack associated with EQUIV to allocate vr->equiv.  */
+  if (m_equiv == NULL
+      && equiv != NULL)
+    m_equiv = BITMAP_ALLOC (equiv->obstack);
+
+  if (equiv != m_equiv)
+    {
+      if (equiv && !bitmap_empty_p (equiv))
+	bitmap_copy (m_equiv, equiv);
+      else
+	bitmap_clear (m_equiv);
+    }
+  if (flag_checking)
+    check ();
+}
+
+value_range::value_range (value_range_type vrtype, tree type,
+			  tree min, tree max, bitmap equiv)
+{
+  m_equiv = NULL;
+  set (vrtype, type, min, max, equiv);
+}
+
+/* Initialize value_range from FROM and update equivalence table.  */
+
+void
+value_range::copy_with_equiv_update (const value_range *from)
+{
+  set (from->m_vrtype, from->m_type, from->m_min, from->m_max, from->m_equiv);
+}
+
+/* Check the validity of the range.  */
+
+void
+value_range::check ()
+{
+  if (flag_checking
+      && (m_vrtype == VR_RANGE || m_vrtype == VR_ANTI_RANGE))
+    {
+      int cmp;
+
+      gcc_assert (m_min && m_max);
+
+      gcc_assert (!TREE_OVERFLOW_P (m_min) && !TREE_OVERFLOW_P (m_max));
+
+      /* An anti range cannot be [-MIN, +MAX] because that would
+	 be either empty or VR_UNDEFINED.  */
+      if (INTEGRAL_TYPE_P (TREE_TYPE (m_min)) && m_vrtype == VR_ANTI_RANGE)
+	gcc_assert (!vrp_val_is_min (m_min) || !vrp_val_is_max (m_max));
+
+      cmp = compare_values (m_min, m_max);
+      gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
+    }
+
+  if (flag_checking
+      && (m_vrtype == VR_UNDEFINED || m_vrtype == VR_VARYING))
+    {
+      gcc_assert (m_min == NULL_TREE && m_max == NULL_TREE);
+      gcc_assert (m_equiv == NULL || bitmap_empty_p (m_equiv));
+    }
+}
+
+/* Returns TRUE if THIS == OTHER.  Ignores the equivalence bitmap if
+   IGNORE_EQUIVS is TRUE.  */
+
+bool
+value_range::equal_p (const value_range &other, bool ignore_equivs) const
+{
+ return (m_type == other.m_type
+	 && m_vrtype == other.m_vrtype
+	 && vrp_operand_equal_p (m_min, other.m_min)
+	 && vrp_operand_equal_p (m_max, other.m_max)
+	 && (ignore_equivs
+	     || vrp_bitmap_equal_p (m_equiv, other.m_equiv)));
+}
+
+bool
+value_range::ignore_equivs_equal_p (const value_range &other) const
+{
+  return equal_p (other, /*ignore_equivs=*/true);
+}
+
+bool
+value_range::operator== (const value_range &other) const
+{
+ return equal_p (other, /*ignore_equivs=*/false);
+}
+
+bool
+value_range::operator!= (const value_range &other) const
+{
+ return !(*this == other);
+}
+
+bool
+value_range::symbolic_p () const
+{
+  return (!varying_p ()
+	  && !undefined_p ()
+	  && (!is_gimple_min_invariant (m_min)
+	      || !is_gimple_min_invariant (m_max)));
+}
+
+/* NOTE: Numeric is not the inverse of symbolic_p because the range
+   could also be varying or undefined.  Ideally they should be inverse
+   of each other, with varying only applying to symbolics.  Varying of
+   numerics would be represented as [-MIN, +MAX].  */
+
+bool
+value_range::numeric_p () const
+{
+  return (!varying_p ()
+	  && !undefined_p ()
+	  && TREE_CODE (m_min) == INTEGER_CST
+	  && TREE_CODE (m_max) == INTEGER_CST);
+}
+
+void
+value_range::set_undefined (tree type)
+{
+  if (m_equiv)
+    bitmap_clear (m_equiv);
+  if (type)
+    m_type = type;
+  else
+    gcc_assert (m_type);
+  *this = value_range (VR_UNDEFINED, m_type, NULL, NULL, m_equiv);
+}
+
+void
+value_range::set_varying (tree type)
+{
+  if (m_equiv)
+    bitmap_clear (m_equiv);
+  if (type)
+    m_type = type;
+  else
+    gcc_assert (m_type);
+  *this = value_range (VR_VARYING, m_type, NULL, NULL, m_equiv);
+}
+
+bool
+value_range::may_contain_p (tree val) const
+{
+  if (varying_p ())
+    return true;
+
+  if (undefined_p ())
+    return true;
+
+  if (m_vrtype == VR_ANTI_RANGE)
+    {
+      int res = value_inside_range (val, m_min, m_max);
+      return res == 0 || res == -2;
+    }
+  return value_inside_range (val, m_min, m_max) != 0;
+}
+
+void
+value_range::equiv_free ()
+{
+  BITMAP_FREE (m_equiv);
+  m_equiv = NULL;
+}
+
+void
+value_range::equiv_copy (const value_range *other)
+{
+  bitmap_copy (m_equiv, other->m_equiv);
+}
+
+void
+value_range::equiv_clear ()
+{
+  if (m_equiv)
+    bitmap_clear (m_equiv);
+}
+
+void
+value_range::equiv_and (const value_range *other)
+{
+  if (m_equiv && other->m_equiv)
+    bitmap_and_into (m_equiv, other->m_equiv);
+}
+
+void
+value_range::equiv_ior (const value_range *other)
+{
+  bitmap_ior_into (m_equiv, other->m_equiv);
+}
+
+/* If value range is a singleton, return the singleton, otherwise
+   return NULL.  Note: A singleton can be any gimple invariant, not
+   just constants.  So, [&x, &x] counts as a singleton.  */
+
+tree
+value_range::singleton () const
+{
+  if (m_vrtype == VR_RANGE
+      && vrp_operand_equal_p (m_min, m_max)
+      && is_gimple_min_invariant (m_min))
+    return m_min;
+  return NULL_TREE;
+}
+
+void
+value_range::union_ (const value_range *other)
+{
+  vrp_union (this, other);
+}
+
+void
+value_range::intersect (const value_range *other)
+{
+  vrp_intersect (this, other);
+}
+
+void
+value_range::dump () const
+{
+  dump_value_range (stderr, this);
+  fprintf (stderr, "\n");
+}
+
 /* Return true if the SSA name NAME is live on the edge E.  */
 
 static bool
@@ -243,80 +485,41 @@ intersect_range_with_nonzero_bits (enum value_range_type vr_type,
 /* Set value range VR to VR_UNDEFINED.  */
 
 static inline void
-set_value_range_to_undefined (value_range *vr)
+set_value_range_to_undefined (value_range *vr, tree type)
 {
-  vr->type = VR_UNDEFINED;
-  vr->min = vr->max = NULL_TREE;
-  if (vr->equiv)
-    bitmap_clear (vr->equiv);
+  vr->set_undefined (type);
 }
 
 /* Set value range VR to VR_VARYING.  */
 
 void
-set_value_range_to_varying (value_range *vr)
+set_value_range_to_varying (value_range *vr, tree type)
 {
-  vr->type = VR_VARYING;
-  vr->min = vr->max = NULL_TREE;
-  if (vr->equiv)
-    bitmap_clear (vr->equiv);
+  vr->set_varying (type);
 }
 
 /* Set value range VR to {T, MIN, MAX, EQUIV}.  */
 
 void
-set_value_range (value_range *vr, enum value_range_type t, tree min,
-		 tree max, bitmap equiv)
+set_value_range (value_range *vr, enum value_range_type vrtype,
+		 tree min, tree max, bitmap equiv)
 {
-  /* Check the validity of the range.  */
-  if (flag_checking
-      && (t == VR_RANGE || t == VR_ANTI_RANGE))
-    {
-      int cmp;
-
-      gcc_assert (min && max);
-
-      gcc_assert (!TREE_OVERFLOW_P (min) && !TREE_OVERFLOW_P (max));
-
-      if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
-	gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));
-
-      cmp = compare_values (min, max);
-      gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
-    }
-
-  if (flag_checking
-      && (t == VR_UNDEFINED || t == VR_VARYING))
-    {
-      gcc_assert (min == NULL_TREE && max == NULL_TREE);
-      gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
-    }
-
-  vr->type = t;
-  vr->min = min;
-  vr->max = max;
-
-  /* Since updating the equivalence set involves deep copying the
-     bitmaps, only do it if absolutely necessary.
-
-     All equivalence bitmaps are allocated from the same obstack.  So
-     we can use the obstack associated with EQUIV to allocate vr->equiv.  */
-  if (vr->equiv == NULL
-      && equiv != NULL)
-    vr->equiv = BITMAP_ALLOC (equiv->obstack);
+  gcc_assert (min && max);
+  value_range tmp (vrtype, TREE_TYPE (min), min, max, equiv);
+  vr->copy_with_equiv_update (&tmp);
+}
 
-  if (equiv != vr->equiv)
-    {
-      if (equiv && !bitmap_empty_p (equiv))
-	bitmap_copy (vr->equiv, equiv);
-      else
-	bitmap_clear (vr->equiv);
-    }
+void
+set_value_range (value_range *vr, tree type, enum value_range_type vrtype,
+		 tree min, tree max, bitmap equiv)
+{
+  value_range tmp (vrtype, type, min, max, equiv);
+  vr->copy_with_equiv_update (&tmp);
 }
 
 
-/* Set value range VR to the canonical form of {T, MIN, MAX, EQUIV}.
-   This means adjusting T, MIN and MAX representing the case of a
+/* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}.
+   This means adjusting VRTYPE, MIN and MAX representing the case of a
    wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
    as anti-rage ~[MAX+1, MIN-1].  Likewise for wrapping anti-ranges.
    In corner cases where MAX+1 or MIN-1 wraps this will fall back
@@ -325,18 +528,18 @@ set_value_range (value_range *vr, enum value_range_type t, tree min,
    extract ranges from var + CST op limit.  */
 
 void
-set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
-				  tree min, tree max, bitmap equiv)
+value_range::set_and_canonicalize (enum value_range_type vrtype, tree type,
+				   tree min, tree max, bitmap equiv)
 {
   /* Use the canonical setters for VR_UNDEFINED and VR_VARYING.  */
-  if (t == VR_UNDEFINED)
+  if (vrtype == VR_UNDEFINED)
     {
-      set_value_range_to_undefined (vr);
+      set_undefined (type);
       return;
     }
-  else if (t == VR_VARYING)
+  else if (vrtype == VR_VARYING)
     {
-      set_value_range_to_varying (vr);
+      set_varying (type);
       return;
     }
 
@@ -344,7 +547,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
   if (TREE_CODE (min) != INTEGER_CST
       || TREE_CODE (max) != INTEGER_CST)
     {
-      set_value_range (vr, t, min, max, equiv);
+      set_value_range (this, vrtype, min, max, equiv);
       return;
     }
 
@@ -359,7 +562,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
 	 for VR_ANTI_RANGE empty range, so drop to varying as well.  */
       if (TYPE_PRECISION (TREE_TYPE (min)) == 1)
 	{
-	  set_value_range_to_varying (vr);
+	  set_varying (TREE_TYPE (min));
 	  return;
 	}
 
@@ -373,15 +576,15 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
 	 to varying in this case.  */
       if (tree_int_cst_lt (max, min))
 	{
-	  set_value_range_to_varying (vr);
+	  set_varying (TREE_TYPE (min));
 	  return;
 	}
 
-      t = t == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
+      vrtype = vrtype == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
     }
 
   /* Anti-ranges that can be represented as ranges should be so.  */
-  if (t == VR_ANTI_RANGE)
+  if (vrtype == VR_ANTI_RANGE)
     {
       /* For -fstrict-enums we may receive out-of-range ranges so consider
          values < -INF and values > INF as -INF/INF as well.  */
@@ -395,7 +598,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
 	{
 	  /* We cannot deal with empty ranges, drop to varying.
 	     ???  This could be VR_UNDEFINED instead.  */
-	  set_value_range_to_varying (vr);
+	  set_varying (type);
 	  return;
 	}
       else if (TYPE_PRECISION (TREE_TYPE (min)) == 1
@@ -407,7 +610,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
 	    min = max = vrp_val_max (TREE_TYPE (min));
 	  else
 	    min = max = vrp_val_min (TREE_TYPE (min));
-	  t = VR_RANGE;
+	  vrtype = VR_RANGE;
 	}
       else if (is_min
 	       /* As a special exception preserve non-null ranges.  */
@@ -417,14 +620,14 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
 	  tree one = build_int_cst (TREE_TYPE (max), 1);
 	  min = int_const_binop (PLUS_EXPR, max, one);
 	  max = vrp_val_max (TREE_TYPE (max));
-	  t = VR_RANGE;
+	  vrtype = VR_RANGE;
         }
       else if (is_max)
         {
 	  tree one = build_int_cst (TREE_TYPE (min), 1);
 	  max = int_const_binop (MINUS_EXPR, min, one);
 	  min = vrp_val_min (TREE_TYPE (min));
-	  t = VR_RANGE;
+	  vrtype = VR_RANGE;
         }
     }
 
@@ -432,7 +635,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
      to make sure VRP iteration terminates, otherwise we can get into
      oscillations.  */
 
-  set_value_range (vr, t, min, max, equiv);
+  set_value_range (this, type, vrtype, min, max, equiv);
 }
 
 /* Copy value range FROM into value range TO.  */
@@ -440,7 +643,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
 void
 copy_value_range (value_range *to, const value_range *from)
 {
-  set_value_range (to, from->type, from->min, from->max, from->equiv);
+  to->copy_with_equiv_update (from);
 }
 
 /* Set value range VR to a single value.  This function is only called
@@ -462,7 +665,7 @@ void
 set_value_range_to_nonnull (value_range *vr, tree type)
 {
   tree zero = build_int_cst (type, 0);
-  set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv);
+  set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv ());
 }
 
 
@@ -471,7 +674,7 @@ set_value_range_to_nonnull (value_range *vr, tree type)
 void
 set_value_range_to_null (value_range *vr, tree type)
 {
-  set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv);
+  set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv ());
 }
 
 /* Return true, if VAL1 and VAL2 are equal values for VRP purposes.  */
@@ -503,9 +706,15 @@ vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
 static inline bool
 range_is_null (const value_range *vr)
 {
-  return vr->type == VR_RANGE
-	 && integer_zerop (vr->min)
-	 && integer_zerop (vr->max);
+  return vr->null_p ();
+}
+
+static inline bool
+range_is_nonnull (const value_range *vr)
+{
+  return (vr->vrtype () == VR_ANTI_RANGE
+	  && vr->min () == vr->max ()
+	  && integer_zerop (vr->min ()));
 }
 
 /* Return true if max and min of VR are INTEGER_CST.  It's not necessary
@@ -514,9 +723,9 @@ range_is_null (const value_range *vr)
 bool
 range_int_cst_p (const value_range *vr)
 {
-  return (vr->type == VR_RANGE
-	  && TREE_CODE (vr->max) == INTEGER_CST
-	  && TREE_CODE (vr->min) == INTEGER_CST);
+  return (vr->vrtype () == VR_RANGE
+	  && TREE_CODE (vr->min ()) == INTEGER_CST
+	  && TREE_CODE (vr->max ()) == INTEGER_CST);
 }
 
 /* Return true if VR is a INTEGER_CST singleton.  */
@@ -525,16 +734,7 @@ bool
 range_int_cst_singleton_p (const value_range *vr)
 {
   return (range_int_cst_p (vr)
-	  && tree_int_cst_equal (vr->min, vr->max));
-}
-
-/* Return true if value range VR involves at least one symbol.  */
-
-bool
-symbolic_range_p (const value_range *vr)
-{
-  return (!is_gimple_min_invariant (vr->min)
-          || !is_gimple_min_invariant (vr->max));
+	  && tree_int_cst_equal (vr->min (), vr->max ()));
 }
 
 /* Return the single symbol (an SSA_NAME) contained in T if any, or NULL_TREE
@@ -849,34 +1049,20 @@ value_inside_range (tree val, tree min, tree max)
 bool
 range_includes_zero_p (const value_range *vr)
 {
-  if (vr->type == VR_VARYING)
-    return true;
-
-  /* Ughh, we don't know.  We choose not to optimize.  */
-  if (vr->type == VR_UNDEFINED)
-    return true;
-
-  tree zero = build_int_cst (TREE_TYPE (vr->min), 0);
-  if (vr->type == VR_ANTI_RANGE)
-    {
-      int res = value_inside_range (zero, vr->min, vr->max);
-      return res == 0 || res == -2;
-    }
-  return value_inside_range (zero, vr->min, vr->max) != 0;
+  tree zero = build_int_cst (vr->type (), 0);
+  return vr->may_contain_p (zero);
 }
 
-/* If *VR has a value rante that is a single constant value return that,
-   otherwise return NULL_TREE.  */
+/* If *VR has a value range that is a single constant value return that,
+   otherwise return NULL_TREE.
+
+   ?? This actually returns TRUE for [&x, &x], so perhaps "constant"
+   is not the best name.  */
 
 tree
 value_range_constant_singleton (const value_range *vr)
 {
-  if (vr->type == VR_RANGE
-      && vrp_operand_equal_p (vr->min, vr->max)
-      && is_gimple_min_invariant (vr->min))
-    return vr->min;
-
-  return NULL_TREE;
+  return vr->singleton ();
 }
 
 /* Value range wrapper for wide_int_range_set_zero_nonzero_bits.
@@ -899,8 +1085,8 @@ vrp_set_zero_nonzero_bits (const tree expr_type,
       return false;
     }
   wide_int_range_set_zero_nonzero_bits (TYPE_SIGN (expr_type),
-					wi::to_wide (vr->min),
-					wi::to_wide (vr->max),
+					wi::to_wide (vr->min ()),
+					wi::to_wide (vr->max ()),
 					*may_be_nonzero, *must_be_nonzero);
   return true;
 }
@@ -914,40 +1100,36 @@ static bool
 ranges_from_anti_range (const value_range *ar,
 			value_range *vr0, value_range *vr1)
 {
-  tree type = TREE_TYPE (ar->min);
+  tree type = ar->type ();
 
-  vr0->type = VR_UNDEFINED;
-  vr1->type = VR_UNDEFINED;
+  vr0->set_undefined (type);
+  vr1->set_undefined (type);
 
   /* As a future improvement, we could handle ~[0, A] as: [-INF, -1] U
      [A+1, +INF].  Not sure if this helps in practice, though.  */
 
-  if (ar->type != VR_ANTI_RANGE
-      || TREE_CODE (ar->min) != INTEGER_CST
-      || TREE_CODE (ar->max) != INTEGER_CST
+  if (ar->vrtype () != VR_ANTI_RANGE
+      || TREE_CODE (ar->min ()) != INTEGER_CST
+      || TREE_CODE (ar->max ()) != INTEGER_CST
       || !vrp_val_min (type)
       || !vrp_val_max (type))
     return false;
 
-  if (!vrp_val_is_min (ar->min))
-    {
-      vr0->type = VR_RANGE;
-      vr0->min = vrp_val_min (type);
-      vr0->max = wide_int_to_tree (type, wi::to_wide (ar->min) - 1);
-    }
-  if (!vrp_val_is_max (ar->max))
-    {
-      vr1->type = VR_RANGE;
-      vr1->min = wide_int_to_tree (type, wi::to_wide (ar->max) + 1);
-      vr1->max = vrp_val_max (type);
-    }
-  if (vr0->type == VR_UNDEFINED)
+  if (!vrp_val_is_min (ar->min ()))
+    *vr0 = value_range (VR_RANGE, type,
+			vrp_val_min (type),
+			wide_int_to_tree (type, wi::to_wide (ar->min ()) - 1));
+  if (!vrp_val_is_max (ar->max ()))
+    *vr1 = value_range (VR_RANGE, type,
+			wide_int_to_tree (type, wi::to_wide (ar->max ()) + 1),
+			vrp_val_max (type));
+  if (vr0->undefined_p ())
     {
       *vr0 = *vr1;
-      vr1->type = VR_UNDEFINED;
+      vr1->set_undefined (type);
     }
 
-  return vr0->type != VR_UNDEFINED;
+  return !vr0->undefined_p ();
 }
 
 /* Extract the components of a value range into a pair of wide ints in
@@ -961,13 +1143,11 @@ extract_range_into_wide_ints (const value_range *vr,
 			      signop sign, unsigned prec,
 			      wide_int &wmin, wide_int &wmax)
 {
-  if ((vr->type == VR_RANGE
-       || vr->type == VR_ANTI_RANGE)
-      && TREE_CODE (vr->min) == INTEGER_CST
-      && TREE_CODE (vr->max) == INTEGER_CST)
+  gcc_assert (vr->vrtype () != VR_ANTI_RANGE || vr->symbolic_p ());
+  if (range_int_cst_p (vr))
     {
-      wmin = wi::to_wide (vr->min);
-      wmax = wi::to_wide (vr->max);
+      wmin = wi::to_wide (vr->min ());
+      wmax = wi::to_wide (vr->max ());
     }
   else
     {
@@ -994,14 +1174,15 @@ extract_range_from_multiplicative_op (value_range *vr,
 	      || code == ROUND_DIV_EXPR
 	      || code == RSHIFT_EXPR
 	      || code == LSHIFT_EXPR);
-  gcc_assert (vr0->type == VR_RANGE && vr0->type == vr1->type);
+  gcc_assert (vr0->vrtype () == VR_RANGE
+	      && vr0->vrtype () == vr1->vrtype ());
 
-  tree type = TREE_TYPE (vr0->min);
+  tree type = vr0->type ();
   wide_int res_lb, res_ub;
-  wide_int vr0_lb = wi::to_wide (vr0->min);
-  wide_int vr0_ub = wi::to_wide (vr0->max);
-  wide_int vr1_lb = wi::to_wide (vr1->min);
-  wide_int vr1_ub = wi::to_wide (vr1->max);
+  wide_int vr0_lb = wi::to_wide (vr0->min ());
+  wide_int vr0_ub = wi::to_wide (vr0->max ());
+  wide_int vr1_lb = wi::to_wide (vr1->min ());
+  wide_int vr1_ub = wi::to_wide (vr1->max ());
   bool overflow_undefined = TYPE_OVERFLOW_UNDEFINED (type);
   bool overflow_wraps = TYPE_OVERFLOW_WRAPS (type);
   unsigned prec = TYPE_PRECISION (type);
@@ -1010,11 +1191,11 @@ extract_range_from_multiplicative_op (value_range *vr,
 					 code, TYPE_SIGN (type), prec,
 					 vr0_lb, vr0_ub, vr1_lb, vr1_ub,
 					 overflow_undefined, overflow_wraps))
-    set_and_canonicalize_value_range (vr, VR_RANGE,
-				      wide_int_to_tree (type, res_lb),
-				      wide_int_to_tree (type, res_ub), NULL);
+    vr->set_and_canonicalize (VR_RANGE, type,
+			      wide_int_to_tree (type, res_lb),
+			      wide_int_to_tree (type, res_ub), NULL);
   else
-    set_value_range_to_varying (vr);
+    set_value_range_to_varying (vr, type);
 }
 
 /* If BOUND will include a symbolic bound, adjust it accordingly,
@@ -1114,14 +1295,12 @@ set_value_range_with_overflow (value_range &vr,
 {
   const signop sgn = TYPE_SIGN (type);
   const unsigned int prec = TYPE_PRECISION (type);
-  vr.type = VR_RANGE;
-  vr.equiv = NULL;
 
   /* For one bit precision if max < min, then the swapped
      range covers all values.  */
   if (prec == 1 && wi::lt_p (wmax, wmin, sgn))
     {
-      set_value_range_to_varying (&vr);
+      set_value_range_to_varying (&vr, type);
       return;
     }
 
@@ -1133,10 +1312,18 @@ set_value_range_with_overflow (value_range &vr,
       wide_int tmax = wide_int::from (wmax, prec, sgn);
       if ((min_ovf != wi::OVF_NONE) == (max_ovf != wi::OVF_NONE))
 	{
-	  /* No overflow or both overflow or underflow.  The
-	     range kind stays VR_RANGE.  */
-	  vr.min = wide_int_to_tree (type, tmin);
-	  vr.max = wide_int_to_tree (type, tmax);
+	  /* If the limits are swapped, we wrapped around and cover
+	     the entire range.  We have a similar check at the end of
+	     extract_range_from_binary_expr_1.  */
+	  if (wi::gt_p (tmin, tmax, sgn))
+	    vr.set_varying (type);
+	  else
+	    /* No overflow or both overflow or underflow.  The
+	       range kind stays VR_RANGE.  */
+	    vr = value_range (VR_RANGE, type,
+			      wide_int_to_tree (type, tmin),
+			      wide_int_to_tree (type, tmax));
+	  return;
 	}
       else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
 	       || (max_ovf == wi::OVF_OVERFLOW && min_ovf == wi::OVF_NONE))
@@ -1145,7 +1332,6 @@ set_value_range_with_overflow (value_range &vr,
 	     changes to VR_ANTI_RANGE.  */
 	  bool covers = false;
 	  wide_int tem = tmin;
-	  vr.type = VR_ANTI_RANGE;
 	  tmin = tmax + 1;
 	  if (wi::cmp (tmin, tmax, sgn) < 0)
 	    covers = true;
@@ -1157,16 +1343,18 @@ set_value_range_with_overflow (value_range &vr,
 	     types values.  */
 	  if (covers || wi::cmp (tmin, tmax, sgn) > 0)
 	    {
-	      set_value_range_to_varying (&vr);
+	      set_value_range_to_varying (&vr, type);
 	      return;
 	    }
-	  vr.min = wide_int_to_tree (type, tmin);
-	  vr.max = wide_int_to_tree (type, tmax);
+	  vr = value_range (VR_ANTI_RANGE, type,
+			    wide_int_to_tree (type, tmin),
+			    wide_int_to_tree (type, tmax));
+	  return;
 	}
       else
 	{
 	  /* Other underflow and/or overflow, drop to VR_VARYING.  */
-	  set_value_range_to_varying (&vr);
+	  set_value_range_to_varying (&vr, type);
 	  return;
 	}
     }
@@ -1176,19 +1364,21 @@ set_value_range_with_overflow (value_range &vr,
 	 value.  */
       wide_int type_min = wi::min_value (prec, sgn);
       wide_int type_max = wi::max_value (prec, sgn);
+      tree min, max;
       if (min_ovf == wi::OVF_UNDERFLOW)
-	vr.min = wide_int_to_tree (type, type_min);
+	min = wide_int_to_tree (type, type_min);
       else if (min_ovf == wi::OVF_OVERFLOW)
-	vr.min = wide_int_to_tree (type, type_max);
+	min = wide_int_to_tree (type, type_max);
       else
-	vr.min = wide_int_to_tree (type, wmin);
+	min = wide_int_to_tree (type, wmin);
 
       if (max_ovf == wi::OVF_UNDERFLOW)
-	vr.max = wide_int_to_tree (type, type_min);
+	max = wide_int_to_tree (type, type_min);
       else if (max_ovf == wi::OVF_OVERFLOW)
-	vr.max = wide_int_to_tree (type, type_max);
+	max = wide_int_to_tree (type, type_max);
       else
-	vr.max = wide_int_to_tree (type, wmax);
+	max = wide_int_to_tree (type, wmax);
+      vr = value_range (VR_RANGE, type, min, max);
     }
 }
 
@@ -1205,7 +1395,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
   signop sign = TYPE_SIGN (expr_type);
   unsigned int prec = TYPE_PRECISION (expr_type);
   value_range vr0 = *vr0_, vr1 = *vr1_;
-  value_range vrtem0 = VR_INITIALIZER, vrtem1 = VR_INITIALIZER;
+  value_range vrtem0 (expr_type), vrtem1 (expr_type);
   enum value_range_type type;
   tree min = NULL_TREE, max = NULL_TREE;
   int cmp;
@@ -1213,7 +1403,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
   if (!INTEGRAL_TYPE_P (expr_type)
       && !POINTER_TYPE_P (expr_type))
     {
-      set_value_range_to_varying (vr);
+      set_value_range_to_varying (vr, expr_type);
       return;
     }
 
@@ -1237,33 +1427,30 @@ extract_range_from_binary_expr_1 (value_range *vr,
       && code != BIT_IOR_EXPR
       && code != BIT_XOR_EXPR)
     {
-      set_value_range_to_varying (vr);
+      set_value_range_to_varying (vr, expr_type);
       return;
     }
 
   /* If both ranges are UNDEFINED, so is the result.  */
-  if (vr0.type == VR_UNDEFINED && vr1.type == VR_UNDEFINED)
+  if (vr0.undefined_p () && vr1.undefined_p ())
     {
-      set_value_range_to_undefined (vr);
+      set_value_range_to_undefined (vr, expr_type);
       return;
     }
   /* If one of the ranges is UNDEFINED drop it to VARYING for the following
      code.  At some point we may want to special-case operations that
      have UNDEFINED result for all or some value-ranges of the not UNDEFINED
      operand.  */
-  else if (vr0.type == VR_UNDEFINED)
-    set_value_range_to_varying (&vr0);
-  else if (vr1.type == VR_UNDEFINED)
-    set_value_range_to_varying (&vr1);
+  else if (vr0.undefined_p ())
+    set_value_range_to_varying (&vr0, vr0.type ());
+  else if (vr1.undefined_p ())
+    set_value_range_to_varying (&vr1, vr1.type ());
 
   /* We get imprecise results from ranges_from_anti_range when
      code is EXACT_DIV_EXPR.  We could mask out bits in the resulting
-     range, but then we also need to hack up vrp_meet.  It's just
+     range, but then we also need to hack up vrp_union.  It's just
      easier to special case when vr0 is ~[0,0] for EXACT_DIV_EXPR.  */
-  if (code == EXACT_DIV_EXPR
-      && vr0.type == VR_ANTI_RANGE
-      && vr0.min == vr0.max
-      && integer_zerop (vr0.min))
+  if (code == EXACT_DIV_EXPR && range_is_nonnull (&vr0))
     {
       set_value_range_to_nonnull (vr, expr_type);
       return;
@@ -1271,36 +1458,35 @@ extract_range_from_binary_expr_1 (value_range *vr,
 
   /* Now canonicalize anti-ranges to ranges when they are not symbolic
      and express ~[] op X as ([]' op X) U ([]'' op X).  */
-  if (vr0.type == VR_ANTI_RANGE
+  if (vr0.vrtype () == VR_ANTI_RANGE
       && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))
     {
       extract_range_from_binary_expr_1 (vr, code, expr_type, &vrtem0, vr1_);
-      if (vrtem1.type != VR_UNDEFINED)
+      if (!vrtem1.undefined_p ())
 	{
-	  value_range vrres = VR_INITIALIZER;
-	  extract_range_from_binary_expr_1 (&vrres, code, expr_type,
-					    &vrtem1, vr1_);
-	  vrp_meet (vr, &vrres);
+	  value_range vrres (expr_type);
+	  extract_range_from_binary_expr_1 (&vrres, code, expr_type,					    &vrtem1, vr1_);
+	  vr->union_ (&vrres);
 	}
       return;
     }
   /* Likewise for X op ~[].  */
-  if (vr1.type == VR_ANTI_RANGE
+  if (vr1.vrtype () == VR_ANTI_RANGE
       && ranges_from_anti_range (&vr1, &vrtem0, &vrtem1))
     {
       extract_range_from_binary_expr_1 (vr, code, expr_type, vr0_, &vrtem0);
-      if (vrtem1.type != VR_UNDEFINED)
+      if (!vrtem1.undefined_p ())
 	{
-	  value_range vrres = VR_INITIALIZER;
+	  value_range vrres (expr_type);
 	  extract_range_from_binary_expr_1 (&vrres, code, expr_type,
 					    vr0_, &vrtem1);
-	  vrp_meet (vr, &vrres);
+	  vr->union_ (&vrres);
 	}
       return;
     }
 
   /* The type of the resulting value range defaults to VR0.TYPE.  */
-  type = vr0.type;
+  type = vr0.vrtype ();
 
   /* Refuse to operate on VARYING ranges, ranges of different kinds
      and symbolic ranges.  As an exception, we allow BIT_{AND,IOR}
@@ -1323,13 +1509,13 @@ extract_range_from_binary_expr_1 (value_range *vr,
       && code != MINUS_EXPR
       && code != RSHIFT_EXPR
       && code != POINTER_PLUS_EXPR
-      && (vr0.type == VR_VARYING
-	  || vr1.type == VR_VARYING
-	  || vr0.type != vr1.type
-	  || symbolic_range_p (&vr0)
-	  || symbolic_range_p (&vr1)))
+      && (vr0.varying_p ()
+	  || vr1.varying_p ()
+	  || vr0.vrtype () != vr1.vrtype ()
+	  || vr0.symbolic_p ()
+	  || vr1.symbolic_p ()))
     {
-      set_value_range_to_varying (vr);
+      set_value_range_to_varying (vr, expr_type);
       return;
     }
 
@@ -1347,7 +1533,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	  else if (range_is_null (&vr0) && range_is_null (&vr1))
 	    set_value_range_to_null (vr, expr_type);
 	  else
-	    set_value_range_to_varying (vr);
+	    set_value_range_to_varying (vr, expr_type);
 	}
       else if (code == POINTER_PLUS_EXPR)
 	{
@@ -1359,7 +1545,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	  else if (range_is_null (&vr0) && range_is_null (&vr1))
 	    set_value_range_to_null (vr, expr_type);
 	  else
-	    set_value_range_to_varying (vr);
+	    set_value_range_to_varying (vr, expr_type);
 	}
       else if (code == BIT_AND_EXPR)
 	{
@@ -1370,10 +1556,10 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	  else if (range_is_null (&vr0) || range_is_null (&vr1))
 	    set_value_range_to_null (vr, expr_type);
 	  else
-	    set_value_range_to_varying (vr);
+	    set_value_range_to_varying (vr, expr_type);
 	}
       else
-	set_value_range_to_varying (vr);
+	set_value_range_to_varying (vr, expr_type);
 
       return;
     }
@@ -1385,24 +1571,20 @@ extract_range_from_binary_expr_1 (value_range *vr,
       /* This will normalize things such that calculating
 	 [0,0] - VR_VARYING is not dropped to varying, but is
 	 calculated as [MIN+1, MAX].  */
-      if (vr0.type == VR_VARYING)
-	{
-	  vr0.type = VR_RANGE;
-	  vr0.min = vrp_val_min (expr_type);
-	  vr0.max = vrp_val_max (expr_type);
-	}
-      if (vr1.type == VR_VARYING)
-	{
-	  vr1.type = VR_RANGE;
-	  vr1.min = vrp_val_min (expr_type);
-	  vr1.max = vrp_val_max (expr_type);
-	}
+      if (vr0.varying_p ())
+	vr0 = value_range (VR_RANGE, vr0.type (),
+			   vrp_val_min (expr_type),
+			   vrp_val_max (expr_type), vr0.equiv ());
+      if (vr1.varying_p ())
+	vr1 = value_range (VR_RANGE, vr1.type (),
+			   vrp_val_min (expr_type),
+			   vrp_val_max (expr_type), vr0.equiv ());
 
       const bool minus_p = (code == MINUS_EXPR);
-      tree min_op0 = vr0.min;
-      tree min_op1 = minus_p ? vr1.max : vr1.min;
-      tree max_op0 = vr0.max;
-      tree max_op1 = minus_p ? vr1.min : vr1.max;
+      tree min_op0 = vr0.min ();
+      tree min_op1 = minus_p ? vr1.max () : vr1.min ();
+      tree max_op0 = vr0.max ();
+      tree max_op1 = minus_p ? vr1.min () : vr1.max ();
       tree sym_min_op0 = NULL_TREE;
       tree sym_min_op1 = NULL_TREE;
       tree sym_max_op0 = NULL_TREE;
@@ -1415,7 +1597,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	 single-symbolic ranges, try to compute the precise resulting range,
 	 but only if we know that this resulting range will also be constant
 	 or single-symbolic.  */
-      if (vr0.type == VR_RANGE && vr1.type == VR_RANGE
+      if (vr0.vrtype () == VR_RANGE && vr1.vrtype () == VR_RANGE
 	  && (TREE_CODE (min_op0) == INTEGER_CST
 	      || (sym_min_op0
 		  = get_single_symbol (min_op0, &neg_min_op0, &min_op0)))
@@ -1448,28 +1630,26 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	  if (((bool)min_ovf && sym_min_op0 != sym_min_op1)
 	      || ((bool)max_ovf && sym_max_op0 != sym_max_op1))
 	    {
-	      set_value_range_to_varying (vr);
+	      set_value_range_to_varying (vr, expr_type);
 	      return;
 	    }
 
 	  /* Adjust the range for possible overflow.  */
 	  set_value_range_with_overflow (*vr, expr_type,
 					 wmin, wmax, min_ovf, max_ovf);
-	  if (vr->type == VR_VARYING)
+	  if (vr->varying_p ())
 	    return;
 
 	  /* Build the symbolic bounds if needed.  */
-	  adjust_symbolic_bound (vr->min, code, expr_type,
+	  min = vr->min ();
+	  max = vr->max ();
+	  adjust_symbolic_bound (min, code, expr_type,
 				 sym_min_op0, sym_min_op1,
 				 neg_min_op0, neg_min_op1);
-	  adjust_symbolic_bound (vr->max, code, expr_type,
+	  adjust_symbolic_bound (max, code, expr_type,
 				 sym_max_op0, sym_max_op1,
 				 neg_max_op0, neg_max_op1);
-	  /* ?? It would probably be cleaner to eliminate min/max/type
-	     entirely and hold these values in VR directly.  */
-	  min = vr->min;
-	  max = vr->max;
-	  type = vr->type;
+	  type = vr->vrtype ();
 	}
       else
 	{
@@ -1485,7 +1665,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	     a single range or anti-range as the above is
 		 [-INF+1, +INF(OVF)] intersected with ~[5, 5]
 	     but one could use a scheme similar to equivalences for this. */
-	  set_value_range_to_varying (vr);
+	  set_value_range_to_varying (vr, expr_type);
 	  return;
 	}
     }
@@ -1503,7 +1683,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 			 wide_int_to_tree (expr_type, wmin),
 			 wide_int_to_tree (expr_type, wmax), NULL);
       else
-	set_value_range_to_varying (vr);
+	set_value_range_to_varying (vr, expr_type);
       return;
     }
   else if (code == MULT_EXPR)
@@ -1511,7 +1691,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
       if (!range_int_cst_p (&vr0)
 	  || !range_int_cst_p (&vr1))
 	{
-	  set_value_range_to_varying (vr);
+	  set_value_range_to_varying (vr, expr_type);
 	  return;
 	}
       extract_range_from_multiplicative_op (vr, code, &vr0, &vr1);
@@ -1522,19 +1702,21 @@ extract_range_from_binary_expr_1 (value_range *vr,
     {
       if (range_int_cst_p (&vr1)
 	  && !wide_int_range_shift_undefined_p (prec,
-						wi::to_wide (vr1.min),
-						wi::to_wide (vr1.max)))
+						wi::to_wide (vr1.min ()),
+						wi::to_wide (vr1.max ())))
 	{
 	  if (code == RSHIFT_EXPR)
 	    {
 	      /* Even if vr0 is VARYING or otherwise not usable, we can derive
 		 useful ranges just from the shift count.  E.g.
 		 x >> 63 for signed 64-bit x is always [-1, 0].  */
-	      if (vr0.type != VR_RANGE || symbolic_range_p (&vr0))
+	      if (vr0.vrtype () != VR_RANGE || vr0.symbolic_p ())
 		{
-		  vr0.type = type = VR_RANGE;
-		  vr0.min = vrp_val_min (expr_type);
-		  vr0.max = vrp_val_max (expr_type);
+		  type = VR_RANGE;
+		  vr0 = value_range (type, vr0.type (),
+				     vrp_val_min (expr_type),
+				     vrp_val_max (expr_type),
+				     vr0.equiv ());
 		}
 	      extract_range_from_multiplicative_op (vr, code, &vr0, &vr1);
 	      return;
@@ -1544,22 +1726,22 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	    {
 	      wide_int res_lb, res_ub;
 	      if (wide_int_range_lshift (res_lb, res_ub, sign, prec,
-					 wi::to_wide (vr0.min),
-					 wi::to_wide (vr0.max),
-					 wi::to_wide (vr1.min),
-					 wi::to_wide (vr1.max),
+					 wi::to_wide (vr0.min ()),
+					 wi::to_wide (vr0.max ()),
+					 wi::to_wide (vr1.min ()),
+					 wi::to_wide (vr1.max ()),
 					 TYPE_OVERFLOW_UNDEFINED (expr_type),
 					 TYPE_OVERFLOW_WRAPS (expr_type)))
 		{
 		  min = wide_int_to_tree (expr_type, res_lb);
 		  max = wide_int_to_tree (expr_type, res_ub);
-		  set_and_canonicalize_value_range (vr, VR_RANGE,
-						    min, max, NULL);
+		  vr->set_and_canonicalize (VR_RANGE, expr_type, min, max,
+					    NULL);
 		  return;
 		}
 	    }
 	}
-      set_value_range_to_varying (vr);
+      set_value_range_to_varying (vr, expr_type);
       return;
     }
   else if (code == TRUNC_DIV_EXPR
@@ -1575,7 +1757,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
       /* Special case explicit division by zero as undefined.  */
       if (range_is_null (&vr1))
 	{
-	  set_value_range_to_undefined (vr);
+	  set_value_range_to_undefined (vr, expr_type);
 	  return;
 	}
 
@@ -1597,7 +1779,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 			       TYPE_OVERFLOW_WRAPS (expr_type),
 			       extra_range_p, extra_min, extra_max))
 	{
-	  set_value_range_to_varying (vr);
+	  set_value_range_to_varying (vr, expr_type);
 	  return;
 	}
       set_value_range (vr, VR_RANGE,
@@ -1605,11 +1787,11 @@ extract_range_from_binary_expr_1 (value_range *vr,
 		       wide_int_to_tree (expr_type, wmax), NULL);
       if (extra_range_p)
 	{
-	  value_range extra_range = VR_INITIALIZER;
+	  value_range extra_range (expr_type);
 	  set_value_range (&extra_range, VR_RANGE,
 			   wide_int_to_tree (expr_type, extra_min),
 			   wide_int_to_tree (expr_type, extra_max), NULL);
-	  vrp_meet (vr, &extra_range);
+	  vr->union_ (&extra_range);
 	}
       return;
     }
@@ -1617,7 +1799,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
     {
       if (range_is_null (&vr1))
 	{
-	  set_value_range_to_undefined (vr);
+	  set_value_range_to_undefined (vr, expr_type);
 	  return;
 	}
       wide_int wmin, wmax, tmp;
@@ -1658,7 +1840,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	      set_value_range (vr, VR_RANGE, min, max, NULL);
 	    }
 	  else
-	    set_value_range_to_varying (vr);
+	    set_value_range_to_varying (vr, expr_type);
 	  return;
 	}
       else if (code == BIT_IOR_EXPR)
@@ -1676,7 +1858,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	      set_value_range (vr, VR_RANGE, min, max, NULL);
 	    }
 	  else
-	    set_value_range_to_varying (vr);
+	    set_value_range_to_varying (vr, expr_type);
 	  return;
 	}
       else if (code == BIT_XOR_EXPR)
@@ -1692,7 +1874,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
 	      set_value_range (vr, VR_RANGE, min, max, NULL);
 	    }
 	  else
-	    set_value_range_to_varying (vr);
+	    set_value_range_to_varying (vr, expr_type);
 	  return;
 	}
     }
@@ -1706,7 +1888,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
       || max == NULL_TREE
       || TREE_OVERFLOW_P (max))
     {
-      set_value_range_to_varying (vr);
+      set_value_range_to_varying (vr, expr_type);
       return;
     }
 
@@ -1715,7 +1897,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
      Note that we do accept [-INF, -INF] and [+INF, +INF].  */
   if (vrp_val_is_min (min) && vrp_val_is_max (max))
     {
-      set_value_range_to_varying (vr);
+      set_value_range_to_varying (vr, expr_type);
       return;
     }
 
@@ -1725,7 +1907,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
       /* If the new range has its limits swapped around (MIN > MAX),
 	 then the operation caused one of them to wrap around, mark
 	 the new range VARYING.  */
-      set_value_range_to_varying (vr);
+      set_value_range_to_varying (vr, expr_type);
     }
   else
     set_value_range (vr, type, min, max, NULL);
@@ -1742,7 +1924,9 @@ extract_range_from_unary_expr (value_range *vr,
 {
   signop sign = TYPE_SIGN (type);
   unsigned int prec = TYPE_PRECISION (type);
-  value_range vr0 = *vr0_, vrtem0 = VR_INITIALIZER, vrtem1 = VR_INITIALIZER;
+  value_range vr0 = *vr0_;
+  value_range vrtem0 (vr0.type ());
+  value_range vrtem1 (vr0.type ());
 
   /* VRP only operates on integral and pointer types.  */
   if (!(INTEGRAL_TYPE_P (op0_type)
@@ -1750,14 +1934,14 @@ extract_range_from_unary_expr (value_range *vr,
       || !(INTEGRAL_TYPE_P (type)
 	   || POINTER_TYPE_P (type)))
     {
-      set_value_range_to_varying (vr);
+      set_value_range_to_varying (vr, type);
       return;
     }
 
   /* If VR0 is UNDEFINED, so is the result.  */
-  if (vr0.type == VR_UNDEFINED)
+  if (vr0.undefined_p ())
     {
-      set_value_range_to_undefined (vr);
+      set_value_range_to_undefined (vr, type);
       return;
     }
 
@@ -1772,7 +1956,7 @@ extract_range_from_unary_expr (value_range *vr,
     {
       /* -X is simply 0 - X, so re-use existing code that also handles
          anti-ranges fine.  */
-      value_range zero = VR_INITIALIZER;
+      value_range zero (type);
       set_value_range_to_value (&zero, build_int_cst (type, 0), NULL);
       extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &zero, &vr0);
       return;
@@ -1781,7 +1965,7 @@ extract_range_from_unary_expr (value_range *vr,
     {
       /* ~X is simply -1 - X, so re-use existing code that also handles
          anti-ranges fine.  */
-      value_range minusone = VR_INITIALIZER;
+      value_range minusone (type);
       set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL);
       extract_range_from_binary_expr_1 (vr, MINUS_EXPR,
 					type, &minusone, &vr0);
@@ -1790,16 +1974,16 @@ extract_range_from_unary_expr (value_range *vr,
 
   /* Now canonicalize anti-ranges to ranges when they are not symbolic
      and express op ~[]  as (op []') U (op []'').  */
-  if (vr0.type == VR_ANTI_RANGE
+  if (vr0.vrtype () == VR_ANTI_RANGE
       && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))
     {
       extract_range_from_unary_expr (vr, code, type, &vrtem0, op0_type);
-      if (vrtem1.type != VR_UNDEFINED)
+      if (!vrtem1.undefined_p ())
 	{
-	  value_range vrres = VR_INITIALIZER;
+	  value_range vrres (type);
 	  extract_range_from_unary_expr (&vrres, code, type,
 					 &vrtem1, op0_type);
-	  vrp_meet (vr, &vrres);
+	  vr->union_ (&vrres);
 	}
       return;
     }
@@ -1823,7 +2007,7 @@ extract_range_from_unary_expr (value_range *vr,
 	  else if (range_is_null (&vr0))
 	    set_value_range_to_null (vr, type);
 	  else
-	    set_value_range_to_varying (vr);
+	    set_value_range_to_varying (vr, type);
 	  return;
 	}
 
@@ -1831,8 +2015,8 @@ extract_range_from_unary_expr (value_range *vr,
 	 pointer anti-ranges.  Any remaining anti-ranges at this point
 	 will be integer conversions from SSA names that will be
 	 normalized into VARYING.  For instance: ~[x_55, x_55].  */
-      gcc_assert (vr0.type != VR_ANTI_RANGE
-		  || TREE_CODE (vr0.min) != INTEGER_CST);
+      gcc_assert (vr0.vrtype () != VR_ANTI_RANGE
+		  || TREE_CODE (vr0.min ()) != INTEGER_CST);
 
       /* NOTES: Previously we were returning VARYING for all symbolics, but
 	 we can do better by treating them as [-MIN, +MAX].  For
@@ -1855,10 +2039,10 @@ extract_range_from_unary_expr (value_range *vr,
 	{
 	  tree min = wide_int_to_tree (outer_type, wmin);
 	  tree max = wide_int_to_tree (outer_type, wmax);
-	  set_and_canonicalize_value_range (vr, VR_RANGE, min, max, NULL);
+	  vr->set_and_canonicalize (VR_RANGE, outer_type, min, max, NULL);
 	}
       else
-	set_value_range_to_varying (vr);
+	set_value_range_to_varying (vr, outer_type);
       return;
     }
   else if (code == ABS_EXPR)
@@ -1872,12 +2056,12 @@ extract_range_from_unary_expr (value_range *vr,
 			 wide_int_to_tree (type, wmin),
 			 wide_int_to_tree (type, wmax), NULL);
       else
-	set_value_range_to_varying (vr);
+	set_value_range_to_varying (vr, type);
       return;
     }
 
   /* For unhandled operations fall back to varying.  */
-  set_value_range_to_varying (vr);
+  set_value_range_to_varying (vr, type);
   return;
 }
 
@@ -1897,39 +2081,39 @@ dump_value_range (FILE *file, const value_range *vr)
 {
   if (vr == NULL)
     fprintf (file, "[]");
-  else if (vr->type == VR_UNDEFINED)
+  else if (vr->undefined_p ())
     fprintf (file, "UNDEFINED");
-  else if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
+  else if (vr->vrtype () == VR_RANGE || vr->vrtype () == VR_ANTI_RANGE)
     {
-      tree type = TREE_TYPE (vr->min);
+      tree type = TREE_TYPE (vr->min ());
 
-      fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");
+      fprintf (file, "%s[", (vr->vrtype () == VR_ANTI_RANGE) ? "~" : "");
 
       if (INTEGRAL_TYPE_P (type)
 	  && !TYPE_UNSIGNED (type)
-	  && vrp_val_is_min (vr->min))
+	  && vrp_val_is_min (vr->min ()))
 	fprintf (file, "-INF");
       else
-	print_generic_expr (file, vr->min);
+	print_generic_expr (file, vr->min ());
 
       fprintf (file, ", ");
 
       if (INTEGRAL_TYPE_P (type)
-	  && vrp_val_is_max (vr->max))
+	  && vrp_val_is_max (vr->max ()))
 	fprintf (file, "+INF");
       else
-	print_generic_expr (file, vr->max);
+	print_generic_expr (file, vr->max ());
 
       fprintf (file, "]");
 
-      if (vr->equiv)
+      if (vr->equiv ())
 	{
 	  bitmap_iterator bi;
 	  unsigned i, c = 0;
 
 	  fprintf (file, "  EQUIVALENCES: { ");
 
-	  EXECUTE_IF_SET_IN_BITMAP (vr->equiv, 0, i, bi)
+	  EXECUTE_IF_SET_IN_BITMAP (vr->equiv (), 0, i, bi)
 	    {
 	      print_generic_expr (file, ssa_name (i));
 	      fprintf (file, " ");
@@ -1939,7 +2123,7 @@ dump_value_range (FILE *file, const value_range *vr)
 	  fprintf (file, "} (%u elements)", c);
 	}
     }
-  else if (vr->type == VR_VARYING)
+  else if (vr->varying_p ())
     fprintf (file, "VARYING");
   else
     fprintf (file, "INVALID RANGE");
@@ -1951,14 +2135,7 @@ dump_value_range (FILE *file, const value_range *vr)
 DEBUG_FUNCTION void
 debug_value_range (const value_range *vr)
 {
-  dump_value_range (stderr, vr);
-  fprintf (stderr, "\n");
-}
-
-void
-value_range::dump () const
-{
-  debug_value_range (this);
+  vr->dump ();
 }
 
 
@@ -4202,14 +4379,14 @@ vrp_prop::check_array_ref (location_t location, tree ref,
   if (TREE_CODE (low_sub) == SSA_NAME)
     {
       vr = get_value_range (low_sub);
-      if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
+      if (!vr->undefined_p () && !vr->varying_p ())
         {
-          low_sub = vr->type == VR_RANGE ? vr->max : vr->min;
-          up_sub = vr->type == VR_RANGE ? vr->min : vr->max;
+          low_sub = vr->vrtype () == VR_RANGE ? vr->max () : vr->min ();
+          up_sub = vr->vrtype () == VR_RANGE ? vr->min () : vr->max ();
         }
     }
 
-  if (vr && vr->type == VR_ANTI_RANGE)
+  if (vr && vr->vrtype () == VR_ANTI_RANGE)
     {
       if (up_bound
 	  && TREE_CODE (up_sub) == INTEGER_CST
@@ -4337,21 +4514,20 @@ vrp_prop::check_mem_ref (location_t location, tree ref,
 	break;
 
       vr = get_value_range (varoff);
-      if (!vr || vr->type == VR_UNDEFINED || !vr->min || !vr->max)
+      if (!vr || vr->undefined_p () || vr->varying_p ())
 	break;
 
-      if (TREE_CODE (vr->min) != INTEGER_CST
-          || TREE_CODE (vr->max) != INTEGER_CST)
+      if (!vr->numeric_p ())
         break;
 
-      if (vr->type == VR_RANGE)
+      if (vr->vrtype () == VR_RANGE)
 	{
-	  if (tree_int_cst_lt (vr->min, vr->max))
+	  if (tree_int_cst_lt (vr->min (), vr->max ()))
 	    {
 	      offset_int min
-		= wi::to_offset (fold_convert (ptrdiff_type_node, vr->min));
+		= wi::to_offset (fold_convert (ptrdiff_type_node, vr->min ()));
 	      offset_int max
-		= wi::to_offset (fold_convert (ptrdiff_type_node, vr->max));
+		= wi::to_offset (fold_convert (ptrdiff_type_node, vr->max ()));
 	      if (min < max)
 		{
 		  offrange[0] += min;
@@ -4969,7 +5145,8 @@ vrp_prop::vrp_initialize ()
 	  if (!stmt_interesting_for_vrp (phi))
 	    {
 	      tree lhs = PHI_RESULT (phi);
-	      set_value_range_to_varying (get_value_range (lhs));
+	      set_value_range_to_varying (get_value_range (lhs),
+					  TREE_TYPE (lhs));
 	      prop_set_simulate_again (phi, false);
 	    }
 	  else
@@ -5123,8 +5300,8 @@ find_case_label_range (gswitch *stmt, tree min, tree max, size_t *min_idx,
 enum ssa_prop_result
 vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
 {
-  value_range vr = VR_INITIALIZER;
   tree lhs = gimple_get_lhs (stmt);
+  value_range vr (lhs ? TREE_TYPE (lhs) : NULL);
   extract_range_from_stmt (stmt, taken_edge_p, output_p, &vr);
 
   if (*output_p)
@@ -5140,7 +5317,7 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
 	      fprintf (dump_file, "\n");
 	    }
 
-	  if (vr.type == VR_VARYING)
+	  if (vr.varying_p ())
 	    return SSA_PROP_VARYING;
 
 	  return SSA_PROP_INTERESTING;
@@ -5164,7 +5341,8 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
 	    use_operand_p use_p;
 	    enum ssa_prop_result res = SSA_PROP_VARYING;
 
-	    set_value_range_to_varying (get_value_range (lhs));
+	    set_value_range_to_varying (get_value_range (lhs),
+					TREE_TYPE (lhs));
 
 	    FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
 	      {
@@ -5193,17 +5371,14 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
 		   SSA_PROP_NOT_INTERESTING.  If there are no
 		   {REAL,IMAG}PART_EXPR uses at all,
 		   return SSA_PROP_VARYING.  */
-		value_range new_vr = VR_INITIALIZER;
+		value_range new_vr (TREE_TYPE (lhs));
 		extract_range_basic (&new_vr, use_stmt);
 		const value_range *old_vr = get_value_range (use_lhs);
-		if (old_vr->type != new_vr.type
-		    || !vrp_operand_equal_p (old_vr->min, new_vr.min)
-		    || !vrp_operand_equal_p (old_vr->max, new_vr.max)
-		    || !vrp_bitmap_equal_p (old_vr->equiv, new_vr.equiv))
+		if (*old_vr != new_vr)
 		  res = SSA_PROP_INTERESTING;
 		else
 		  res = SSA_PROP_NOT_INTERESTING;
-		BITMAP_FREE (new_vr.equiv);
+		new_vr.equiv_free ();
 		if (res == SSA_PROP_INTERESTING)
 		  {
 		    *output_p = lhs;
@@ -5814,8 +5989,6 @@ intersect_ranges (enum value_range_type *vr0type,
       *vr0min = vr1min;
       *vr0max = vr1max;
     }
-
-  return;
 }
 
 
@@ -5823,14 +5996,12 @@ intersect_ranges (enum value_range_type *vr0type,
    in *VR0.  This may not be the smallest possible such range.  */
 
 static void
-vrp_intersect_ranges_1 (value_range *vr0, const value_range *vr1)
+vrp_intersect_1 (value_range *vr0, const value_range *vr1)
 {
-  value_range saved;
-
   /* If either range is VR_VARYING the other one wins.  */
-  if (vr1->type == VR_VARYING)
+  if (vr1->varying_p ())
     return;
-  if (vr0->type == VR_VARYING)
+  if (vr0->varying_p ())
     {
       copy_value_range (vr0, vr1);
       return;
@@ -5838,49 +6009,53 @@ vrp_intersect_ranges_1 (value_range *vr0, const value_range *vr1)
 
   /* When either range is VR_UNDEFINED the resulting range is
      VR_UNDEFINED, too.  */
-  if (vr0->type == VR_UNDEFINED)
+  if (vr0->undefined_p ())
     return;
-  if (vr1->type == VR_UNDEFINED)
+  if (vr1->undefined_p ())
     {
-      set_value_range_to_undefined (vr0);
+      set_value_range_to_undefined (vr0, vr0->type ());
       return;
     }
 
   /* Save the original vr0 so we can return it as conservative intersection
      result when our worker turns things to varying.  */
-  saved = *vr0;
-  intersect_ranges (&vr0->type, &vr0->min, &vr0->max,
-		    vr1->type, vr1->min, vr1->max);
+  value_range saved (*vr0);
+
+  value_range_type vr0type = vr0->vrtype ();
+  tree vr0min = vr0->min ();
+  tree vr0max = vr0->max ();
+  intersect_ranges (&vr0type, &vr0min, &vr0max,
+		    vr1->vrtype (), vr1->min (), vr1->max ());
   /* Make sure to canonicalize the result though as the inversion of a
      VR_RANGE can still be a VR_RANGE.  */
-  set_and_canonicalize_value_range (vr0, vr0->type,
-				    vr0->min, vr0->max, vr0->equiv);
+  vr0->set_and_canonicalize (vr0type, vr0->type (), vr0min, vr0max,
+			     vr0->equiv ());
   /* If that failed, use the saved original VR0.  */
-  if (vr0->type == VR_VARYING)
+  if (vr0->varying_p ())
     {
       *vr0 = saved;
       return;
     }
   /* If the result is VR_UNDEFINED there is no need to mess with
      the equivalencies.  */
-  if (vr0->type == VR_UNDEFINED)
+  if (vr0->undefined_p ())
     return;
 
   /* The resulting set of equivalences for range intersection is the union of
      the two sets.  */
-  if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
-    bitmap_ior_into (vr0->equiv, vr1->equiv);
-  else if (vr1->equiv && !vr0->equiv)
+  if (vr0->equiv () && vr1->equiv () && vr0->equiv () != vr1->equiv ())
+    vr0->equiv_ior (vr1);
+  else if (vr1->equiv () && !vr0->equiv ())
     {
       /* All equivalence bitmaps are allocated from the same obstack.  So
 	 we can use the obstack associated with VR to allocate vr0->equiv.  */
-      vr0->equiv = BITMAP_ALLOC (vr1->equiv->obstack);
-      bitmap_copy (vr0->equiv, vr1->equiv);
+      vr0->set_equiv (BITMAP_ALLOC (vr1->equiv ()->obstack));
+      vr0->equiv_copy (vr1);
     }
 }
 
-void
-vrp_intersect_ranges (value_range *vr0, const value_range *vr1)
+static void
+vrp_intersect (value_range *vr0, const value_range *vr1)
 {
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -5890,7 +6065,7 @@ vrp_intersect_ranges (value_range *vr0, const value_range *vr1)
       dump_value_range (dump_file, vr1);
       fprintf (dump_file, "\n");
     }
-  vrp_intersect_ranges_1 (vr0, vr1);
+  vrp_intersect_1 (vr0, vr1);
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "to\n  ");
@@ -5904,38 +6079,40 @@ vrp_intersect_ranges (value_range *vr0, const value_range *vr1)
    may not be the smallest possible such range.  */
 
 static void
-vrp_meet_1 (value_range *vr0, const value_range *vr1)
+vrp_union_1 (value_range *vr0, const value_range *vr1)
 {
-  value_range saved;
-
-  if (vr0->type == VR_UNDEFINED)
+  if (vr0->undefined_p ())
     {
-      set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr1->equiv);
+      vr0->copy_with_equiv_update (vr1);
       return;
     }
 
-  if (vr1->type == VR_UNDEFINED)
+  if (vr1->undefined_p ())
     {
       /* VR0 already has the resulting range.  */
       return;
     }
 
-  if (vr0->type == VR_VARYING)
+  if (vr0->varying_p ())
     {
       /* Nothing to do.  VR0 already has the resulting range.  */
       return;
     }
 
-  if (vr1->type == VR_VARYING)
+  if (vr1->varying_p ())
     {
-      set_value_range_to_varying (vr0);
+      set_value_range_to_varying (vr0, vr0->type ());
       return;
     }
 
-  saved = *vr0;
-  union_ranges (&vr0->type, &vr0->min, &vr0->max,
-		vr1->type, vr1->min, vr1->max);
-  if (vr0->type == VR_VARYING)
+  value_range saved (*vr0);
+  value_range_type vr0type = vr0->vrtype ();
+  tree vr0min = vr0->min ();
+  tree vr0max = vr0->max ();
+  union_ranges (&vr0type, &vr0min, &vr0max,
+		vr1->vrtype (), vr1->min (), vr1->max ());
+  *vr0 = value_range (vr0type, vr0->type (), vr0min, vr0max);
+  if (vr0->varying_p ())
     {
       /* Failed to find an efficient meet.  Before giving up and setting
 	 the result to VARYING, see if we can at least derive a useful
@@ -5943,33 +6120,32 @@ vrp_meet_1 (value_range *vr0, const value_range *vr1)
       if (range_includes_zero_p (&saved) == 0
 	  && range_includes_zero_p (vr1) == 0)
 	{
-	  set_value_range_to_nonnull (vr0, TREE_TYPE (saved.min));
+	  set_value_range_to_nonnull (vr0, saved.type ());
 
 	  /* Since this meet operation did not result from the meeting of
 	     two equivalent names, VR0 cannot have any equivalences.  */
-	  if (vr0->equiv)
-	    bitmap_clear (vr0->equiv);
+	  vr0->equiv_clear ();
 	  return;
 	}
 
-      set_value_range_to_varying (vr0);
+      set_value_range_to_varying (vr0, vr0->type ());
       return;
     }
-  set_and_canonicalize_value_range (vr0, vr0->type, vr0->min, vr0->max,
-				    vr0->equiv);
-  if (vr0->type == VR_VARYING)
+  vr0->set_and_canonicalize (vr0->vrtype (), vr0->type (),
+			     vr0->min (), vr0->max (), vr0->equiv ());
+  if (vr0->varying_p ())
     return;
 
   /* The resulting set of equivalences is always the intersection of
      the two sets.  */
-  if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
-    bitmap_and_into (vr0->equiv, vr1->equiv);
-  else if (vr0->equiv && !vr1->equiv)
-    bitmap_clear (vr0->equiv);
+  if (vr0->equiv () != vr1->equiv ())
+    vr0->equiv_and (vr1);
+  else if (!vr1->equiv ())
+    vr0->equiv_clear ();
 }
 
-void
-vrp_meet (value_range *vr0, const value_range *vr1)
+static void
+vrp_union (value_range *vr0, const value_range *vr1)
 {
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -5979,7 +6155,7 @@ vrp_meet (value_range *vr0, const value_range *vr1)
       dump_value_range (dump_file, vr1);
       fprintf (dump_file, "\n");
     }
-  vrp_meet_1 (vr0, vr1);
+  vrp_union_1 (vr0, vr1);
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "to\n  ");
@@ -5988,7 +6164,6 @@ vrp_meet (value_range *vr0, const value_range *vr1)
     }
 }
 
-
 /* Visit all arguments for PHI node PHI that flow through executable
    edges.  If a valid value range can be derived from all the incoming
    value ranges, set a new range for the LHS of PHI.  */
@@ -5997,7 +6172,7 @@ enum ssa_prop_result
 vrp_prop::visit_phi (gphi *phi)
 {
   tree lhs = PHI_RESULT (phi);
-  value_range vr_result = VR_INITIALIZER;
+  value_range vr_result (TREE_TYPE (lhs));
   extract_range_from_phi_node (phi, &vr_result);
   if (update_value_range (lhs, &vr_result))
     {
@@ -6010,7 +6185,7 @@ vrp_prop::visit_phi (gphi *phi)
 	  fprintf (dump_file, "\n");
 	}
 
-      if (vr_result.type == VR_VARYING)
+      if (vr_result.varying_p ())
 	return SSA_PROP_VARYING;
 
       return SSA_PROP_INTERESTING;
@@ -6194,16 +6369,17 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
       op = lhs_of_dominating_assert (op, bb, stmt);
 
       const value_range *vr = vr_values->get_value_range (op);
-      if ((vr->type != VR_RANGE && vr->type != VR_ANTI_RANGE)
-	  || symbolic_range_p (vr))
+      if (vr->undefined_p ()
+	  || vr->varying_p ()
+	  || vr->symbolic_p ())
 	return NULL_TREE;
 
-      if (vr->type == VR_RANGE)
+      if (vr->vrtype () == VR_RANGE)
 	{
 	  size_t i, j;
 	  /* Get the range of labels that contain a part of the operand's
 	     value range.  */
-	  find_case_label_range (switch_stmt, vr->min, vr->max, &i, &j);
+	  find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j);
 
 	  /* Is there only one such label?  */
 	  if (i == j)
@@ -6213,10 +6389,11 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
 	      /* The i'th label will be taken only if the value range of the
 		 operand is entirely within the bounds of this label.  */
 	      if (CASE_HIGH (label) != NULL_TREE
-		  ? (tree_int_cst_compare (CASE_LOW (label), vr->min) <= 0
-		     && tree_int_cst_compare (CASE_HIGH (label), vr->max) >= 0)
-		  : (tree_int_cst_equal (CASE_LOW (label), vr->min)
-		     && tree_int_cst_equal (vr->min, vr->max)))
+		  ? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0
+		     && tree_int_cst_compare (CASE_HIGH (label),
+					      vr->max ()) >= 0)
+		  : (tree_int_cst_equal (CASE_LOW (label), vr->min ())
+		     && tree_int_cst_equal (vr->min (), vr->max ())))
 		return label;
 	    }
 
@@ -6226,7 +6403,7 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
 	    return gimple_switch_label (switch_stmt, 0);
 	}
 
-      if (vr->type == VR_ANTI_RANGE)
+      if (vr->vrtype () == VR_ANTI_RANGE)
 	{
 	  unsigned n = gimple_switch_num_labels (switch_stmt);
 	  tree min_label = gimple_switch_label (switch_stmt, 1);
@@ -6235,10 +6412,12 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
 	  /* The default label will be taken only if the anti-range of the
 	     operand is entirely outside the bounds of all the (non-default)
 	     case labels.  */
-	  if (tree_int_cst_compare (vr->min, CASE_LOW (min_label)) <= 0
+	  if (tree_int_cst_compare (vr->min (), CASE_LOW (min_label)) <= 0
 	      && (CASE_HIGH (max_label) != NULL_TREE
-		  ? tree_int_cst_compare (vr->max, CASE_HIGH (max_label)) >= 0
-		  : tree_int_cst_compare (vr->max, CASE_LOW (max_label)) >= 0))
+		  ? tree_int_cst_compare (vr->max (),
+					  CASE_HIGH (max_label)) >= 0
+		  : tree_int_cst_compare (vr->max (),
+					  CASE_LOW (max_label)) >= 0))
 	  return gimple_switch_label (switch_stmt, 0);
 	}
 
@@ -6255,11 +6434,12 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
 	{
 	  edge dummy_e;
 	  tree dummy_tree;
-	  value_range new_vr = VR_INITIALIZER;
+	  value_range new_vr (TREE_TYPE (lhs));
 	  vr_values->extract_range_from_stmt (stmt, &dummy_e,
 					      &dummy_tree, &new_vr);
-	  if (range_int_cst_singleton_p (&new_vr))
-	    return new_vr.min;
+	  tree singleton = new_vr.singleton ();
+	  if (singleton)
+	    return singleton;
 	}
     }
 
@@ -6431,20 +6611,16 @@ vrp_prop::vrp_finalize (bool warn_array_bounds_p)
 	continue;
 
       const value_range *vr = get_value_range (name);
-      if (!name
-	  || (vr->type == VR_VARYING)
-	  || (vr->type == VR_UNDEFINED)
-	  || (TREE_CODE (vr->min) != INTEGER_CST)
-	  || (TREE_CODE (vr->max) != INTEGER_CST))
+      if (!name || !vr->numeric_p ())
 	continue;
 
       if (POINTER_TYPE_P (TREE_TYPE (name))
 	  && range_includes_zero_p (vr) == 0)
 	set_ptr_nonnull (name);
       else if (!POINTER_TYPE_P (TREE_TYPE (name)))
-	set_range_info (name, vr->type,
-			wi::to_wide (vr->min),
-			wi::to_wide (vr->max));
+	set_range_info (name, vr->vrtype (),
+			wi::to_wide (vr->min ()),
+			wi::to_wide (vr->max ()));
     }
 
   /* If we're checking array refs, we want to merge information on
@@ -6636,7 +6812,8 @@ determine_value_range_1 (value_range *vr, tree expr)
 {
   if (BINARY_CLASS_P (expr))
     {
-      value_range vr0 = VR_INITIALIZER, vr1 = VR_INITIALIZER;
+      value_range vr0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
+      value_range vr1 (TREE_TYPE (TREE_OPERAND (expr, 1)));
       determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
       determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1));
       extract_range_from_binary_expr_1 (vr, TREE_CODE (expr), TREE_TYPE (expr),
@@ -6644,7 +6821,7 @@ determine_value_range_1 (value_range *vr, tree expr)
     }
   else if (UNARY_CLASS_P (expr))
     {
-      value_range vr0 = VR_INITIALIZER;
+      value_range vr0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
       determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
       extract_range_from_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
 				     &vr0, TREE_TYPE (TREE_OPERAND (expr, 0)));
@@ -6663,7 +6840,7 @@ determine_value_range_1 (value_range *vr, tree expr)
 	set_value_range (vr, kind, wide_int_to_tree (TREE_TYPE (expr), min),
 			 wide_int_to_tree (TREE_TYPE (expr), max), NULL);
       else
-	set_value_range_to_varying (vr);
+	set_value_range_to_varying (vr, TREE_TYPE (expr));
     }
 }
 
@@ -6673,15 +6850,13 @@ determine_value_range_1 (value_range *vr, tree expr)
 value_range_type
 determine_value_range (tree expr, wide_int *min, wide_int *max)
 {
-  value_range vr = VR_INITIALIZER;
+  value_range vr (TREE_TYPE (expr));
   determine_value_range_1 (&vr, expr);
-  if ((vr.type == VR_RANGE
-       || vr.type == VR_ANTI_RANGE)
-      && !symbolic_range_p (&vr))
+  if (vr.numeric_p ())
     {
-      *min = wi::to_wide (vr.min);
-      *max = wi::to_wide (vr.max);
-      return vr.type;
+      *min = wi::to_wide (vr.min ());
+      *max = wi::to_wide (vr.max ());
+      return vr.vrtype ();
     }
 
   return VR_VARYING;
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index 655cf055f0a..04e0d0cb4a6 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -27,35 +27,140 @@ enum value_range_type { VR_UNDEFINED, VR_RANGE,
 
 /* Range of values that can be associated with an SSA_NAME after VRP
    has executed.  */
-struct GTY((for_user)) value_range
+class GTY((for_user)) value_range
 {
-  /* Lattice value represented by this range.  */
-  enum value_range_type type;
+ public:
+  value_range ();
+  value_range (tree type);
+  value_range (value_range_type, tree type, tree, tree, bitmap = NULL);
+  bool operator== (const value_range &) const;
+  bool operator!= (const value_range &) const;
+  void intersect (const value_range *);
+  void union_ (const value_range *);
+  /* Like operator== but ignore equivalence bitmap.  */
+  bool ignore_equivs_equal_p (const value_range &) const;
+  /* Like a operator= but update equivalence bitmap efficiently.  */
+  void copy_with_equiv_update (const value_range *);
+
+  /* Types of value ranges.  */
+  bool undefined_p () const;
+  bool varying_p () const;
+  bool symbolic_p () const;
+  bool numeric_p () const;
+  void set_undefined (tree = NULL);
+  void set_varying (tree = NULL);
+
+  /* Equivalence bitmap methods.  */
+  bitmap equiv () const;
+  void set_equiv (bitmap);
+  void equiv_free ();
+  void equiv_copy (const value_range *);
+  void equiv_clear ();
+  void equiv_and (const value_range *);
+  void equiv_ior (const value_range *);
+
+  /* Misc methods.  */
+  tree type () const;
+  bool null_p () const;
+  bool may_contain_p (tree) const;
+  tree singleton () const;
+  void set_and_canonicalize (enum value_range_type, tree, tree, tree, bitmap);
+  void dump () const;
 
-  /* Minimum and maximum values represented by this range.  These
-     values should be interpreted as follows:
+  /* Temporary accessors that should eventually be removed.  */
+  enum value_range_type vrtype () const;
+  tree min () const;
+  tree max () const;
+
+ private:
+  void set (value_range_type, tree type, tree, tree, bitmap);
+  void check ();
+  bool equal_p (const value_range &, bool ignore_equivs) const;
+
+  enum value_range_type m_vrtype;
+ public:
+  /* These should be private, but GTY is a piece of crap.  */
+  tree m_min;
+  tree m_max;
+  tree m_type;
+  /* Set of SSA names whose value ranges are equivalent to this one.
+     This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE.  */
+  bitmap m_equiv;
+};
 
-	- If TYPE is VR_UNDEFINED or VR_VARYING then MIN and MAX must
-	  be NULL.
+inline
+value_range::value_range ()
+{
+  m_type = m_min = m_max = NULL;
+  m_vrtype = VR_UNDEFINED;
+  m_equiv = NULL;
+}
 
-	- If TYPE == VR_RANGE then MIN holds the minimum value and
-	  MAX holds the maximum value of the range [MIN, MAX].
+inline
+value_range::value_range (tree type)
+{
+  m_vrtype = VR_UNDEFINED;
+  m_min = m_max = NULL;
+  m_equiv = NULL;
+  m_type = type;
+}
+
+inline value_range_type
+value_range::vrtype () const
+{
+  return m_vrtype;
+}
 
-	- If TYPE == ANTI_RANGE the variable is known to NOT
-	  take any values in the range [MIN, MAX].  */
-  tree min;
-  tree max;
+inline tree
+value_range::type () const
+{
+  return m_type;
+}
 
-  /* Set of SSA names whose value ranges are equivalent to this one.
-     This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE.  */
-  bitmap equiv;
+inline bitmap
+value_range::equiv () const
+{
+  return m_equiv;
+}
 
-  /* Dump value range to stderr.  */
-  void dump () const;
-};
+inline tree
+value_range::min () const
+{
+  return m_min;
+}
+
+inline tree
+value_range::max () const
+{
+  return m_max;
+}
+
+inline bool
+value_range::varying_p () const
+{
+  return m_vrtype == VR_VARYING;
+}
+
+inline bool
+value_range::undefined_p () const
+{
+  return m_vrtype == VR_UNDEFINED;
+}
+
+inline void
+value_range::set_equiv (bitmap b)
+{
+  m_equiv = b;
+}
+
+inline bool
+value_range::null_p () const
+{
+  return (m_vrtype == VR_RANGE
+	  && integer_zerop (m_min)
+	  && integer_zerop (m_max));
+}
 
-extern void vrp_intersect_ranges (value_range *vr0, const value_range *vr1);
-extern void vrp_meet (value_range *vr0, const value_range *vr1);
 extern void dump_value_range (FILE *, const value_range *);
 extern void extract_range_from_unary_expr (value_range *vr,
 					   enum tree_code code,
@@ -85,19 +190,17 @@ struct assert_info
 extern void register_edge_assert_for (tree, edge, enum tree_code,
 				      tree, tree, vec<assert_info> &);
 extern bool stmt_interesting_for_vrp (gimple *);
-extern void set_value_range_to_varying (value_range *);
+extern void set_value_range_to_varying (value_range *, tree);
 extern bool range_includes_zero_p (const value_range *);
 extern bool infer_value_range (gimple *, tree, tree_code *, tree *);
 
 extern void set_value_range_to_nonnull (value_range *, tree);
 extern void set_value_range (value_range *, enum value_range_type, tree,
 			     tree, bitmap);
-extern void set_and_canonicalize_value_range (value_range *,
-					      enum value_range_type,
-					      tree, tree, bitmap);
+extern void set_value_range (value_range *, tree, enum value_range_type, tree,
+			     tree, bitmap);
 extern bool vrp_bitmap_equal_p (const_bitmap, const_bitmap);
 extern tree value_range_constant_singleton (const value_range *);
-extern bool symbolic_range_p (const value_range *);
 extern int compare_values (tree, tree);
 extern int compare_values_warnv (tree, tree, bool *);
 extern bool vrp_val_is_min (const_tree);
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 32392a11618..984cc16ddc0 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -55,7 +55,7 @@ static inline void
 set_value_range_to_nonnegative (value_range *vr, tree type)
 {
   tree zero = build_int_cst (type, 0);
-  set_value_range (vr, VR_RANGE, zero, vrp_val_max (type), vr->equiv);
+  set_value_range (vr, VR_RANGE, zero, vrp_val_max (type), vr->equiv ());
 }
 
 /* Set value range VR to a range of a truthvalue of type TYPE.  */
@@ -64,11 +64,11 @@ static inline void
 set_value_range_to_truthvalue (value_range *vr, tree type)
 {
   if (TYPE_PRECISION (type) == 1)
-    set_value_range_to_varying (vr);
+    set_value_range_to_varying (vr, type);
   else
     set_value_range (vr, VR_RANGE,
 		     build_int_cst (type, 0), build_int_cst (type, 1),
-		     vr->equiv);
+		     vr->equiv ());
 }
 
 
@@ -80,8 +80,8 @@ set_value_range_to_truthvalue (value_range *vr, tree type)
 value_range *
 vr_values::get_value_range (const_tree var)
 {
-  static const value_range vr_const_varying
-    = { VR_VARYING, NULL_TREE, NULL_TREE, NULL };
+  static const value_range vr_const_varying (VR_VARYING, TREE_TYPE (var),
+					     NULL, NULL);
   value_range *vr;
   tree sym;
   unsigned ver = SSA_NAME_VERSION (var);
@@ -106,10 +106,7 @@ vr_values::get_value_range (const_tree var)
 
   /* Create a default value range.  */
   vr_value[ver] = vr = vrp_value_range_pool.allocate ();
-  memset (vr, 0, sizeof (*vr));
-
-  /* Defer allocating the equivalence set.  */
-  vr->equiv = NULL;
+  *vr = value_range (TREE_TYPE (var));
 
   /* If VAR is a default definition of a parameter, the variable can
      take any value in VAR's type.  */
@@ -135,10 +132,10 @@ vr_values::get_value_range (const_tree var)
 				 wide_int_to_tree (TREE_TYPE (var), max),
 				 NULL);
 	      else
-		set_value_range_to_varying (vr);
+		set_value_range_to_varying (vr, TREE_TYPE (var));
 	    }
 	  else
-	    set_value_range_to_varying (vr);
+	    set_value_range_to_varying (vr, TREE_TYPE (sym));
 	}
       else if (TREE_CODE (sym) == RESULT_DECL
 	       && DECL_BY_REFERENCE (sym))
@@ -159,8 +156,8 @@ vr_values::set_defs_to_varying (gimple *stmt)
     {
       value_range *vr = get_value_range (def);
       /* Avoid writing to vr_const_varying get_value_range may return.  */
-      if (vr->type != VR_VARYING)
-	set_value_range_to_varying (vr);
+      if (!vr->varying_p ())
+	set_value_range_to_varying (vr, vr->type ());
     }
 }
 
@@ -191,18 +188,19 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
 	  tree nr_min, nr_max;
 	  nr_min = wide_int_to_tree (TREE_TYPE (var), min);
 	  nr_max = wide_int_to_tree (TREE_TYPE (var), max);
-	  value_range nr = VR_INITIALIZER;
-	  set_and_canonicalize_value_range (&nr, rtype, nr_min, nr_max, NULL);
-	  vrp_intersect_ranges (new_vr, &nr);
+	  value_range nr (TREE_TYPE (var));
+	  nr.set_and_canonicalize (rtype, TREE_TYPE (var), nr_min, nr_max,
+				   NULL);
+	  new_vr->intersect (&nr);
 	}
     }
 
   /* Update the value range, if necessary.  */
   old_vr = get_value_range (var);
-  is_new = old_vr->type != new_vr->type
-	   || !vrp_operand_equal_p (old_vr->min, new_vr->min)
-	   || !vrp_operand_equal_p (old_vr->max, new_vr->max)
-	   || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv);
+  is_new = old_vr->vrtype () != new_vr->vrtype ()
+	   || !vrp_operand_equal_p (old_vr->min (), new_vr->min ())
+	   || !vrp_operand_equal_p (old_vr->max (), new_vr->max ())
+	   || !vrp_bitmap_equal_p (old_vr->equiv (), new_vr->equiv ());
 
   if (is_new)
     {
@@ -212,19 +210,20 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
 	 the same.  We may not have is_new when transitioning to
 	 UNDEFINED.  If old_vr->type is VARYING, we shouldn't be
 	 called.  */
-      if (new_vr->type == VR_UNDEFINED)
+      if (new_vr->undefined_p ())
 	{
-	  BITMAP_FREE (new_vr->equiv);
-	  set_value_range_to_varying (old_vr);
-	  set_value_range_to_varying (new_vr);
+	  new_vr->equiv_free ();
+	  set_value_range_to_varying (old_vr, TREE_TYPE (var));
+	  set_value_range_to_varying (new_vr, TREE_TYPE (var));
 	  return true;
 	}
       else
-	set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
-			 new_vr->equiv);
+	set_value_range (old_vr, new_vr->type (), new_vr->vrtype (),
+			 new_vr->min (), new_vr->max (),
+			 new_vr->equiv ());
     }
 
-  BITMAP_FREE (new_vr->equiv);
+  new_vr->equiv_free ();
 
   return is_new;
 }
@@ -233,17 +232,19 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
 /* Add VAR and VAR's equivalence set to EQUIV.  This is the central
    point where equivalence processing can be turned on/off.  */
 
-void
-vr_values::add_equivalence (bitmap *equiv, const_tree var)
+bitmap
+vr_values::add_equivalence (bitmap equiv, const_tree var)
 {
   unsigned ver = SSA_NAME_VERSION (var);
   value_range *vr = get_value_range (var);
+  bitmap ret = equiv;
 
-  if (*equiv == NULL)
-    *equiv = BITMAP_ALLOC (&vrp_equiv_obstack);
-  bitmap_set_bit (*equiv, ver);
-  if (vr && vr->equiv)
-    bitmap_ior_into (*equiv, vr->equiv);
+  if (ret == NULL)
+    ret = BITMAP_ALLOC (&vrp_equiv_obstack);
+  bitmap_set_bit (ret, ver);
+  if (vr && vr->equiv ())
+    bitmap_ior_into (ret, vr->equiv ());
+  return ret;
 }
 
 /* Return true if value range VR involves exactly one symbol SYM.  */
@@ -254,16 +255,16 @@ symbolic_range_based_on_p (value_range *vr, const_tree sym)
   bool neg, min_has_symbol, max_has_symbol;
   tree inv;
 
-  if (is_gimple_min_invariant (vr->min))
+  if (is_gimple_min_invariant (vr->min ()))
     min_has_symbol = false;
-  else if (get_single_symbol (vr->min, &neg, &inv) == sym)
+  else if (get_single_symbol (vr->min (), &neg, &inv) == sym)
     min_has_symbol = true;
   else
     return false;
 
-  if (is_gimple_min_invariant (vr->max))
+  if (is_gimple_min_invariant (vr->max ()))
     max_has_symbol = false;
-  else if (get_single_symbol (vr->max, &neg, &inv) == sym)
+  else if (get_single_symbol (vr->max (), &neg, &inv) == sym)
     max_has_symbol = true;
   else
     return false;
@@ -403,9 +404,9 @@ vr_values::op_with_boolean_value_range_p (tree op)
     return false;
 
   vr = get_value_range (op);
-  return (vr->type == VR_RANGE
-	  && integer_zerop (vr->min)
-	  && integer_onep (vr->max));
+  return (vr->vrtype () == VR_RANGE
+	  && integer_zerop (vr->min ())
+	  && integer_onep (vr->max ()));
 }
 
 /* Extract value range information for VAR when (OP COND_CODE LIMIT) is
@@ -427,7 +428,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
   if ((POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
       || limit == var)
     {
-      set_value_range_to_varying (vr_p);
+      set_value_range_to_varying (vr_p, type);
       return;
     }
 
@@ -438,12 +439,13 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 
   /* LIMIT's range is only interesting if it has any useful information.  */
   if (! limit_vr
-      || limit_vr->type == VR_UNDEFINED
-      || limit_vr->type == VR_VARYING
-      || (symbolic_range_p (limit_vr)
-	  && ! (limit_vr->type == VR_RANGE
-		&& (limit_vr->min == limit_vr->max
-		    || operand_equal_p (limit_vr->min, limit_vr->max, 0)))))
+      || limit_vr->undefined_p ()
+      || limit_vr->varying_p ()
+      || (limit_vr->symbolic_p ()
+	  && ! (limit_vr->vrtype () == VR_RANGE
+		&& (limit_vr->min () == limit_vr->max ()
+		    || operand_equal_p (limit_vr->min (),
+					limit_vr->max (), 0)))))
     limit_vr = NULL;
 
   /* Initially, the new range has the same set of equivalences of
@@ -451,8 +453,8 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
      value.  Since assertions may be chained via mutually exclusive
      predicates, we will need to trim the set of equivalences before
      we are done.  */
-  gcc_assert (vr_p->equiv == NULL);
-  add_equivalence (&vr_p->equiv, var);
+  gcc_assert (vr_p->equiv () == NULL);
+  vr_p->set_equiv (add_equivalence (vr_p->equiv (), var));
 
   /* Extract a new range based on the asserted comparison for VAR and
      LIMIT's value range.  Notice that if LIMIT has an anti-range, we
@@ -488,14 +490,14 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
       max = force_fit_type (TREE_TYPE (var), wi::to_widest (max), 0, false);
 
       /* We can transform a max, min range to an anti-range or
-         vice-versa.  Use set_and_canonicalize_value_range which does
-	 this for us.  */
+         vice-versa.  Use set_and_canonicalize which does this for
+         us.  */
       if (cond_code == LE_EXPR)
-        set_and_canonicalize_value_range (vr_p, VR_RANGE,
-					  min, max, vr_p->equiv);
+        vr_p->set_and_canonicalize (VR_RANGE, TREE_TYPE (min), min, max,
+				    vr_p->equiv ());
       else if (cond_code == GT_EXPR)
-        set_and_canonicalize_value_range (vr_p, VR_ANTI_RANGE,
-					  min, max, vr_p->equiv);
+        vr_p->set_and_canonicalize (VR_ANTI_RANGE, TREE_TYPE (min), min, max,
+				    vr_p->equiv ());
       else
 	gcc_unreachable ();
     }
@@ -505,9 +507,9 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 
       if (limit_vr)
 	{
-	  range_type = limit_vr->type;
-	  min = limit_vr->min;
-	  max = limit_vr->max;
+	  range_type = limit_vr->vrtype ();
+	  min = limit_vr->min ();
+	  max = limit_vr->max ();
 	}
       else
 	{
@@ -516,13 +518,13 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 	  max = limit;
 	}
 
-      set_value_range (vr_p, range_type, min, max, vr_p->equiv);
+      set_value_range (vr_p, range_type, min, max, vr_p->equiv ());
 
       /* When asserting the equality VAR == LIMIT and LIMIT is another
 	 SSA name, the new range will also inherit the equivalence set
 	 from LIMIT.  */
       if (TREE_CODE (limit) == SSA_NAME)
-	add_equivalence (&vr_p->equiv, limit);
+	vr_p->set_equiv (add_equivalence (vr_p->equiv (), limit));
     }
   else if (cond_code == NE_EXPR)
     {
@@ -547,11 +549,11 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 	 (i.e., LIMIT_VR->MIN == LIMIT_VR->MAX).  In that case,
 	 build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX].  */
       if (limit_vr
-	  && limit_vr->type == VR_RANGE
-	  && compare_values (limit_vr->min, limit_vr->max) == 0)
+	  && limit_vr->vrtype () == VR_RANGE
+	  && compare_values (limit_vr->min (), limit_vr->max ()) == 0)
 	{
-	  min = limit_vr->min;
-	  max = limit_vr->max;
+	  min = limit_vr->min ();
+	  max = limit_vr->max ();
 	}
       else
 	{
@@ -567,21 +569,21 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 	  && vrp_val_is_max (max))
 	min = max = limit;
 
-      set_and_canonicalize_value_range (vr_p, VR_ANTI_RANGE,
-					min, max, vr_p->equiv);
+      vr_p->set_and_canonicalize (VR_ANTI_RANGE, TREE_TYPE (min), min, max,
+				  vr_p->equiv ());
     }
   else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
     {
       min = TYPE_MIN_VALUE (type);
 
-      if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
+      if (limit_vr == NULL || limit_vr->vrtype () == VR_ANTI_RANGE)
 	max = limit;
       else
 	{
 	  /* If LIMIT_VR is of the form [N1, N2], we need to build the
 	     range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for
 	     LT_EXPR.  */
-	  max = limit_vr->max;
+	  max = limit_vr->max ();
 	}
 
       /* If the maximum value forces us to be out of bounds, simply punt.
@@ -589,7 +591,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 	 all should be optimized away above us.  */
       if (cond_code == LT_EXPR
 	  && compare_values (max, min) == 0)
-	set_value_range_to_varying (vr_p);
+	set_value_range_to_varying (vr_p, type);
       else
 	{
 	  /* For LT_EXPR, we create the range [MIN, MAX - 1].  */
@@ -607,21 +609,21 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 		TREE_NO_WARNING (max) = 1;
 	    }
 
-	  set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
+	  set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv ());
 	}
     }
   else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
     {
       max = TYPE_MAX_VALUE (type);
 
-      if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
+      if (limit_vr == NULL || limit_vr->vrtype () == VR_ANTI_RANGE)
 	min = limit;
       else
 	{
 	  /* If LIMIT_VR is of the form [N1, N2], we need to build the
 	     range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for
 	     GT_EXPR.  */
-	  min = limit_vr->min;
+	  min = limit_vr->min ();
 	}
 
       /* If the minimum value forces us to be out of bounds, simply punt.
@@ -629,7 +631,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 	 all should be optimized away above us.  */
       if (cond_code == GT_EXPR
 	  && compare_values (min, max) == 0)
-	set_value_range_to_varying (vr_p);
+	set_value_range_to_varying (vr_p, type);
       else
 	{
 	  /* For GT_EXPR, we create the range [MIN + 1, MAX].  */
@@ -647,14 +649,14 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
 		TREE_NO_WARNING (min) = 1;
 	    }
 
-	  set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
+	  set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv ());
 	}
     }
   else
     gcc_unreachable ();
 
   /* Finally intersect the new range with what we already know about var.  */
-  vrp_intersect_ranges (vr_p, get_value_range (var));
+  vr_p->intersect (get_value_range (var));
 }
 
 /* Extract value range information from an ASSERT_EXPR EXPR and store
@@ -711,12 +713,12 @@ vr_values::extract_range_from_ssa_name (value_range *vr, tree var)
 {
   value_range *var_vr = get_value_range (var);
 
-  if (var_vr->type != VR_VARYING)
+  if (!var_vr->varying_p ())
     copy_value_range (vr, var_vr);
   else
     set_value_range (vr, VR_RANGE, var, var, NULL);
 
-  add_equivalence (&vr->equiv, var);
+  vr->set_equiv (add_equivalence (vr->equiv (), var));
 }
 
 /* Extract range information from a binary expression OP0 CODE OP1 based on
@@ -728,8 +730,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
 					   enum tree_code code,
 					   tree expr_type, tree op0, tree op1)
 {
-  value_range vr0 = VR_INITIALIZER;
-  value_range vr1 = VR_INITIALIZER;
+  value_range vr0 (expr_type), vr1 (expr_type);
 
   /* Get value ranges for each operand.  For constant operands, create
      a new value range with the operand to simplify processing.  */
@@ -738,32 +739,28 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
   else if (is_gimple_min_invariant (op0))
     set_value_range_to_value (&vr0, op0, NULL);
   else
-    set_value_range_to_varying (&vr0);
+    set_value_range_to_varying (&vr0, expr_type);
 
   if (TREE_CODE (op1) == SSA_NAME)
     vr1 = *(get_value_range (op1));
   else if (is_gimple_min_invariant (op1))
     set_value_range_to_value (&vr1, op1, NULL);
   else
-    set_value_range_to_varying (&vr1);
+    set_value_range_to_varying (&vr1, expr_type);
 
   /* If one argument is varying, we can sometimes still deduce a
      range for the output: any + [3, +INF] is in [MIN+3, +INF].  */
   if (INTEGRAL_TYPE_P (TREE_TYPE (op0))
       && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
     {
-      if (vr0.type == VR_VARYING && vr1.type != VR_VARYING)
-	{
-	  vr0.type = VR_RANGE;
-	  vr0.min = vrp_val_min (expr_type);
-	  vr0.max = vrp_val_max (expr_type);
-	}
-      else if (vr1.type == VR_VARYING && vr0.type != VR_VARYING)
-	{
-	  vr1.type = VR_RANGE;
-	  vr1.min = vrp_val_min (expr_type);
-	  vr1.max = vrp_val_max (expr_type);
-	}
+      if (vr0.varying_p () && !vr1.varying_p ())
+	vr0 = value_range (VR_RANGE, vr0.type (),
+			   vrp_val_min (expr_type),
+			   vrp_val_max (expr_type));
+      else if (vr1.varying_p () && !vr0.varying_p ())
+	vr1 = value_range (VR_RANGE, vr1.type (),
+			   vrp_val_min (expr_type),
+			   vrp_val_max (expr_type));
     }
 
   extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1);
@@ -773,7 +770,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
      n = def - arg
      Here the range for n can be set to [0, PTRDIFF_MAX - 1]. */
 
-  if (vr->type == VR_VARYING
+  if (vr->varying_p ()
       && code == POINTER_DIFF_EXPR
       && TREE_CODE (op0) == SSA_NAME
       && TREE_CODE (op1) == SSA_NAME)
@@ -806,21 +803,21 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
      symbolic comparison.  When a bound of the range of the first operand
      is invariant, we set the corresponding bound of the new range to INF
      in order to avoid recursing on the range of the second operand.  */
-  if (vr->type == VR_VARYING
+  if (vr->varying_p ()
       && (code == PLUS_EXPR || code == MINUS_EXPR)
       && TREE_CODE (op1) == SSA_NAME
-      && vr0.type == VR_RANGE
+      && vr0.vrtype () == VR_RANGE
       && symbolic_range_based_on_p (&vr0, op1))
     {
       const bool minus_p = (code == MINUS_EXPR);
-      value_range n_vr1 = VR_INITIALIZER;
+      value_range n_vr1 (expr_type);
 
       /* Try with VR0 and [-INF, OP1].  */
-      if (is_gimple_min_invariant (minus_p ? vr0.max : vr0.min))
+      if (is_gimple_min_invariant (minus_p ? vr0.max () : vr0.min ()))
 	set_value_range (&n_vr1, VR_RANGE, vrp_val_min (expr_type), op1, NULL);
 
       /* Try with VR0 and [OP1, +INF].  */
-      else if (is_gimple_min_invariant (minus_p ? vr0.min : vr0.max))
+      else if (is_gimple_min_invariant (minus_p ? vr0.min () : vr0.max ()))
 	set_value_range (&n_vr1, VR_RANGE, op1, vrp_val_max (expr_type), NULL);
 
       /* Try with VR0 and [OP1, OP1].  */
@@ -830,21 +827,21 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
       extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &n_vr1);
     }
 
-  if (vr->type == VR_VARYING
+  if (vr->varying_p ()
       && (code == PLUS_EXPR || code == MINUS_EXPR)
       && TREE_CODE (op0) == SSA_NAME
-      && vr1.type == VR_RANGE
+      && vr1.vrtype () == VR_RANGE
       && symbolic_range_based_on_p (&vr1, op0))
     {
       const bool minus_p = (code == MINUS_EXPR);
-      value_range n_vr0 = VR_INITIALIZER;
+      value_range n_vr0 (expr_type);
 
       /* Try with [-INF, OP0] and VR1.  */
-      if (is_gimple_min_invariant (minus_p ? vr1.max : vr1.min))
+      if (is_gimple_min_invariant (minus_p ? vr1.max () : vr1.min ()))
 	set_value_range (&n_vr0, VR_RANGE, vrp_val_min (expr_type), op0, NULL);
 
       /* Try with [OP0, +INF] and VR1.  */
-      else if (is_gimple_min_invariant (minus_p ? vr1.min : vr1.max))
+      else if (is_gimple_min_invariant (minus_p ? vr1.min (): vr1.max ()))
 	set_value_range (&n_vr0, VR_RANGE, op0, vrp_val_max (expr_type), NULL);
 
       /* Try with [OP0, OP0] and VR1.  */
@@ -858,15 +855,15 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
      op1's range is ~[op0,op0] or vice-versa, then we
      can derive a non-null range.  This happens often for
      pointer subtraction.  */
-  if (vr->type == VR_VARYING
+  if (vr->varying_p ()
       && (code == MINUS_EXPR || code == POINTER_DIFF_EXPR)
       && TREE_CODE (op0) == SSA_NAME
-      && ((vr0.type == VR_ANTI_RANGE
-	   && vr0.min == op1
-	   && vr0.min == vr0.max)
-	  || (vr1.type == VR_ANTI_RANGE
-	      && vr1.min == op0
-	      && vr1.min == vr1.max)))
+      && ((vr0.vrtype () == VR_ANTI_RANGE
+	   && vr0.min () == op1
+	   && vr0.min () == vr0.max ())
+	  || (vr1.vrtype () == VR_ANTI_RANGE
+	      && vr1.min () == op0
+	      && vr1.min () == vr1.max ())))
       set_value_range_to_nonnull (vr, expr_type);
 }
 
@@ -878,7 +875,7 @@ void
 vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
 					  tree type, tree op0)
 {
-  value_range vr0 = VR_INITIALIZER;
+  value_range vr0 (TREE_TYPE (op0));
 
   /* Get value ranges for the operand.  For constant operands, create
      a new value range with the operand to simplify processing.  */
@@ -887,7 +884,7 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
   else if (is_gimple_min_invariant (op0))
     set_value_range_to_value (&vr0, op0, NULL);
   else
-    set_value_range_to_varying (&vr0);
+    set_value_range_to_varying (&vr0, TREE_TYPE (op0));
 
   ::extract_range_from_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0));
 }
@@ -899,31 +896,29 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
 void
 vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
 {
-  tree op0, op1;
-  value_range vr0 = VR_INITIALIZER;
-  value_range vr1 = VR_INITIALIZER;
-
   /* Get value ranges for each operand.  For constant operands, create
      a new value range with the operand to simplify processing.  */
-  op0 = gimple_assign_rhs2 (stmt);
+  tree op0 = gimple_assign_rhs2 (stmt);
+  value_range vr0 (TREE_TYPE (op0));
   if (TREE_CODE (op0) == SSA_NAME)
     vr0 = *(get_value_range (op0));
   else if (is_gimple_min_invariant (op0))
     set_value_range_to_value (&vr0, op0, NULL);
   else
-    set_value_range_to_varying (&vr0);
+    set_value_range_to_varying (&vr0, TREE_TYPE (op0));
 
-  op1 = gimple_assign_rhs3 (stmt);
+  tree op1 = gimple_assign_rhs3 (stmt);
+  value_range vr1 (TREE_TYPE (op1));
   if (TREE_CODE (op1) == SSA_NAME)
     vr1 = *(get_value_range (op1));
   else if (is_gimple_min_invariant (op1))
     set_value_range_to_value (&vr1, op1, NULL);
   else
-    set_value_range_to_varying (&vr1);
+    set_value_range_to_varying (&vr1, TREE_TYPE (op1));
 
   /* The resulting value range is the union of the operand ranges */
   copy_value_range (vr, &vr0);
-  vrp_meet (vr, &vr1);
+  vr->union_ (&vr1);
 }
 
 
@@ -946,9 +941,9 @@ vr_values::extract_range_from_comparison (value_range *vr, enum tree_code code,
 	 type.  */
       val = fold_convert (type, val);
       if (is_gimple_min_invariant (val))
-	set_value_range_to_value (vr, val, vr->equiv);
+	set_value_range_to_value (vr, val, vr->equiv ());
       else
-	set_value_range (vr, VR_RANGE, val, val, vr->equiv);
+	set_value_range (vr, VR_RANGE, val, val, vr->equiv ());
     }
   else
     /* The result of a comparison is always true or false.  */
@@ -965,45 +960,47 @@ bool
 vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
 					 tree op0, tree op1, bool *ovf)
 {
-  value_range vr0 = VR_INITIALIZER;
-  value_range vr1 = VR_INITIALIZER;
+  value_range vr0 (type);
+  value_range vr1 (type);
   if (TREE_CODE (op0) == SSA_NAME)
     vr0 = *get_value_range (op0);
   else if (TREE_CODE (op0) == INTEGER_CST)
     set_value_range_to_value (&vr0, op0, NULL);
   else
-    set_value_range_to_varying (&vr0);
+    set_value_range_to_varying (&vr0, TREE_TYPE (op0));
 
   if (TREE_CODE (op1) == SSA_NAME)
     vr1 = *get_value_range (op1);
   else if (TREE_CODE (op1) == INTEGER_CST)
     set_value_range_to_value (&vr1, op1, NULL);
   else
-    set_value_range_to_varying (&vr1);
+    set_value_range_to_varying (&vr1, TREE_TYPE (op1));
 
+  tree vr0min = vr0.min (), vr0max = vr0.max ();
+  tree vr1min = vr1.min (), vr1max = vr1.max ();
   if (!range_int_cst_p (&vr0)
-      || TREE_OVERFLOW (vr0.min)
-      || TREE_OVERFLOW (vr0.max))
+      || TREE_OVERFLOW (vr0min)
+      || TREE_OVERFLOW (vr0max))
     {
-      vr0.min = vrp_val_min (TREE_TYPE (op0));
-      vr0.max = vrp_val_max (TREE_TYPE (op0));
+      vr0min = vrp_val_min (TREE_TYPE (op0));
+      vr0max = vrp_val_max (TREE_TYPE (op0));
     }
   if (!range_int_cst_p (&vr1)
-      || TREE_OVERFLOW (vr1.min)
-      || TREE_OVERFLOW (vr1.max))
+      || TREE_OVERFLOW (vr1min)
+      || TREE_OVERFLOW (vr1max))
     {
-      vr1.min = vrp_val_min (TREE_TYPE (op1));
-      vr1.max = vrp_val_max (TREE_TYPE (op1));
+      vr1min = vrp_val_min (TREE_TYPE (op1));
+      vr1max = vrp_val_max (TREE_TYPE (op1));
     }
-  *ovf = arith_overflowed_p (subcode, type, vr0.min,
-			     subcode == MINUS_EXPR ? vr1.max : vr1.min);
-  if (arith_overflowed_p (subcode, type, vr0.max,
-			  subcode == MINUS_EXPR ? vr1.min : vr1.max) != *ovf)
+  *ovf = arith_overflowed_p (subcode, type, vr0min,
+			     subcode == MINUS_EXPR ? vr1max : vr1min);
+  if (arith_overflowed_p (subcode, type, vr0max,
+			  subcode == MINUS_EXPR ? vr1min : vr1max) != *ovf)
     return false;
   if (subcode == MULT_EXPR)
     {
-      if (arith_overflowed_p (subcode, type, vr0.min, vr1.max) != *ovf
-	  || arith_overflowed_p (subcode, type, vr0.max, vr1.min) != *ovf)
+      if (arith_overflowed_p (subcode, type, vr0min, vr1max) != *ovf
+	  || arith_overflowed_p (subcode, type, vr0max, vr1min) != *ovf)
 	return false;
     }
   if (*ovf)
@@ -1016,10 +1013,10 @@ vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
       widest_int wmin, wmax;
       widest_int w[4];
       int i;
-      w[0] = wi::to_widest (vr0.min);
-      w[1] = wi::to_widest (vr0.max);
-      w[2] = wi::to_widest (vr1.min);
-      w[3] = wi::to_widest (vr1.max);
+      w[0] = wi::to_widest (vr0min);
+      w[1] = wi::to_widest (vr0max);
+      w[2] = wi::to_widest (vr1min);
+      w[3] = wi::to_widest (vr1max);
       for (i = 0; i < 4; i++)
 	{
 	  widest_int wt;
@@ -1113,11 +1110,11 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
 		mini = 1;
 	      /* If some high bits are known to be zero,
 		 we can decrease the maximum.  */
-	      if (vr0->type == VR_RANGE
-		  && TREE_CODE (vr0->max) == INTEGER_CST
-		  && !operand_less_p (vr0->min,
-				      build_zero_cst (TREE_TYPE (vr0->min))))
-		maxi = tree_floor_log2 (vr0->max) + 1;
+	      if (vr0->vrtype () == VR_RANGE
+		  && TREE_CODE (vr0->max ()) == INTEGER_CST
+		  && !operand_less_p (vr0->min (),
+				      build_zero_cst (TREE_TYPE (vr0->min ()))))
+		maxi = tree_floor_log2 (vr0->max ()) + 1;
 	    }
 	  goto bitop_builtin;
 	  /* __builtin_parity* returns [0, 1].  */
@@ -1148,15 +1145,15 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
 	      value_range *vr0 = get_value_range (arg);
 	      /* From clz of VR_RANGE minimum we can compute
 		 result maximum.  */
-	      if (vr0->type == VR_RANGE
-		  && TREE_CODE (vr0->min) == INTEGER_CST)
+	      if (vr0->vrtype () == VR_RANGE
+		  && TREE_CODE (vr0->min ()) == INTEGER_CST)
 		{
-		  maxi = prec - 1 - tree_floor_log2 (vr0->min);
+		  maxi = prec - 1 - tree_floor_log2 (vr0->min ());
 		  if (maxi != prec)
 		    mini = 0;
 		}
-	      else if (vr0->type == VR_ANTI_RANGE
-		       && integer_zerop (vr0->min))
+	      else if (vr0->vrtype () == VR_ANTI_RANGE
+		       && integer_zerop (vr0->min ()))
 		{
 		  maxi = prec - 1;
 		  mini = 0;
@@ -1165,10 +1162,10 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
 		break;
 	      /* From clz of VR_RANGE maximum we can compute
 		 result minimum.  */
-	      if (vr0->type == VR_RANGE
-		  && TREE_CODE (vr0->max) == INTEGER_CST)
+	      if (vr0->vrtype () == VR_RANGE
+		  && TREE_CODE (vr0->max ()) == INTEGER_CST)
 		{
-		  mini = prec - 1 - tree_floor_log2 (vr0->max);
+		  mini = prec - 1 - tree_floor_log2 (vr0->max ());
 		  if (mini == prec)
 		    break;
 		}
@@ -1204,20 +1201,20 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
 	    {
 	      value_range *vr0 = get_value_range (arg);
 	      /* If arg is non-zero, then use [0, prec - 1].  */
-	      if ((vr0->type == VR_RANGE
-		   && integer_nonzerop (vr0->min))
-		  || (vr0->type == VR_ANTI_RANGE
-		      && integer_zerop (vr0->min)))
+	      if ((vr0->vrtype () == VR_RANGE
+		   && integer_nonzerop (vr0->min ()))
+		  || (vr0->vrtype () == VR_ANTI_RANGE
+		      && integer_zerop (vr0->min ())))
 		{
 		  mini = 0;
 		  maxi = prec - 1;
 		}
 	      /* If some high bits are known to be zero,
 		 we can decrease the result maximum.  */
-	      if (vr0->type == VR_RANGE
-		  && TREE_CODE (vr0->max) == INTEGER_CST)
+	      if (vr0->vrtype () == VR_RANGE
+		  && TREE_CODE (vr0->max ()) == INTEGER_CST)
 		{
-		  maxi = tree_floor_log2 (vr0->max);
+		  maxi = tree_floor_log2 (vr0->max ());
 		  /* For vr0 [0, 0] give up.  */
 		  if (maxi == -1)
 		    break;
@@ -1302,10 +1299,10 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
 	     this should have been already folded and if not, it
 	     wasn't folded because of overflow.  Avoid removing the
 	     UBSAN_CHECK_* calls in that case.  */
-	  if (vr->type == VR_RANGE
-	      && (vr->min == vr->max
-		  || operand_equal_p (vr->min, vr->max, 0)))
-	    set_value_range_to_varying (vr);
+	  if (vr->vrtype () == VR_RANGE
+	      && (vr->min () == vr->max ()
+		  || operand_equal_p (vr->min (), vr->max (), 0)))
+	    set_value_range_to_varying (vr, vr->type ());
 	  return;
 	}
     }
@@ -1363,7 +1360,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
 						  NULL);
 		      else if (TYPE_PRECISION (type) == 1
 			       && !TYPE_UNSIGNED (type))
-			set_value_range_to_varying (vr);
+			set_value_range_to_varying (vr, type);
 		      else
 			set_value_range (vr, VR_RANGE, build_int_cst (type, 0),
 					 build_int_cst (type, 1), NULL);
@@ -1381,8 +1378,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
 		    }
 		  else
 		    {
-		      value_range vr0 = VR_INITIALIZER;
-		      value_range vr1 = VR_INITIALIZER;
+		      value_range vr0 (type), vr1 (type);
 		      bool saved_flag_wrapv = flag_wrapv;
 		      /* Pretend the arithmetics is wrapping.  If there is
 			 any overflow, IMAGPART_EXPR will be set.  */
@@ -1406,7 +1402,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
   else if (vrp_stmt_computes_nonzero (stmt))
     set_value_range_to_nonnull (vr, type);
   else
-    set_value_range_to_varying (vr);
+    set_value_range_to_varying (vr, type);
 }
 
 
@@ -1442,9 +1438,12 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt)
 	   && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
     set_value_range_to_value (vr, gimple_assign_rhs1 (stmt), NULL);
   else
-    set_value_range_to_varying (vr);
+    {
+      tree type = TREE_TYPE (gimple_assign_lhs (stmt));
+      set_value_range_to_varying (vr, type);
+    }
 
-  if (vr->type == VR_VARYING)
+  if (vr->varying_p ())
     extract_range_basic (vr, stmt);
 }
 
@@ -1467,18 +1466,18 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
 		bool *strict_overflow_p)
 {
   /* VARYING or UNDEFINED ranges cannot be compared.  */
-  if (vr0->type == VR_VARYING
-      || vr0->type == VR_UNDEFINED
-      || vr1->type == VR_VARYING
-      || vr1->type == VR_UNDEFINED)
+  if (vr0->varying_p ()
+      || vr0->undefined_p ()
+      || vr1->varying_p ()
+      || vr1->undefined_p ())
     return NULL_TREE;
 
   /* Anti-ranges need to be handled separately.  */
-  if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
+  if (vr0->vrtype () == VR_ANTI_RANGE || vr1->vrtype () == VR_ANTI_RANGE)
     {
       /* If both are anti-ranges, then we cannot compute any
 	 comparison.  */
-      if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
+      if (vr0->vrtype () == VR_ANTI_RANGE && vr1->vrtype () == VR_ANTI_RANGE)
 	return NULL_TREE;
 
       /* These comparisons are never statically computable.  */
@@ -1490,7 +1489,7 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
 
       /* Equality can be computed only between a range and an
 	 anti-range.  ~[VAL1, VAL2] == [VAL1, VAL2] is always false.  */
-      if (vr0->type == VR_RANGE)
+      if (vr0->vrtype () == VR_RANGE)
 	{
 	  /* To simplify processing, make VR0 the anti-range.  */
 	  value_range *tmp = vr0;
@@ -1500,8 +1499,8 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
 
       gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);
 
-      if (compare_values_warnv (vr0->min, vr1->min, strict_overflow_p) == 0
-	  && compare_values_warnv (vr0->max, vr1->max, strict_overflow_p) == 0)
+      if (compare_values_warnv (vr0->min (), vr1->min (), strict_overflow_p) == 0
+	  && compare_values_warnv (vr0->max (), vr1->max (), strict_overflow_p) == 0)
 	return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
 
       return NULL_TREE;
@@ -1519,12 +1518,12 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
     {
       /* Equality may only be computed if both ranges represent
 	 exactly one value.  */
-      if (compare_values_warnv (vr0->min, vr0->max, strict_overflow_p) == 0
-	  && compare_values_warnv (vr1->min, vr1->max, strict_overflow_p) == 0)
+      if (compare_values_warnv (vr0->min (), vr0->max (), strict_overflow_p) == 0
+	  && compare_values_warnv (vr1->min (), vr1->max (), strict_overflow_p) == 0)
 	{
-	  int cmp_min = compare_values_warnv (vr0->min, vr1->min,
+	  int cmp_min = compare_values_warnv (vr0->min (), vr1->min (),
 					      strict_overflow_p);
-	  int cmp_max = compare_values_warnv (vr0->max, vr1->max,
+	  int cmp_max = compare_values_warnv (vr0->max (), vr1->max (),
 					      strict_overflow_p);
 	  if (cmp_min == 0 && cmp_max == 0)
 	    return boolean_true_node;
@@ -1532,9 +1531,9 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
 	    return boolean_false_node;
 	}
       /* If [V0_MIN, V1_MAX] < [V1_MIN, V1_MAX] then V0 != V1.  */
-      else if (compare_values_warnv (vr0->min, vr1->max,
+      else if (compare_values_warnv (vr0->min (), vr1->max (),
 				     strict_overflow_p) == 1
-	       || compare_values_warnv (vr1->min, vr0->max,
+	       || compare_values_warnv (vr1->min (), vr0->max (),
 					strict_overflow_p) == 1)
 	return boolean_false_node;
 
@@ -1549,20 +1548,20 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
 	 make sure that both comparisons yield similar results to
 	 avoid comparing values that cannot be compared at
 	 compile-time.  */
-      cmp1 = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
-      cmp2 = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
+      cmp1 = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
+      cmp2 = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p);
       if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1))
 	return boolean_true_node;
 
       /* If VR0 and VR1 represent a single value and are identical,
 	 return false.  */
-      else if (compare_values_warnv (vr0->min, vr0->max,
+      else if (compare_values_warnv (vr0->min (), vr0->max (),
 				     strict_overflow_p) == 0
-	       && compare_values_warnv (vr1->min, vr1->max,
+	       && compare_values_warnv (vr1->min (), vr1->max (),
 					strict_overflow_p) == 0
-	       && compare_values_warnv (vr0->min, vr1->min,
+	       && compare_values_warnv (vr0->min (), vr1->min (),
 					strict_overflow_p) == 0
-	       && compare_values_warnv (vr0->max, vr1->max,
+	       && compare_values_warnv (vr0->max (), vr1->max (),
 					strict_overflow_p) == 0)
 	return boolean_false_node;
 
@@ -1575,13 +1574,13 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
       int tst;
 
       /* If VR0 is to the left of VR1, return true.  */
-      tst = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
+      tst = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
       if ((comp == LT_EXPR && tst == -1)
 	  || (comp == LE_EXPR && (tst == -1 || tst == 0)))
 	return boolean_true_node;
 
       /* If VR0 is to the right of VR1, return false.  */
-      tst = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
+      tst = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p);
       if ((comp == LT_EXPR && (tst == 0 || tst == 1))
 	  || (comp == LE_EXPR && tst == 1))
 	return boolean_false_node;
@@ -1605,11 +1604,11 @@ static tree
 compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
 			  bool *strict_overflow_p)
 {
-  if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
+  if (vr->varying_p () || vr->undefined_p ())
     return NULL_TREE;
 
   /* Anti-ranges need to be handled separately.  */
-  if (vr->type == VR_ANTI_RANGE)
+  if (vr->vrtype () == VR_ANTI_RANGE)
     {
       /* For anti-ranges, the only predicates that we can compute at
 	 compile time are equality and inequality.  */
@@ -1620,7 +1619,7 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
 	return NULL_TREE;
 
       /* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2.  */
-      if (value_inside_range (val, vr->min, vr->max) == 1)
+      if (value_inside_range (val, vr->min (), vr->max ()) == 1)
 	return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
 
       return NULL_TREE;
@@ -1630,16 +1629,16 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
     {
       /* EQ_EXPR may only be computed if VR represents exactly
 	 one value.  */
-      if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0)
+      if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0)
 	{
-	  int cmp = compare_values_warnv (vr->min, val, strict_overflow_p);
+	  int cmp = compare_values_warnv (vr->min (), val, strict_overflow_p);
 	  if (cmp == 0)
 	    return boolean_true_node;
 	  else if (cmp == -1 || cmp == 1 || cmp == 2)
 	    return boolean_false_node;
 	}
-      else if (compare_values_warnv (val, vr->min, strict_overflow_p) == -1
-	       || compare_values_warnv (vr->max, val, strict_overflow_p) == -1)
+      else if (compare_values_warnv (val, vr->min (), strict_overflow_p) == -1
+	       || compare_values_warnv (vr->max (), val, strict_overflow_p) == -1)
 	return boolean_false_node;
 
       return NULL_TREE;
@@ -1647,14 +1646,14 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
   else if (comp == NE_EXPR)
     {
       /* If VAL is not inside VR, then they are always different.  */
-      if (compare_values_warnv (vr->max, val, strict_overflow_p) == -1
-	  || compare_values_warnv (vr->min, val, strict_overflow_p) == 1)
+      if (compare_values_warnv (vr->max (), val, strict_overflow_p) == -1
+	  || compare_values_warnv (vr->min (), val, strict_overflow_p) == 1)
 	return boolean_true_node;
 
       /* If VR represents exactly one value equal to VAL, then return
 	 false.  */
-      if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0
-	  && compare_values_warnv (vr->min, val, strict_overflow_p) == 0)
+      if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0
+	  && compare_values_warnv (vr->min (), val, strict_overflow_p) == 0)
 	return boolean_false_node;
 
       /* Otherwise, they may or may not be different.  */
@@ -1665,13 +1664,13 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
       int tst;
 
       /* If VR is to the left of VAL, return true.  */
-      tst = compare_values_warnv (vr->max, val, strict_overflow_p);
+      tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
       if ((comp == LT_EXPR && tst == -1)
 	  || (comp == LE_EXPR && (tst == -1 || tst == 0)))
 	return boolean_true_node;
 
       /* If VR is to the right of VAL, return false.  */
-      tst = compare_values_warnv (vr->min, val, strict_overflow_p);
+      tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
       if ((comp == LT_EXPR && (tst == 0 || tst == 1))
 	  || (comp == LE_EXPR && tst == 1))
 	return boolean_false_node;
@@ -1684,13 +1683,13 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
       int tst;
 
       /* If VR is to the right of VAL, return true.  */
-      tst = compare_values_warnv (vr->min, val, strict_overflow_p);
+      tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
       if ((comp == GT_EXPR && tst == 1)
 	  || (comp == GE_EXPR && (tst == 0 || tst == 1)))
 	return boolean_true_node;
 
       /* If VR is to the left of VAL, return false.  */
-      tst = compare_values_warnv (vr->max, val, strict_overflow_p);
+      tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
       if ((comp == GT_EXPR && (tst == -1 || tst == 0))
 	  || (comp == GE_EXPR && tst == -1))
 	return boolean_false_node;
@@ -1714,7 +1713,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
 
   /* TODO.  Don't adjust anti-ranges.  An anti-range may provide
      better opportunities than a regular range, but I'm not sure.  */
-  if (vr->type == VR_ANTI_RANGE)
+  if (vr->vrtype () == VR_ANTI_RANGE)
     return;
 
   chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
@@ -1722,7 +1721,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
   /* Like in PR19590, scev can return a constant function.  */
   if (is_gimple_min_invariant (chrec))
     {
-      set_value_range_to_value (vr, chrec, vr->equiv);
+      set_value_range_to_value (vr, chrec, vr->equiv ());
       return;
     }
 
@@ -1771,7 +1770,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
   if (TREE_CODE (step) == INTEGER_CST
       && is_gimple_val (init)
       && (TREE_CODE (init) != SSA_NAME
-	  || get_value_range (init)->type == VR_RANGE))
+	  || get_value_range (init)->vrtype () == VR_RANGE))
     {
       widest_int nit;
 
@@ -1779,7 +1778,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
 	 the number of latch executions is the correct thing to use.  */
       if (max_loop_iterations (loop, &nit))
 	{
-	  value_range maxvr = VR_INITIALIZER;
+	  value_range maxvr (TREE_TYPE (init));
 	  signop sgn = TYPE_SIGN (TREE_TYPE (step));
 	  wi::overflow_type overflow;
 
@@ -1799,9 +1798,9 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
 	      extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
 					      TREE_TYPE (init), init, tem);
 	      /* Likewise if the addition did.  */
-	      if (maxvr.type == VR_RANGE)
+	      if (maxvr.vrtype () == VR_RANGE)
 		{
-		  value_range initvr = VR_INITIALIZER;
+		  value_range initvr (TREE_TYPE (init));
 
 		  if (TREE_CODE (init) == SSA_NAME)
 		    initvr = *(get_value_range (init));
@@ -1815,19 +1814,19 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
 		     because the loop may exit immediately.  Overflow could
 		     happen in the plus expression in this case.  */
 		  if ((dir == EV_DIR_DECREASES
-		       && compare_values (maxvr.min, initvr.min) != -1)
+		       && compare_values (maxvr.min (), initvr.min ()) != -1)
 		      || (dir == EV_DIR_GROWS
-			  && compare_values (maxvr.max, initvr.max) != 1))
+			  && compare_values (maxvr.max (), initvr.max ()) != 1))
 		    return;
 
-		  tmin = maxvr.min;
-		  tmax = maxvr.max;
+		  tmin = maxvr.min ();
+		  tmax = maxvr.max ();
 		}
 	    }
 	}
     }
 
-  if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
+  if (vr->varying_p () || vr->undefined_p ())
     {
       min = tmin;
       max = tmax;
@@ -1840,15 +1839,15 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
       else
 	min = init;
     }
-  else if (vr->type == VR_RANGE)
+  else if (vr->vrtype () == VR_RANGE)
     {
-      min = vr->min;
-      max = vr->max;
+      min = vr->min ();
+      max = vr->max ();
 
       if (dir == EV_DIR_DECREASES)
 	{
-	  /* INIT is the maximum value.  If INIT is lower than VR->MAX
-	     but no smaller than VR->MIN, set VR->MAX to INIT.  */
+	  /* INIT is the maximum value.  If INIT is lower than VR->MAX ()
+	     but no smaller than VR->MIN (), set VR->MAX () to INIT.  */
 	  if (compare_values (init, max) == -1)
 	    max = init;
 
@@ -1860,7 +1859,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
 	}
       else
 	{
-	  /* If INIT is bigger than VR->MIN, set VR->MIN to INIT.  */
+	  /* If INIT is bigger than VR->MIN (), set VR->MIN () to INIT.  */
 	  if (compare_values (init, min) == 1)
 	    min = init;
 
@@ -1886,7 +1885,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
   if (TREE_OVERFLOW_P (max))
     max = drop_tree_overflow (max);
 
-  set_value_range (vr, VR_RANGE, min, max, vr->equiv);
+  set_value_range (vr, VR_RANGE, min, max, vr->equiv ());
 }
 
 /* Dump value ranges of all SSA_NAMEs to FILE.  */
@@ -1957,11 +1956,11 @@ vrp_valueize (tree name)
   if (TREE_CODE (name) == SSA_NAME)
     {
       value_range *vr = x_vr_values->get_value_range (name);
-      if (vr->type == VR_RANGE
-	  && (TREE_CODE (vr->min) == SSA_NAME
-	      || is_gimple_min_invariant (vr->min))
-	  && vrp_operand_equal_p (vr->min, vr->max))
-	return vr->min;
+      if (vr->vrtype () == VR_RANGE
+	  && (TREE_CODE (vr->min ()) == SSA_NAME
+	      || is_gimple_min_invariant (vr->min ()))
+	  && vrp_operand_equal_p (vr->min (), vr->max ()))
+	return vr->min ();
     }
   return name;
 }
@@ -1982,8 +1981,9 @@ vrp_valueize_1 (tree name)
 	  && prop_simulate_again_p (def_stmt))
 	return NULL_TREE;
       value_range *vr = x_vr_values->get_value_range (name);
-      if (range_int_cst_singleton_p (vr))
-	return vr->min;
+      tree singleton = vr->singleton ();
+      if (singleton)
+	return singleton;
     }
   return name;
 }
@@ -2066,12 +2066,9 @@ vr_values::get_vr_for_comparison (int i)
   /* If name N_i does not have a valid range, use N_i as its own
      range.  This allows us to compare against names that may
      have N_i in their ranges.  */
-  if (vr.type == VR_VARYING || vr.type == VR_UNDEFINED)
-    {
-      vr.type = VR_RANGE;
-      vr.min = ssa_name (i);
-      vr.max = ssa_name (i);
-    }
+  if (vr.varying_p () || vr.undefined_p ())
+    vr = value_range (VR_RANGE, vr.type (), ssa_name (i), ssa_name (i),
+		      vr.equiv ());
 
   return vr;
 }
@@ -2094,7 +2091,7 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
   value_range equiv_vr;
 
   /* Get the set of equivalences for VAR.  */
-  e = get_value_range (var)->equiv;
+  e = get_value_range (var)->equiv ();
 
   /* Start at -1.  Set it to 0 if we do a comparison without relying
      on overflow, or 1 if all comparisons rely on overflow.  */
@@ -2180,8 +2177,8 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
 
   /* Compare the ranges of every name equivalent to N1 against the
      ranges of every name equivalent to N2.  */
-  e1 = get_value_range (n1)->equiv;
-  e2 = get_value_range (n2)->equiv;
+  e1 = get_value_range (n1)->equiv ();
+  e2 = get_value_range (n2)->equiv ();
 
   /* Use the fake bitmaps if e1 or e2 are not available.  */
   if (s_obstack == NULL)
@@ -2440,10 +2437,10 @@ vr_values::vrp_evaluate_conditional (tree_code code, tree op0,
       tree type = TREE_TYPE (op0);
       value_range *vr0 = get_value_range (op0);
 
-      if (vr0->type == VR_RANGE
+      if (vr0->vrtype () == VR_RANGE
 	  && INTEGRAL_TYPE_P (type)
-	  && vrp_val_is_min (vr0->min)
-	  && vrp_val_is_max (vr0->max)
+	  && vrp_val_is_min (vr0->min ())
+	  && vrp_val_is_max (vr0->max ())
 	  && is_gimple_min_invariant (op1))
 	{
 	  location_t location;
@@ -2572,9 +2569,9 @@ find_case_label_ranges (gswitch *stmt, value_range *vr, size_t *min_idx1,
   unsigned int n = gimple_switch_num_labels (stmt);
   bool take_default;
   tree case_low, case_high;
-  tree min = vr->min, max = vr->max;
+  tree min = vr->min (), max = vr->max ();
 
-  gcc_checking_assert (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE);
+  gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ());
 
   take_default = !find_case_label_range (stmt, min, max, &i, &j);
 
@@ -2582,7 +2579,7 @@ find_case_label_ranges (gswitch *stmt, value_range *vr, size_t *min_idx1,
   *min_idx2 = 1;
   *max_idx2 = 0;
 
-  if (vr->type == VR_RANGE)
+  if (vr->vrtype () == VR_RANGE)
     {
       *min_idx1 = i;
       *max_idx1 = j;
@@ -2663,9 +2660,9 @@ vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
       fprintf (dump_file, "\n");
     }
 
-  if ((vr->type != VR_RANGE
-       && vr->type != VR_ANTI_RANGE)
-      || symbolic_range_p (vr))
+  if (vr->undefined_p ()
+      || vr->varying_p ()
+      || vr->symbolic_p ())
     return;
 
   /* Find the single edge that is taken from the switch expression.  */
@@ -2809,29 +2806,20 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
 		 See PR53465 and PR54767.  */
 	      if (e->flags & EDGE_DFS_BACK)
 		{
-		  if (vr_arg.type == VR_RANGE
-		      || vr_arg.type == VR_ANTI_RANGE)
+		  if (!vr_arg.varying_p ()
+		      && !vr_arg.undefined_p ())
 		    {
-		      vr_arg.equiv = NULL;
-		      if (symbolic_range_p (&vr_arg))
-			{
-			  vr_arg.type = VR_VARYING;
-			  vr_arg.min = NULL_TREE;
-			  vr_arg.max = NULL_TREE;
-			}
+		      vr_arg.equiv_clear ();
+		      if (vr_arg.symbolic_p ())
+			vr_arg.set_varying ();
 		    }
 		}
 	      else
 		{
 		  /* If the non-backedge arguments range is VR_VARYING then
 		     we can still try recording a simple equivalence.  */
-		  if (vr_arg.type == VR_VARYING)
-		    {
-		      vr_arg.type = VR_RANGE;
-		      vr_arg.min = arg;
-		      vr_arg.max = arg;
-		      vr_arg.equiv = NULL;
-		    }
+		  if (vr_arg.varying_p ())
+		    vr_arg.equiv_clear ();
 		}
 	    }
 	  else
@@ -2839,10 +2827,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
 	      if (TREE_OVERFLOW_P (arg))
 		arg = drop_tree_overflow (arg);
 
-	      vr_arg.type = VR_RANGE;
-	      vr_arg.min = arg;
-	      vr_arg.max = arg;
-	      vr_arg.equiv = NULL;
+	      vr_arg = value_range (VR_RANGE, TREE_TYPE (arg), arg, arg);
 	    }
 
 	  if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2857,17 +2842,17 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
 	  if (first)
 	    copy_value_range (vr_result, &vr_arg);
 	  else
-	    vrp_meet (vr_result, &vr_arg);
+	    vr_result->union_ (&vr_arg);
 	  first = false;
 
-	  if (vr_result->type == VR_VARYING)
+	  if (vr_result->varying_p ())
 	    break;
 	}
     }
 
-  if (vr_result->type == VR_VARYING)
+  if (vr_result->varying_p ())
     goto varying;
-  else if (vr_result->type == VR_UNDEFINED)
+  else if (vr_result->undefined_p ())
     goto update_range;
 
   old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
@@ -2883,21 +2868,21 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
   if (edges > 0
       && gimple_phi_num_args (phi) > 1
       && edges == old_edges
-      && lhs_vr->type != VR_UNDEFINED
+      && !lhs_vr->undefined_p ()
       && may_simulate_backedge_again)
     {
       /* Compare old and new ranges, fall back to varying if the
          values are not comparable.  */
-      int cmp_min = compare_values (lhs_vr->min, vr_result->min);
+      int cmp_min = compare_values (lhs_vr->min (), vr_result->min ());
       if (cmp_min == -2)
 	goto varying;
-      int cmp_max = compare_values (lhs_vr->max, vr_result->max);
+      int cmp_max = compare_values (lhs_vr->max (), vr_result->max ());
       if (cmp_max == -2)
 	goto varying;
 
       /* For non VR_RANGE or for pointers fall back to varying if
 	 the range changed.  */
-      if ((lhs_vr->type != VR_RANGE || vr_result->type != VR_RANGE
+      if ((lhs_vr->vrtype () != VR_RANGE || vr_result->vrtype () != VR_RANGE
 	   || POINTER_TYPE_P (TREE_TYPE (lhs)))
 	  && (cmp_min != 0 || cmp_max != 0))
 	goto varying;
@@ -2910,24 +2895,27 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
 	 times to reach -INF.  Going to -INF + 1 also lets the following
 	 iteration compute whether there will be any overflow, at the
 	 expense of one additional iteration.  */
+      tree new_min = vr_result->min ();
+      tree new_max = vr_result->max ();
       if (cmp_min < 0)
-	vr_result->min = lhs_vr->min;
+	new_min = lhs_vr->min ();
       else if (cmp_min > 0
-	       && !vrp_val_is_min (vr_result->min))
-	vr_result->min
-	  = int_const_binop (PLUS_EXPR,
-			     vrp_val_min (TREE_TYPE (vr_result->min)),
-			     build_int_cst (TREE_TYPE (vr_result->min), 1));
+	       && !vrp_val_is_min (vr_result->min ()))
+	new_min = int_const_binop (PLUS_EXPR,
+				   vrp_val_min (vr_result->type ()),
+				   build_int_cst (vr_result->type (), 1));
 
       /* Similarly for the maximum value.  */
       if (cmp_max > 0)
-	vr_result->max = lhs_vr->max;
+	new_max = lhs_vr->max ();
       else if (cmp_max < 0
-	       && !vrp_val_is_max (vr_result->max))
-	vr_result->max
-	  = int_const_binop (MINUS_EXPR,
-			     vrp_val_max (TREE_TYPE (vr_result->min)),
-			     build_int_cst (TREE_TYPE (vr_result->min), 1));
+	       && !vrp_val_is_max (vr_result->max ()))
+	new_max = int_const_binop (MINUS_EXPR,
+				   vrp_val_max (vr_result->type ()),
+				   build_int_cst (vr_result->type (), 1));
+
+      *vr_result = value_range (vr_result->vrtype (), vr_result->type (),
+				new_min, new_max, vr_result->equiv ());
 
       /* If we dropped either bound to +-INF then if this is a loop
 	 PHI node SCEV may known more about its value-range.  */
@@ -2941,7 +2929,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
   goto update_range;
 
 varying:
-  set_value_range_to_varying (vr_result);
+  set_value_range_to_varying (vr_result, TREE_TYPE (lhs));
 
 scev_check:
   /* If this is a loop PHI node SCEV may known more about its value-range.
@@ -2957,12 +2945,12 @@ infinite_check:
   /* If we will end up with a (-INF, +INF) range, set it to
      VARYING.  Same if the previous max value was invalid for
      the type and we end up with vr_result.min > vr_result.max.  */
-  if ((vr_result->type == VR_RANGE || vr_result->type == VR_ANTI_RANGE)
-      && !((vrp_val_is_max (vr_result->max) && vrp_val_is_min (vr_result->min))
-	   || compare_values (vr_result->min, vr_result->max) > 0))
+  if ((!vr_result->varying_p () && !vr_result->undefined_p ())
+      && !((vrp_val_is_max (vr_result->max ()) && vrp_val_is_min (vr_result->min ()))
+	   || compare_values (vr_result->min (), vr_result->max ()) > 0))
     ;
   else
-    set_value_range_to_varying (vr_result);
+    set_value_range_to_varying (vr_result, TREE_TYPE (lhs));
 
   /* If the new range is different than the previous value, keep
      iterating.  */
@@ -3071,8 +3059,8 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
       vr = get_value_range (op0);
       if (range_int_cst_p (vr))
 	{
-	  op0min = vr->min;
-	  op0max = vr->max;
+	  op0min = vr->min ();
+	  op0max = vr->max ();
 	}
     }
 
@@ -3081,7 +3069,7 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
     {
       value_range *vr1 = get_value_range (op1);
       if (range_int_cst_p (vr1))
-	op1min = vr1->min;
+	op1min = vr1->min ();
     }
   if (rhs_code == TRUNC_MOD_EXPR
       && TREE_CODE (op1min) == INTEGER_CST
@@ -3285,8 +3273,8 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi,
   tree op0 = gimple_assign_rhs1 (stmt);
   tree op1 = gimple_assign_rhs2 (stmt);
   tree op = NULL_TREE;
-  value_range vr0 = VR_INITIALIZER;
-  value_range vr1 = VR_INITIALIZER;
+  value_range vr0 (TREE_TYPE (op0));
+  value_range vr1 (TREE_TYPE (op1));
   wide_int may_be_nonzero0, may_be_nonzero1;
   wide_int must_be_nonzero0, must_be_nonzero1;
   wide_int mask;
@@ -3405,10 +3393,10 @@ test_for_singularity (enum tree_code cond_code, tree op0,
      value range information we have for op0.  */
   if (min && max)
     {
-      if (compare_values (vr->min, min) == 1)
-	min = vr->min;
-      if (compare_values (vr->max, max) == -1)
-	max = vr->max;
+      if (compare_values (vr->min (), min) == 1)
+	min = vr->min ();
+      if (compare_values (vr->max (), max) == -1)
+	max = vr->max ();
 
       /* If the new min/max values have converged to a single value,
 	 then there is only one value which can satisfy the condition,
@@ -3431,14 +3419,14 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn)
   signop src_sgn;
 
   /* We can only handle integral and pointer types.  */
-  src_type = TREE_TYPE (vr->min);
+  src_type = vr->type ();
   if (!INTEGRAL_TYPE_P (src_type)
       && !POINTER_TYPE_P (src_type))
     return false;
 
   /* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED,
      and so is an identity transform.  */
-  src_precision = TYPE_PRECISION (TREE_TYPE (vr->min));
+  src_precision = TYPE_PRECISION (vr->type ());
   src_sgn = TYPE_SIGN (src_type);
   if ((src_precision < dest_precision
        && !(dest_sgn == UNSIGNED && src_sgn == SIGNED))
@@ -3446,9 +3434,7 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn)
     return true;
 
   /* Now we can only handle ranges with constant bounds.  */
-  if (vr->type != VR_RANGE
-      || TREE_CODE (vr->min) != INTEGER_CST
-      || TREE_CODE (vr->max) != INTEGER_CST)
+  if (!range_int_cst_p (vr))
     return false;
 
   /* For sign changes, the MSB of the wide_int has to be clear.
@@ -3456,17 +3442,17 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn)
      a signed wide_int, while a negative value cannot be represented
      by an unsigned wide_int.  */
   if (src_sgn != dest_sgn
-      && (wi::lts_p (wi::to_wide (vr->min), 0)
-	  || wi::lts_p (wi::to_wide (vr->max), 0)))
+      && (wi::lts_p (wi::to_wide (vr->min ()), 0)
+	  || wi::lts_p (wi::to_wide (vr->max ()), 0)))
     return false;
 
   /* Then we can perform the conversion on both ends and compare
      the result for equality.  */
-  tem = wi::ext (wi::to_widest (vr->min), dest_precision, dest_sgn);
-  if (tem != wi::to_widest (vr->min))
+  tem = wi::ext (wi::to_widest (vr->min ()), dest_precision, dest_sgn);
+  if (tem != wi::to_widest (vr->min ()))
     return false;
-  tem = wi::ext (wi::to_widest (vr->max), dest_precision, dest_sgn);
-  if (tem != wi::to_widest (vr->max))
+  tem = wi::ext (wi::to_widest (vr->max ()), dest_precision, dest_sgn);
+  if (tem != wi::to_widest (vr->max ()))
     return false;
 
   return true;
@@ -3493,7 +3479,7 @@ vr_values::simplify_cond_using_ranges_1 (gcond *stmt)
 
       /* If we have range information for OP0, then we might be
 	 able to simplify this conditional. */
-      if (vr->type == VR_RANGE)
+      if (vr->vrtype () == VR_RANGE)
 	{
 	  tree new_tree = test_for_singularity (cond_code, op0, op1, vr);
 	  if (new_tree)
@@ -3636,9 +3622,9 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
       vr = get_value_range (op);
 
       /* We can only handle integer ranges.  */
-      if ((vr->type != VR_RANGE
-	   && vr->type != VR_ANTI_RANGE)
-	  || symbolic_range_p (vr))
+      if (vr->varying_p ()
+	  || vr->undefined_p ()
+	  || vr->symbolic_p ())
 	return false;
 
       /* Find case label for min/max of the value range.  */
@@ -3666,7 +3652,7 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
      value range.  */
   size_t min_idx = 1, max_idx = 0;
   if (vr != NULL)
-    find_case_label_range (stmt, vr->min, vr->max, &min_idx, &max_idx);
+    find_case_label_range (stmt, vr->min (), vr->max (), &min_idx, &max_idx);
   if (min_idx <= max_idx)
     {
       tree min_label = gimple_switch_label (stmt, min_idx);
@@ -3674,10 +3660,10 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
 
       /* Avoid changing the type of the case labels when truncating.  */
       tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
-      tree vr_min = fold_convert (case_label_type, vr->min);
-      tree vr_max = fold_convert (case_label_type, vr->max);
+      tree vr_min = fold_convert (case_label_type, vr->min ());
+      tree vr_max = fold_convert (case_label_type, vr->max ());
 
-      if (vr->type == VR_RANGE)
+      if (vr->vrtype () == VR_RANGE)
 	{
 	  /* If OP's value range is [2,8] and the low label range is
 	     0 ... 3, truncate the label's range to 2 .. 3.  */
@@ -3693,7 +3679,7 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
 	      && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
 	    CASE_HIGH (max_label) = vr_max;
 	}
-      else if (vr->type == VR_ANTI_RANGE)
+      else if (vr->vrtype () == VR_ANTI_RANGE)
 	{
 	  tree one_cst = build_one_cst (case_label_type);
 
@@ -3930,9 +3916,7 @@ vr_values::simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi,
   gassign *conv;
 
   /* We can only handle constant ranges.  */
-  if (vr->type != VR_RANGE
-      || TREE_CODE (vr->min) != INTEGER_CST
-      || TREE_CODE (vr->max) != INTEGER_CST)
+  if (!range_int_cst_p (vr))
     return false;
 
   /* First check if we can use a signed type in place of an unsigned.  */
@@ -4088,26 +4072,26 @@ bool
 vr_values::two_valued_val_range_p (tree var, tree *a, tree *b)
 {
   value_range *vr = get_value_range (var);
-  if ((vr->type != VR_RANGE
-       && vr->type != VR_ANTI_RANGE)
-      || TREE_CODE (vr->min) != INTEGER_CST
-      || TREE_CODE (vr->max) != INTEGER_CST)
+  if (vr->varying_p ()
+      || vr->undefined_p ()
+      || TREE_CODE (vr->min ()) != INTEGER_CST
+      || TREE_CODE (vr->max ()) != INTEGER_CST)
     return false;
 
-  if (vr->type == VR_RANGE
-      && wi::to_wide (vr->max) - wi::to_wide (vr->min) == 1)
+  if (vr->vrtype () == VR_RANGE
+      && wi::to_wide (vr->max ()) - wi::to_wide (vr->min ()) == 1)
     {
-      *a = vr->min;
-      *b = vr->max;
+      *a = vr->min ();
+      *b = vr->max ();
       return true;
     }
 
   /* ~[TYPE_MIN + 1, TYPE_MAX - 1] */
-  if (vr->type == VR_ANTI_RANGE
-      && (wi::to_wide (vr->min)
+  if (vr->vrtype () == VR_ANTI_RANGE
+      && (wi::to_wide (vr->min ())
 	  - wi::to_wide (vrp_val_min (TREE_TYPE (var)))) == 1
       && (wi::to_wide (vrp_val_max (TREE_TYPE (var)))
-	  - wi::to_wide (vr->max)) == 1)
+	  - wi::to_wide (vr->max ())) == 1)
     {
       *a = vrp_val_min (TREE_TYPE (var));
       *b = vrp_val_max (TREE_TYPE (var));
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 487a800c1ea..496707856c3 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -72,7 +72,7 @@ class vr_values
   void cleanup_edges_and_switches (void);
 
  private:
-  void add_equivalence (bitmap *, const_tree);
+  bitmap add_equivalence (bitmap, const_tree);
   bool vrp_stmt_computes_nonzero (gimple *);
   bool op_with_boolean_value_range_p (tree);
   bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *);
@@ -142,7 +142,5 @@ class vr_values
   vec<switch_update> to_update_switch_stmts;
 };
 
-#define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }
-
 extern tree get_output_for_vrp (gimple *);
 #endif /* GCC_VR_VALUES_H */
