diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index 9e581834d08..c3877791a5e 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -53,6 +53,7 @@ evrp_range_analyzer::evrp_range_analyzer () : stack (10)
       FOR_EACH_EDGE (e, ei, bb->preds)
         e->flags |= EDGE_EXECUTABLE;
     }
+  vr_values = new class vr_values;
 }
 
 void
@@ -73,8 +74,8 @@ evrp_range_analyzer::try_find_new_range (tree name,
   value_range *old_vr = get_value_range (name);
 
   /* Discover VR when condition is true.  */
-  extract_range_for_var_from_comparison_expr (name, code, op,
-					      limit, &vr);
+  vr_values->extract_range_for_var_from_comparison_expr (name, code, op,
+							 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)
@@ -83,7 +84,7 @@ evrp_range_analyzer::try_find_new_range (tree name,
 	  && 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.vrp_value_range_pool.allocate ();
+      value_range *new_vr = vr_values->vrp_value_range_pool.allocate ();
       *new_vr = vr;
       return new_vr;
     }
@@ -167,7 +168,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
       value_range vr_result = VR_INITIALIZER;
       bool interesting = stmt_interesting_for_vrp (phi);
       if (!has_unvisited_preds && interesting)
-	extract_range_from_phi_node (phi, &vr_result);
+	vr_values->extract_range_from_phi_node (phi, &vr_result);
       else
 	{
 	  set_value_range_to_varying (&vr_result);
@@ -179,9 +180,9 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
 	  if (interesting
 	      && (l = loop_containing_stmt (phi))
 	      && l->header == gimple_bb (phi))
-	  adjust_range_with_scev (&vr_result, l, phi, lhs);
+	  vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs);
 	}
-      update_value_range (lhs, &vr_result);
+      vr_values->update_value_range (lhs, &vr_result);
 
       /* Set the SSA with the value range.  */
       if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
@@ -216,11 +217,11 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
     {
       edge taken_edge;
       value_range vr = VR_INITIALIZER;
-      extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
+      vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
       if (output
 	  && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE))
 	{
-	  update_value_range (output, &vr);
+	  vr_values->update_value_range (output, &vr);
 
 	  /* Set the SSA with the value range.  */
 	  if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
@@ -240,10 +241,10 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
 	    set_ptr_nonnull (output);
 	}
       else
-	set_defs_to_varying (stmt);
+	vr_values->set_defs_to_varying (stmt);
     }
   else
-    set_defs_to_varying (stmt);
+    vr_values->set_defs_to_varying (stmt);
 
   /* See if we can derive a range for any of STMT's operands.  */
   tree op;
@@ -319,7 +320,7 @@ evrp_range_analyzer::push_value_range (tree var, value_range *vr)
       fprintf (dump_file, "\n");
     }
   stack.safe_push (std::make_pair (var, get_value_range (var)));
-  set_vr_value (var, vr);
+  vr_values->set_vr_value (var, vr);
 }
 
 /* Pop the Value Range from the vrp_stack and update VAR with it.  */
@@ -337,7 +338,7 @@ evrp_range_analyzer::pop_value_range (tree var)
       dump_value_range (dump_file, vr);
       fprintf (dump_file, "\n");
     }
-  set_vr_value (var, vr);
+  vr_values->set_vr_value (var, vr);
   stack.pop ();
   return vr;
 }
diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h
index 2e6c609c45b..b60bba848cc 100644
--- a/gcc/gimple-ssa-evrp-analyze.h
+++ b/gcc/gimple-ssa-evrp-analyze.h
@@ -24,16 +24,46 @@ class evrp_range_analyzer
 {
  public:
   evrp_range_analyzer (void);
-  ~evrp_range_analyzer (void) { stack.release (); }
+  ~evrp_range_analyzer (void) 
+  {
+    if (vr_values)
+      delete vr_values;
+    stack.release ();
+  }
 
   void enter (basic_block);
   void leave (basic_block);
   void record_ranges_from_stmt (gimple *);
 
-  class vr_values vr_values;
+  /* Main interface to retrieve range information.  */
+  value_range *get_value_range (const_tree op)
+    { return vr_values->get_value_range (op); }
+
+  /* Dump all the current value ranges.  This is primarily
+     a debugging interface.  */
+  void dump_all_value_ranges (FILE *fp)
+    { vr_values->dump_all_value_ranges (fp); }
+
+  /* A bit of a wart.  This should ideally go away.  */
+  void vrp_visit_cond_stmt (gcond *cond, edge *e)
+    { return vr_values->vrp_visit_cond_stmt (cond, e); }
+
+  /* Get the underlying vr_values class instance.  If TRANSFER is
+     true, then we are transferring ownership.  Else we keep ownership. 
+
+     This should be converted to a unique_ptr.  */
+  class vr_values *get_vr_values (bool transfer)
+    { 
+      class vr_values *x = vr_values;
+      if (transfer)
+	vr_values = NULL;
+      return x;
+    }
 
  private:
   DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
+  class vr_values *vr_values;
+
   void push_value_range (tree var, value_range *vr);
   value_range *pop_value_range (tree var);
   value_range *try_find_new_range (tree, tree op, tree_code code, tree limit);
@@ -42,30 +72,6 @@ class evrp_range_analyzer
 
   /* STACK holds the old VR.  */
   auto_vec<std::pair <tree, value_range*> > stack;
-
-  /* Temporary delegators.  */
-  value_range *get_value_range (const_tree op)
-    { return vr_values.get_value_range (op); }
-  bool update_value_range (const_tree op, value_range *vr)
-    { return vr_values.update_value_range (op, vr); }
-  void extract_range_from_phi_node (gphi *phi, value_range *vr)
-    { vr_values.extract_range_from_phi_node (phi, vr); }
-  void adjust_range_with_scev (value_range *vr, struct loop *loop,
-                               gimple *stmt, tree var)
-    { vr_values.adjust_range_with_scev (vr, loop, stmt, var); }
-  void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
-                                tree *output_p, value_range *vr)
-    { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
-  void set_defs_to_varying (gimple *stmt)
-    { return vr_values.set_defs_to_varying (stmt); }
-  void set_vr_value (tree name, value_range *vr)
-    { vr_values.set_vr_value (name, vr); }
-  void extract_range_for_var_from_comparison_expr (tree var,
-						   enum tree_code cond_code,
-						   tree op, tree limit,
-						   value_range *vr_p)
-    { vr_values.extract_range_for_var_from_comparison_expr (var, cond_code,
-							    op, limit, vr_p); }
 };
 
 #endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */
diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index 27a983dd9ae..a554cf9e834 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -46,8 +46,11 @@ class evrp_folder : public substitute_and_fold_engine
 {
  public:
   tree get_value (tree) FINAL OVERRIDE;
-
+  evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { }
   class vr_values *vr_values;
+
+ private:
+  DISABLE_COPY_AND_ASSIGN (evrp_folder);
 };
 
 tree
@@ -63,7 +66,9 @@ evrp_folder::get_value (tree op)
 class evrp_dom_walker : public dom_walker
 {
 public:
-  evrp_dom_walker () : dom_walker (CDI_DOMINATORS)
+  evrp_dom_walker ()
+    : dom_walker (CDI_DOMINATORS),
+      evrp_folder (evrp_range_analyzer.get_vr_values (false))
     {
       need_eh_cleanup = BITMAP_ALLOC (NULL);
     }
@@ -82,14 +87,7 @@ public:
   auto_vec<gimple *> stmts_to_remove;
 
   class evrp_range_analyzer evrp_range_analyzer;
-
-  /* Temporary delegators.  */
-  value_range *get_value_range (const_tree op)
-    { return evrp_range_analyzer.vr_values.get_value_range (op); }
-  tree op_with_constant_singleton_value_range (tree op)
-    { return evrp_range_analyzer.vr_values.op_with_constant_singleton_value_range (op); }
-  void vrp_visit_cond_stmt (gcond *cond, edge *e)
-    { evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); }
+  class evrp_folder evrp_folder;
 };
 
 edge
@@ -108,8 +106,9 @@ evrp_dom_walker::before_dom_children (basic_block bb)
       if (virtual_operand_p (lhs))
 	continue;
 
+      value_range *vr = evrp_range_analyzer.get_value_range (lhs);
       /* Mark PHIs whose lhs we fully propagate for removal.  */
-      tree val = op_with_constant_singleton_value_range (lhs);
+      tree val = value_range_constant_singleton (vr);
       if (val && may_propagate_copy (lhs, val))
 	{
 	  stmts_to_remove.safe_push (phi);
@@ -139,7 +138,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
 
       if (gcond *cond = dyn_cast <gcond *> (stmt))
 	{
-	  vrp_visit_cond_stmt (cond, &taken_edge);
+	  evrp_range_analyzer.vrp_visit_cond_stmt (cond, &taken_edge);
 	  if (taken_edge)
 	    {
 	      if (taken_edge->flags & EDGE_TRUE_VALUE)
@@ -153,16 +152,15 @@ evrp_dom_walker::before_dom_children (basic_block bb)
 	}
       else if (stmt_interesting_for_vrp (stmt))
 	{
-	  value_range vr = VR_INITIALIZER;
 	  output = get_output_for_vrp (stmt);
 	  if (output)
 	    {
 	      tree val;
-	      vr = *get_value_range (output);
+	      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 = op_with_constant_singleton_value_range (output))
+	      if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
+		  && (val = value_range_constant_singleton (vr))
 		  && may_propagate_copy (output, val)
 		  && !stmt_could_throw_p (stmt)
 		  && !gimple_has_side_effects (stmt))
@@ -174,8 +172,6 @@ evrp_dom_walker::before_dom_children (basic_block bb)
 	}
 
       /* Try folding stmts with the VR discovered.  */
-      class evrp_folder evrp_folder;
-      evrp_folder.vr_values = &evrp_range_analyzer.vr_values;
       bool did_replace = evrp_folder.replace_uses_in (stmt);
       if (fold_stmt (&gsi, follow_single_use_edges)
 	  || did_replace)
@@ -222,7 +218,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
 	  if (TREE_CODE (arg) != SSA_NAME
 	      || virtual_operand_p (arg))
 	    continue;
-	  tree val = op_with_constant_singleton_value_range (arg);
+	  value_range *vr = evrp_range_analyzer.get_value_range (arg);
+	  tree val = value_range_constant_singleton (vr);
 	  if (val && may_propagate_copy (arg, val))
 	    propagate_value (use_p, val);
 	}
@@ -245,7 +242,7 @@ evrp_dom_walker::cleanup (void)
   if (dump_file)
     {
       fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
-      evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file);
+      evrp_range_analyzer.dump_all_value_ranges (dump_file);
       fprintf (dump_file, "\n");
     }
 
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 24f013a9402..9eeebedfaed 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -40,80 +40,81 @@ class vr_values
   vr_values (void);
   ~vr_values (void);
 
-  /* Value range array.  After propagation, VR_VALUE[I] holds the range
-     of values that SSA name N_I may take.  */
-  unsigned int num_vr_values;
-  value_range **vr_value;
-  bool values_propagated;
+  value_range *get_value_range (const_tree);
 
-  /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
-     number of executable edges we saw the last time we visited the
-     node.  */
-  int *vr_phi_edge_counts;
+  void set_vr_value (tree, value_range *);
+  void set_defs_to_varying (gimple *);
+  bool update_value_range (const_tree, value_range *);
+  tree op_with_constant_singleton_value_range (tree);
+  void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
+  tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
+  void dump_all_value_ranges (FILE *);
+
+  void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
+						   tree, tree, value_range *);
+  void extract_range_from_phi_node (gphi *, value_range *);
+  void extract_range_basic (value_range *, gimple *);
+  void extract_range_from_assignment (value_range *, gassign *);
+  void extract_range_from_stmt (gimple *, edge *, tree *, value_range *);
+
+  void vrp_visit_cond_stmt (gcond *, edge *);
+
+  void simplify_cond_using_ranges_2 (gcond *);
+  bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
+
+  /* This probably belongs in the lattice rather than in here.  */
+  bool values_propagated;
 
   /* Allocation pools for tree-vrp allocations.  */
   object_allocator<value_range> vrp_value_range_pool;
-  bitmap_obstack vrp_equiv_obstack;
 
-  value_range *get_value_range (const_tree);
-  void set_vr_value (tree, value_range *);
-
-  void set_defs_to_varying (gimple *);
-  bool update_value_range (const_tree, value_range *);
+ private:
+  bitmap_obstack vrp_equiv_obstack;
   void add_equivalence (bitmap *, const_tree);
   bool vrp_stmt_computes_nonzero (gimple *);
-  tree op_with_constant_singleton_value_range (tree);
   bool op_with_boolean_value_range_p (tree);
   bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *);
-  void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
   value_range get_vr_for_comparison (int);
   tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool);
   tree compare_names (enum tree_code, tree, tree, bool *);
   bool two_valued_val_range_p (tree, tree *, tree *);
-
   tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code,
 							     tree, tree,
 							     bool *);
   tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code,
 						tree, tree, bool,
 						bool *, bool *);
-  tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
-
-
-  void dump_all_value_ranges (FILE *);
-
-  void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
-						   tree, tree, value_range *);
   void extract_range_from_assert (value_range *, tree);
   void extract_range_from_ssa_name (value_range *, tree);
   void extract_range_from_binary_expr (value_range *, enum tree_code,
 				       tree, tree, tree);
   void extract_range_from_unary_expr (value_range *, enum tree_code,
 				      tree, tree);
-  void extract_range_from_phi_node (gphi *, value_range *);
   void extract_range_from_cond_expr (value_range *, gassign *);
-  void extract_range_basic (value_range *, gimple *);
-  void extract_range_from_assignment (value_range *, gassign *);
-  void extract_range_from_stmt (gimple *, edge *, tree *, value_range *);
   void extract_range_from_comparison (value_range *, enum tree_code,
 				      tree, tree, tree);
-
   void vrp_visit_assignment_or_call (gimple*, tree *, value_range *);
   void vrp_visit_switch_stmt (gswitch *, edge *);
-  void vrp_visit_cond_stmt (gcond *, edge *);
-
   bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_cond_using_ranges_1 (gcond *);
-  void simplify_cond_using_ranges_2 (gcond *);
   bool simplify_switch_using_ranges (gswitch *);
   bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *,
 					       gimple *);
   bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *);
-  bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
+
+  /* Value range array.  After propagation, VR_VALUE[I] holds the range
+     of values that SSA name N_I may take.  */
+  unsigned int num_vr_values;
+  value_range **vr_value;
+
+  /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
+     number of executable edges we saw the last time we visited the
+     node.  */
+  int *vr_phi_edge_counts;
 };
 
 #define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }
