public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Aldy Hernandez <aldyh@redhat.com>
To: Richard Biener <richard.guenther@gmail.com>,
	Martin Sebor <msebor@gmail.com>
Cc: GCC patches <gcc-patches@gcc.gnu.org>,
	Andrew MacLeod <amacleod@redhat.com>,
	Martin Sebor <msebor@redhat.com>
Subject: Re: [PATCH 4/5] Convert remaining passes to RANGE_QUERY.
Date: Tue, 25 May 2021 13:26:08 +0200	[thread overview]
Message-ID: <e44a5c3f-c9b4-b01e-4ce3-16966ef7d679@redhat.com> (raw)
In-Reply-To: <CAFiYyc0wnBD9XiKtWMYDXuCRiZc9DGXKV-noue3Qhe7ZYH28tA@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 908 bytes --]

Same as before, but with the minor change that the following IPA pass 
uses the correct struct function, as discussed.

Tests on x86-64 Linux on-going.

Aldy

diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index a0238710e72..d8292777647 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -43,6 +43,7 @@
  #include "attribs.h"
  #include "tree-ssa.h"
  #include "tree-cfg.h"
+#include "gimple-range.h"

  /* The idea behind this analyzer is to generate set constraints from the
     program, then solve the resulting constraints in order to generate the
@@ -6740,7 +6741,9 @@ find_what_p_points_to (tree fndecl, tree p)
    struct ptr_info_def *pi;
    tree lookup_p = p;
    varinfo_t vi;
-  bool nonnull = get_ptr_nonnull (p);
+  value_range vr;
+  RANGE_QUERY (DECL_STRUCT_FUNCTION (fndecl))->range_of_expr (vr, p);
+  bool nonnull = vr.nonzero_p ();

[snip]

[-- Attachment #2: 0004-Convert-remaining-passes-to-RANGE_QUERY.patch --]
[-- Type: text/x-patch, Size: 48637 bytes --]

From 2e185f6caab305ac3779097005abf2153c91d1d5 Mon Sep 17 00:00:00 2001
From: Aldy Hernandez <aldyh@redhat.com>
Date: Wed, 19 May 2021 18:44:08 +0200
Subject: [PATCH 4/5] Convert remaining passes to RANGE_QUERY.

This patch converts the remaining users of get_range_info and
get_ptr_nonnull to the range_query API.

No effort was made to move passes away from VR_ANTI_RANGE, or any other
use of deprecated methods.  This was a straight up conversion to the new
API, nothing else.

gcc/ChangeLog:

	* builtins.c (check_nul_terminated_array): Convert to RANGE_QUERY.
	(expand_builtin_strnlen): Same.
	(determine_block_size): Same.
	* fold-const.c (expr_not_equal_to): Same.
	* gimple-fold.c (size_must_be_zero_p): Same.
	* gimple-match-head.c: Include gimple-range.h.
	* gimple-pretty-print.c (dump_ssaname_info): Convert to RANGE_QUERY.
	* gimple-ssa-warn-restrict.c
	(builtin_memref::extend_offset_range): Same.
	* graphite-sese-to-poly.c (add_param_constraints): Same.
	* internal-fn.c (get_min_precision): Same.
	* ipa-fnsummary.c (set_switch_stmt_execution_predicate): Same.
	* ipa-prop.c (ipa_compute_jump_functions_for_edge): Same.
	* match.pd: Same.
	* tree-data-ref.c (split_constant_offset): Same.
	(dr_step_indicator): Same.
	* tree-dfa.c (get_ref_base_and_extent): Same.
	* tree-scalar-evolution.c (iv_can_overflow_p): Same.
	* tree-ssa-loop-niter.c (refine_value_range_using_guard): Same.
	(determine_value_range): Same.
	(record_nonwrapping_iv): Same.
	(infer_loop_bounds_from_signedness): Same.
	(scev_var_range_cant_overflow): Same.
	* tree-ssa-phiopt.c (two_value_replacement): Same.
	* tree-ssa-pre.c (insert_into_preds_of_block): Same.
	* tree-ssa-reassoc.c (optimize_range_tests_to_bit_test): Same.
	* tree-ssa-strlen.c (handle_builtin_stxncpy_strncat): Same.
	(get_range): Same.
	(dump_strlen_info): Same.
	(set_strlen_range): Same.
	(maybe_diag_stxncpy_trunc): Same.
	(get_len_or_size): Same.
	(handle_integral_assign): Same.
	* tree-ssa-structalias.c (find_what_p_points_to): Same.
	* tree-ssa-uninit.c (find_var_cmp_const): Same.
	* tree-switch-conversion.c (bit_test_cluster::emit): Same.
	* tree-vect-patterns.c (vect_get_range_info): Same.
	(vect_recog_divmod_pattern): Same.
	* tree-vrp.c (intersect_range_with_nonzero_bits): Same.
	(register_edge_assert_for_2): Same.
	(determine_value_range_1): Same.
	* tree.c (get_range_pos_neg): Same.
	* vr-values.c (vr_values::get_lattice_entry): Same.
	(vr_values::update_value_range): Same.
	(simplify_conversion_using_ranges): Same.
---
 gcc/builtins.c                 | 40 ++++++++++------
 gcc/fold-const.c               |  8 +++-
 gcc/gimple-fold.c              |  7 ++-
 gcc/gimple-match-head.c        |  1 +
 gcc/gimple-pretty-print.c      | 12 ++++-
 gcc/gimple-ssa-warn-restrict.c |  8 +++-
 gcc/graphite-sese-to-poly.c    |  9 +++-
 gcc/internal-fn.c              | 14 +++---
 gcc/ipa-fnsummary.c            | 11 ++++-
 gcc/ipa-prop.c                 | 16 +++----
 gcc/match.pd                   | 19 ++++++--
 gcc/tree-data-ref.c            | 24 ++++++++--
 gcc/tree-dfa.c                 | 14 +++++-
 gcc/tree-scalar-evolution.c    | 13 +++++-
 gcc/tree-ssa-loop-niter.c      | 81 +++++++++++++++++++++-----------
 gcc/tree-ssa-phiopt.c          | 11 ++++-
 gcc/tree-ssa-pre.c             | 19 ++++----
 gcc/tree-ssa-reassoc.c         |  9 ++--
 gcc/tree-ssa-strlen.c          | 85 ++++++++++++++++++++--------------
 gcc/tree-ssa-structalias.c     |  8 ++--
 gcc/tree-ssa-uninit.c          |  8 +++-
 gcc/tree-switch-conversion.c   | 10 ++--
 gcc/tree-vect-patterns.c       | 18 +++++--
 gcc/tree-vrp.c                 | 21 ++++-----
 gcc/tree.c                     | 13 +++---
 gcc/vr-values.c                | 12 +++--
 26 files changed, 332 insertions(+), 159 deletions(-)

diff --git a/gcc/builtins.c b/gcc/builtins.c
index e1b284846b1..deb7c083315 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -79,6 +79,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-outof-ssa.h"
 #include "attr-fnspec.h"
 #include "demangle.h"
+#include "gimple-range.h"
 
 struct target_builtins default_target_builtins;
 #if SWITCHABLE_TARGET
@@ -1214,14 +1215,15 @@ check_nul_terminated_array (tree expr, tree src,
   wide_int bndrng[2];
   if (bound)
     {
-      if (TREE_CODE (bound) == INTEGER_CST)
-	bndrng[0] = bndrng[1] = wi::to_wide (bound);
-      else
-	{
-	  value_range_kind rng = get_range_info (bound, bndrng, bndrng + 1);
-	  if (rng != VR_RANGE)
-	    return true;
-	}
+      value_range r;
+
+      GLOBAL_RANGE_QUERY->range_of_expr (r, bound);
+
+      if (r.kind () != VR_RANGE)
+	return true;
+
+      bndrng[0] = r.lower_bound ();
+      bndrng[1] = r.upper_bound ();
 
       if (exact)
 	{
@@ -3827,9 +3829,12 @@ expand_builtin_strnlen (tree exp, rtx target, machine_mode target_mode)
     return NULL_RTX;
 
   wide_int min, max;
-  enum value_range_kind rng = get_range_info (bound, &min, &max);
-  if (rng != VR_RANGE)
+  value_range r;
+  GLOBAL_RANGE_QUERY->range_of_expr (r, bound);
+  if (r.kind () != VR_RANGE)
     return NULL_RTX;
+  min = r.lower_bound ();
+  max = r.upper_bound ();
 
   if (!len || TREE_CODE (len) != INTEGER_CST)
     {
@@ -3897,7 +3902,16 @@ determine_block_size (tree len, rtx len_rtx,
 	*probable_max_size = *max_size = GET_MODE_MASK (GET_MODE (len_rtx));
 
       if (TREE_CODE (len) == SSA_NAME)
-	range_type = get_range_info (len, &min, &max);
+	{
+	  value_range r;
+	  GLOBAL_RANGE_QUERY->range_of_expr (r, len);
+	  range_type = r.kind ();
+	  if (range_type != VR_UNDEFINED)
+	    {
+	      min = wi::to_wide (r.min ());
+	      max = wi::to_wide (r.max ());
+	    }
+	}
       if (range_type == VR_RANGE)
 	{
 	  if (wi::fits_uhwi_p (min) && *min_size < min.to_uhwi ())
@@ -4914,8 +4928,8 @@ check_read_access (tree exp, tree src, tree bound /* = NULL_TREE */,
 /* If STMT is a call to an allocation function, returns the constant
    maximum size of the object allocated by the call represented as
    sizetype.  If nonnull, sets RNG1[] to the range of the size.
-   When nonnull, uses RVALS for range information, otherwise calls
-   get_range_info to get it.
+   When nonnull, uses RVALS for range information, otherwise gets global
+   range info.
    Returns null when STMT is not a call to a valid allocation function.  */
 
 tree
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 5a41524702b..d680ba1442f 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -83,6 +83,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-vector-builder.h"
 #include "vec-perm-indices.h"
 #include "asan.h"
+#include "gimple-range.h"
 
 /* Nonzero if we are folding constants inside an initializer; zero
    otherwise.  */
@@ -10686,7 +10687,12 @@ expr_not_equal_to (tree t, const wide_int &w)
     case SSA_NAME:
       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
 	return false;
-      get_range_info (t, vr);
+
+      if (cfun)
+	RANGE_QUERY (cfun)->range_of_expr (vr, t);
+      else
+	GLOBAL_RANGE_QUERY->range_of_expr (vr, t);
+
       if (!vr.undefined_p ()
 	  && !vr.contains_p (wide_int_to_tree (TREE_TYPE (t), w)))
 	return true;
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 68717cf1542..228fa1b357f 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -873,7 +873,12 @@ size_must_be_zero_p (tree size)
   value_range valid_range (build_int_cst (type, 0),
 			   wide_int_to_tree (type, ssize_max));
   value_range vr;
-  get_range_info (size, vr);
+  if (cfun)
+    RANGE_QUERY (cfun)->range_of_expr (vr, size);
+  else
+    GLOBAL_RANGE_QUERY->range_of_expr (vr, size);
+  if (vr.undefined_p ())
+    vr.set_varying (TREE_TYPE (size));
   vr.intersect (&valid_range);
   return vr.zero_p ();
 }
diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
index b084a31572a..7112c116835 100644
--- a/gcc/gimple-match-head.c
+++ b/gcc/gimple-match-head.c
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-eh.h"
 #include "dbgcnt.h"
 #include "tm.h"
+#include "gimple-range.h"
 
 /* Forward declarations of the private auto-generated matchers.
    They expect valueized operands in canonical order and do not
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 0ef01e6420b..62d895d1625 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "asan.h"
 #include "cfgloop.h"
+#include "gimple-range.h"
 
 /* Disable warnings about quoting issues in the pp_xxx calls below
    that (intentionally) don't follow GCC diagnostic conventions.  */
@@ -2263,8 +2264,17 @@ dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
       && SSA_NAME_RANGE_INFO (node))
     {
       wide_int min, max, nonzero_bits;
-      value_range_kind range_type = get_range_info (node, &min, &max);
+      value_range r;
 
+      GLOBAL_RANGE_QUERY->range_of_expr (r, node);
+      value_range_kind range_type = r.kind ();
+      if (!r.undefined_p ())
+	{
+	  min = wi::to_wide (r.min ());
+	  max = wi::to_wide (r.max ());
+	}
+
+      // FIXME: Use irange::dump() instead.
       if (range_type == VR_VARYING)
 	pp_printf (buffer, "# RANGE VR_VARYING");
       else if (range_type == VR_RANGE || range_type == VR_ANTI_RANGE)
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index ad37f20afaa..a59731c2bc2 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -349,7 +349,13 @@ builtin_memref::extend_offset_range (tree offset)
 	  /* There is a global version here because
 	     check_bounds_or_overlap may be called from gimple
 	     fold during gimple lowering.  */
-	  rng = get_range_info (offset, &min, &max);
+	  RANGE_QUERY (cfun)->range_of_expr (vr, offset, stmt);
+	  rng = vr.kind ();
+	  if (!vr.undefined_p ())
+	    {
+	      min = wi::to_wide (vr.min ());
+	      max = wi::to_wide (vr.max ());
+	    }
 	}
       if (rng == VR_ANTI_RANGE && wi::lts_p (max, min))
 	{
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index eebf2e02cfc..2d332f69a92 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -418,13 +418,18 @@ static void
 add_param_constraints (scop_p scop, graphite_dim_t p, tree parameter)
 {
   tree type = TREE_TYPE (parameter);
+  value_range r;
   wide_int min, max;
 
   gcc_assert (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type));
 
   if (INTEGRAL_TYPE_P (type)
-      && get_range_info (parameter, &min, &max) == VR_RANGE)
-    ;
+      && RANGE_QUERY (cfun)->range_of_expr (r, parameter)
+      && !r.undefined_p ())
+    {
+      min = r.lower_bound ();
+      max = r.upper_bound ();
+    }
   else
     {
       min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index d209a52f823..dd1f204863e 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "ssa-iterators.h"
 #include "explow.h"
 #include "rtl-iter.h"
+#include "gimple-range.h"
 
 /* The names of each internal function, indexed by function number.  */
 const char *const internal_fn_name_array[] = {
@@ -680,8 +681,9 @@ get_min_precision (tree arg, signop sign)
     }
   if (TREE_CODE (arg) != SSA_NAME)
     return prec + (orig_sign != sign);
-  wide_int arg_min, arg_max;
-  while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
+  value_range r;
+  while (!GLOBAL_RANGE_QUERY->range_of_expr (r, arg)
+	 || r.kind () != VR_RANGE)
     {
       gimple *g = SSA_NAME_DEF_STMT (arg);
       if (is_gimple_assign (g)
@@ -709,14 +711,14 @@ get_min_precision (tree arg, signop sign)
     }
   if (sign == TYPE_SIGN (TREE_TYPE (arg)))
     {
-      int p1 = wi::min_precision (arg_min, sign);
-      int p2 = wi::min_precision (arg_max, sign);
+      int p1 = wi::min_precision (r.lower_bound (), sign);
+      int p2 = wi::min_precision (r.upper_bound (), sign);
       p1 = MAX (p1, p2);
       prec = MIN (prec, p1);
     }
-  else if (sign == UNSIGNED && !wi::neg_p (arg_min, SIGNED))
+  else if (sign == UNSIGNED && !wi::neg_p (r.lower_bound (), SIGNED))
     {
-      int p = wi::min_precision (arg_max, UNSIGNED);
+      int p = wi::min_precision (r.upper_bound (), UNSIGNED);
       prec = MIN (prec, p);
     }
   return prec + (orig_sign != sign);
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index 4e5be812734..299d7fc1f60 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -85,6 +85,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "tree-into-ssa.h"
 #include "symtab-clones.h"
+#include "gimple-range.h"
 
 /* Summaries.  */
 fast_function_summary <ipa_fn_summary *, va_gc> *ipa_fn_summaries;
@@ -1687,8 +1688,14 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
   int bound_limit = opt_for_fn (fbi->node->decl,
 				param_ipa_max_switch_predicate_bounds);
   int bound_count = 0;
-  wide_int vr_wmin, vr_wmax;
-  value_range_kind vr_type = get_range_info (op, &vr_wmin, &vr_wmax);
+  value_range vr;
+
+  RANGE_QUERY (cfun)->range_of_expr (vr, op);
+  if (vr.undefined_p ())
+    vr.set_varying (TREE_TYPE (op));
+  value_range_kind vr_type = vr.kind ();
+  wide_int vr_wmin = wi::to_wide (vr.min ());
+  wide_int vr_wmax = wi::to_wide (vr.max ());
 
   FOR_EACH_EDGE (e, ei, bb->succs)
     {
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 0591ef1b569..02f422bdbf3 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "options.h"
 #include "symtab-clones.h"
 #include "attr-fnspec.h"
+#include "gimple-range.h"
 
 /* Function summary where the parameter infos are actually stored. */
 ipa_node_params_t *ipa_node_params_sum = NULL;
@@ -2237,6 +2238,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
   gcall *call = cs->call_stmt;
   int n, arg_num = gimple_call_num_args (call);
   bool useful_context = false;
+  value_range vr;
 
   if (arg_num == 0 || args->jump_functions)
     return;
@@ -2274,7 +2276,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 
 	  if (TREE_CODE (arg) == SSA_NAME
 	      && param_type
-	      && get_ptr_nonnull (arg))
+	      && RANGE_QUERY (cfun)->range_of_expr (vr, arg)
+	      && vr.nonzero_p ())
 	    addr_nonzero = true;
 	  else if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
 	    addr_nonzero = true;
@@ -2289,19 +2292,14 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	}
       else
 	{
-	  wide_int min, max;
-	  value_range_kind kind;
 	  if (TREE_CODE (arg) == SSA_NAME
 	      && param_type
-	      && (kind = get_range_info (arg, &min, &max))
-	      && (kind == VR_RANGE || kind == VR_ANTI_RANGE))
+	      && RANGE_QUERY (cfun)->range_of_expr (vr, arg)
+	      && !vr.undefined_p ())
 	    {
 	      value_range resvr;
-	      value_range tmpvr (wide_int_to_tree (TREE_TYPE (arg), min),
-				 wide_int_to_tree (TREE_TYPE (arg), max),
-				 kind);
 	      range_fold_unary_expr (&resvr, NOP_EXPR, param_type,
-				     &tmpvr, TREE_TYPE (arg));
+				     &vr, TREE_TYPE (arg));
 	      if (!resvr.undefined_p () && !resvr.varying_p ())
 		ipa_set_jfunc_vr (jfunc, &resvr);
 	      else
diff --git a/gcc/match.pd b/gcc/match.pd
index cdb87636951..9dddf5ebd0a 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -663,11 +663,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (with
      {
        bool overflowed = true;
-       wide_int wmin0, wmax0, wmin1, wmax1;
+       value_range vr0, vr1;
        if (INTEGRAL_TYPE_P (type)
-	   && get_range_info (@0, &wmin0, &wmax0) == VR_RANGE
-	   && get_range_info (@1, &wmin1, &wmax1) == VR_RANGE)
+	   && GLOBAL_RANGE_QUERY->range_of_expr (vr0, @0)
+	   && GLOBAL_RANGE_QUERY->range_of_expr (vr1, @1)
+	   && vr0.kind () == VR_RANGE
+	   && vr1.kind () == VR_RANGE)
 	 {
+	   wide_int wmin0 = vr0.lower_bound ();
+	   wide_int wmax0 = vr0.upper_bound ();
+	   wide_int wmin1 = vr1.lower_bound ();
+	   wide_int wmax1 = vr1.upper_bound ();
 	   /* If the multiplication can't overflow/wrap around, then
 	      it can be optimized too.  */
 	   wi::overflow_type min_ovf, max_ovf;
@@ -2509,9 +2515,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	  = wide_int::from (wi::to_wide (@1), TYPE_PRECISION (inner_type),
 			    TYPE_SIGN (inner_type));
 
-        wide_int wmin0, wmax0;
-        if (get_range_info (@0, &wmin0, &wmax0) == VR_RANGE)
+	value_range vr;
+	if (GLOBAL_RANGE_QUERY->range_of_expr (vr, @0)
+	    && vr.kind () == VR_RANGE)
           {
+	    wide_int wmin0 = vr.lower_bound ();
+	    wide_int wmax0 = vr.upper_bound ();
             wi::add (wmin0, w1, TYPE_SIGN (inner_type), &min_ovf);
             wi::add (wmax0, w1, TYPE_SIGN (inner_type), &max_ovf);
           }
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index e6dd5f15bed..5ba41e2c73d 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -1035,14 +1035,23 @@ split_constant_offset (tree exp, tree *var, tree *off, value_range *exp_range,
       *exp_range = type;
       if (code == SSA_NAME)
 	{
-	  wide_int var_min, var_max;
-	  value_range_kind vr_kind = get_range_info (exp, &var_min, &var_max);
+	  value_range vr;
+	  RANGE_QUERY (cfun)->range_of_expr (vr, exp);
+	  if (vr.undefined_p ())
+	    vr.set_varying (TREE_TYPE (exp));
+	  wide_int var_min = wi::to_wide (vr.min ());
+	  wide_int var_max = wi::to_wide (vr.max ());
+	  value_range_kind vr_kind = vr.kind ();
 	  wide_int var_nonzero = get_nonzero_bits (exp);
 	  vr_kind = intersect_range_with_nonzero_bits (vr_kind,
 						       &var_min, &var_max,
 						       var_nonzero,
 						       TYPE_SIGN (type));
-	  if (vr_kind == VR_RANGE)
+	  /* This check for VR_VARYING is here because the old code
+	     using get_range_info would return VR_RANGE for the entire
+	     domain, instead of VR_VARYING.  The new code normalizes
+	     full-domain ranges to VR_VARYING.  */
+	  if (vr_kind == VR_RANGE || vr_kind == VR_VARYING)
 	    *exp_range = value_range (type, var_min, var_max);
 	}
     }
@@ -6298,12 +6307,19 @@ dr_step_indicator (struct data_reference *dr, int useful_min)
 
       /* Get the range of values that the unconverted step actually has.  */
       wide_int step_min, step_max;
+      value_range vr;
       if (TREE_CODE (step) != SSA_NAME
-	  || get_range_info (step, &step_min, &step_max) != VR_RANGE)
+	  || !RANGE_QUERY (cfun)->range_of_expr (vr, step)
+	  || vr.kind () != VR_RANGE)
 	{
 	  step_min = wi::to_wide (TYPE_MIN_VALUE (type));
 	  step_max = wi::to_wide (TYPE_MAX_VALUE (type));
 	}
+      else
+	{
+	  step_min = vr.lower_bound ();
+	  step_max = vr.upper_bound ();
+	}
 
       /* Check whether the unconverted step has an acceptable range.  */
       signop sgn = TYPE_SIGN (type);
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 0482b05e26c..e9cf4bfa706 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-iterator.h"
 #include "gimple-walk.h"
 #include "tree-dfa.h"
+#include "gimple-range.h"
 
 /* Build and maintain data flow information for trees.  */
 
@@ -530,14 +531,23 @@ get_ref_base_and_extent (tree exp, poly_int64_pod *poffset,
 		   index.  */
 		seen_variable_array_ref = true;
 
-		wide_int min, max;
+		value_range vr;
+		range_query *query;
+		if (cfun)
+		  query = RANGE_QUERY (cfun);
+		else
+		  query = GLOBAL_RANGE_QUERY;
+
 		if (TREE_CODE (index) == SSA_NAME
 		    && (low_bound = array_ref_low_bound (exp),
 			poly_int_tree_p (low_bound))
 		    && (unit_size = array_ref_element_size (exp),
 			TREE_CODE (unit_size) == INTEGER_CST)
-		    && get_range_info (index, &min, &max) == VR_RANGE)
+		    && query->range_of_expr (vr, index)
+		    && vr.kind () == VR_RANGE)
 		  {
+		    wide_int min = vr.lower_bound ();
+		    wide_int max = vr.upper_bound ();
 		    poly_offset_int lbound = wi::to_poly_offset (low_bound);
 		    /* Try to constrain maxsize with range information.  */
 		    offset_int omax
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index ff052be1021..f0f28f26042 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -3039,18 +3039,27 @@ iv_can_overflow_p (class loop *loop, tree type, tree base, tree step)
   widest_int nit;
   wide_int base_min, base_max, step_min, step_max, type_min, type_max;
   signop sgn = TYPE_SIGN (type);
+  value_range r;
 
   if (integer_zerop (step))
     return false;
 
   if (!INTEGRAL_TYPE_P (TREE_TYPE (base))
-      || get_range_info (base, &base_min, &base_max) != VR_RANGE)
+      || !RANGE_QUERY (cfun)->range_of_expr (r, base)
+      || r.kind () != VR_RANGE)
     return true;
 
+  base_min = r.lower_bound ();
+  base_max = r.upper_bound ();
+
   if (!INTEGRAL_TYPE_P (TREE_TYPE (step))
-      || get_range_info (step, &step_min, &step_max) != VR_RANGE)
+      || !RANGE_QUERY (cfun)->range_of_expr (r, step)
+      || r.kind () != VR_RANGE)
     return true;
 
+  step_min = r.lower_bound ();
+  step_max = r.upper_bound ();
+
   if (!get_max_loop_iterations (loop, &nit))
     return true;
 
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 3817ec423e7..bfbb11c59c5 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-chrec.h"
 #include "tree-scalar-evolution.h"
 #include "tree-dfa.h"
+#include "gimple-range.h"
 
 
 /* The maximum number of dominator BBs we search for conditions
@@ -121,7 +122,6 @@ refine_value_range_using_guard (tree type, tree var,
   tree varc0, varc1, ctype;
   mpz_t offc0, offc1;
   mpz_t mint, maxt, minc1, maxc1;
-  wide_int minv, maxv;
   bool no_wrap = nowrap_type_p (type);
   bool c0_ok, c1_ok;
   signop sgn = TYPE_SIGN (type);
@@ -221,6 +221,7 @@ refine_value_range_using_guard (tree type, tree var,
   get_type_static_bounds (type, mint, maxt);
   mpz_init (minc1);
   mpz_init (maxc1);
+  value_range r;
   /* Setup range information for varc1.  */
   if (integer_zerop (varc1))
     {
@@ -229,11 +230,12 @@ refine_value_range_using_guard (tree type, tree var,
     }
   else if (TREE_CODE (varc1) == SSA_NAME
 	   && INTEGRAL_TYPE_P (type)
-	   && get_range_info (varc1, &minv, &maxv) == VR_RANGE)
+	   && RANGE_QUERY (cfun)->range_of_expr (r, varc1)
+	   && r.kind () == VR_RANGE)
     {
-      gcc_assert (wi::le_p (minv, maxv, sgn));
-      wi::to_mpz (minv, minc1, sgn);
-      wi::to_mpz (maxv, maxc1, sgn);
+      gcc_assert (wi::le_p (r.lower_bound (), r.upper_bound (), sgn));
+      wi::to_mpz (r.lower_bound (), minc1, sgn);
+      wi::to_mpz (r.upper_bound (), maxc1, sgn);
     }
   else
     {
@@ -372,34 +374,50 @@ determine_value_range (class loop *loop, tree type, tree var, mpz_t off,
       gphi_iterator gsi;
 
       /* Either for VAR itself...  */
-      rtype = get_range_info (var, &minv, &maxv);
+      value_range var_range;
+      RANGE_QUERY (cfun)->range_of_expr (var_range, var);
+      rtype = var_range.kind ();
+      if (!var_range.undefined_p ())
+	{
+	  minv = var_range.lower_bound ();
+	  maxv = var_range.upper_bound ();
+	}
+
       /* Or for PHI results in loop->header where VAR is used as
 	 PHI argument from the loop preheader edge.  */
       for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
 	{
 	  gphi *phi = gsi.phi ();
-	  wide_int minc, maxc;
+	  value_range phi_range;
 	  if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var
-	      && (get_range_info (gimple_phi_result (phi), &minc, &maxc)
-		  == VR_RANGE))
+	      && RANGE_QUERY (cfun)->range_of_expr (phi_range,
+						    gimple_phi_result (phi))
+	      && phi_range.kind () == VR_RANGE)
 	    {
 	      if (rtype != VR_RANGE)
 		{
 		  rtype = VR_RANGE;
-		  minv = minc;
-		  maxv = maxc;
+		  minv = phi_range.lower_bound ();
+		  maxv = phi_range.upper_bound ();
 		}
 	      else
 		{
-		  minv = wi::max (minv, minc, sgn);
-		  maxv = wi::min (maxv, maxc, sgn);
+		  minv = wi::max (minv, phi_range.lower_bound (), sgn);
+		  maxv = wi::min (maxv, phi_range.upper_bound (), sgn);
 		  /* If the PHI result range are inconsistent with
 		     the VAR range, give up on looking at the PHI
 		     results.  This can happen if VR_UNDEFINED is
 		     involved.  */
 		  if (wi::gt_p (minv, maxv, sgn))
 		    {
-		      rtype = get_range_info (var, &minv, &maxv);
+		      value_range vr;
+		      RANGE_QUERY (cfun)->range_of_expr (vr, var);
+		      rtype = vr.kind ();
+		      if (!vr.undefined_p ())
+			{
+			  minv = vr.lower_bound ();
+			  maxv = vr.upper_bound ();
+			}
 		      break;
 		    }
 		}
@@ -3545,12 +3563,16 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt,
 
   if (tree_int_cst_sign_bit (step))
     {
-      wide_int min, max;
+      wide_int max;
+      value_range base_range;
+      if (RANGE_QUERY (cfun)->range_of_expr (base_range, orig_base)
+	  && !base_range.undefined_p ())
+	max = base_range.upper_bound ();
       extreme = fold_convert (unsigned_type, low);
       if (TREE_CODE (orig_base) == SSA_NAME
 	  && TREE_CODE (high) == INTEGER_CST
 	  && INTEGRAL_TYPE_P (TREE_TYPE (orig_base))
-	  && (get_range_info (orig_base, &min, &max) == VR_RANGE
+	  && (base_range.kind () == VR_RANGE
 	      || get_cst_init_from_scev (orig_base, &max, false))
 	  && wi::gts_p (wi::to_wide (high), max))
 	base = wide_int_to_tree (unsigned_type, max);
@@ -3563,12 +3585,16 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt,
     }
   else
     {
-      wide_int min, max;
+      wide_int min;
+      value_range base_range;
+      if (RANGE_QUERY (cfun)->range_of_expr (base_range, orig_base)
+	  && !base_range.undefined_p ())
+	min = base_range.lower_bound ();
       extreme = fold_convert (unsigned_type, high);
       if (TREE_CODE (orig_base) == SSA_NAME
 	  && TREE_CODE (low) == INTEGER_CST
 	  && INTEGRAL_TYPE_P (TREE_TYPE (orig_base))
-	  && (get_range_info (orig_base, &min, &max) == VR_RANGE
+	  && (base_range.kind () == VR_RANGE
 	      || get_cst_init_from_scev (orig_base, &min, true))
 	  && wi::gts_p (min, wi::to_wide (low)))
 	base = wide_int_to_tree (unsigned_type, min);
@@ -3835,11 +3861,12 @@ infer_loop_bounds_from_signedness (class loop *loop, gimple *stmt)
 
   low = lower_bound_in_type (type, type);
   high = upper_bound_in_type (type, type);
-  wide_int minv, maxv;
-  if (get_range_info (def, &minv, &maxv) == VR_RANGE)
+  value_range r;
+  RANGE_QUERY (cfun)->range_of_expr (r, def);
+  if (r.kind () == VR_RANGE)
     {
-      low = wide_int_to_tree (type, minv);
-      high = wide_int_to_tree (type, maxv);
+      low = wide_int_to_tree (type, r.lower_bound ());
+      high = wide_int_to_tree (type, r.upper_bound ());
     }
 
   record_nonwrapping_iv (loop, base, step, stmt, low, high, false, true);
@@ -4873,7 +4900,6 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop)
 {
   tree type;
   wide_int minv, maxv, diff, step_wi;
-  enum value_range_kind rtype;
 
   if (TREE_CODE (step) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (var)))
     return false;
@@ -4884,8 +4910,9 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop)
   if (!def_bb || !dominated_by_p (CDI_DOMINATORS, loop->latch, def_bb))
     return false;
 
-  rtype = get_range_info (var, &minv, &maxv);
-  if (rtype != VR_RANGE)
+  value_range r;
+  RANGE_QUERY (cfun)->range_of_expr (r, var);
+  if (r.kind () != VR_RANGE)
     return false;
 
   /* VAR is a scev whose evolution part is STEP and value range info
@@ -4899,11 +4926,11 @@ scev_var_range_cant_overflow (tree var, tree step, class loop *loop)
   type = TREE_TYPE (var);
   if (tree_int_cst_sign_bit (step))
     {
-      diff = minv - wi::to_wide (lower_bound_in_type (type, type));
+      diff = r.lower_bound () - wi::to_wide (lower_bound_in_type (type, type));
       step_wi = - step_wi;
     }
   else
-    diff = wi::to_wide (upper_bound_in_type (type, type)) - maxv;
+    diff = wi::to_wide (upper_bound_in_type (type, type)) - r.upper_bound ();
 
   return (wi::geu_p (diff, step_wi));
 }
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 8e8a08bc679..d464c84f164 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-eh.h"
 #include "gimple-fold.h"
 #include "internal-fn.h"
+#include "gimple-range.h"
 
 static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
 static bool two_value_replacement (basic_block, basic_block, edge, gphi *,
@@ -684,7 +685,15 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb,
     return false;
 
   wide_int min, max;
-  if (get_range_info (lhs, &min, &max) != VR_RANGE)
+  value_range r;
+  RANGE_QUERY (cfun)->range_of_expr (r, lhs);
+
+  if (r.kind () == VR_RANGE)
+    {
+      min = r.lower_bound ();
+      max = r.upper_bound ();
+    }
+  else
     {
       int prec = TYPE_PRECISION (TREE_TYPE (lhs));
       signop sgn = TYPE_SIGN (TREE_TYPE (lhs));
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 2d22535af87..870d3cba9ff 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-dce.h"
 #include "tree-cfgcleanup.h"
 #include "alias.h"
+#include "gimple-range.h"
 
 /* Even though this file is called tree-ssa-pre.c, we actually
    implement a bit more than just PRE here.  All of them piggy-back
@@ -3234,16 +3235,18 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
 	  >= TYPE_PRECISION (TREE_TYPE (expr->u.nary->op[0])))
       && SSA_NAME_RANGE_INFO (expr->u.nary->op[0]))
     {
-      wide_int min, max;
-      if (get_range_info (expr->u.nary->op[0], &min, &max) == VR_RANGE
-	  && !wi::neg_p (min, SIGNED)
-	  && !wi::neg_p (max, SIGNED))
+      value_range r;
+      if (RANGE_QUERY (cfun)->range_of_expr (r, expr->u.nary->op[0])
+	  && r.kind () == VR_RANGE
+	  && !wi::neg_p (r.lower_bound (), SIGNED)
+	  && !wi::neg_p (r.upper_bound (), SIGNED))
 	/* Just handle extension and sign-changes of all-positive ranges.  */
-	set_range_info (temp,
-			SSA_NAME_RANGE_TYPE (expr->u.nary->op[0]),
-			wide_int_storage::from (min, TYPE_PRECISION (type),
+	set_range_info (temp, VR_RANGE,
+			wide_int_storage::from (r.lower_bound (),
+						TYPE_PRECISION (type),
 						TYPE_SIGN (type)),
-			wide_int_storage::from (max, TYPE_PRECISION (type),
+			wide_int_storage::from (r.upper_bound (),
+						TYPE_PRECISION (type),
 						TYPE_SIGN (type)));
     }
 
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 32e1632705b..cc098369e2e 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "case-cfn-macros.h"
 #include "tree-ssa-reassoc.h"
 #include "tree-ssa-math-opts.h"
+#include "gimple-range.h"
 
 /*  This is a simple global reassociation pass.  It is, in part, based
     on the LLVM pass of the same name (They do some things more/less
@@ -3221,12 +3222,14 @@ optimize_range_tests_to_bit_test (enum tree_code opcode, int first, int length,
 	 amount, then we can merge the entry test in the bit test.  In this
 	 case, if we would need otherwise 2 or more comparisons, then use
 	 the bit test; in the other cases, the threshold is 3 comparisons.  */
-      wide_int min, max;
       bool entry_test_needed;
+      value_range r;
       if (TREE_CODE (exp) == SSA_NAME
-	  && get_range_info (exp, &min, &max) == VR_RANGE
-	  && wi::leu_p (max - min, prec - 1))
+	  && RANGE_QUERY (cfun)->range_of_expr (r, exp)
+	  && r.kind () == VR_RANGE
+	  && wi::leu_p (r.upper_bound () - r.lower_bound (), prec - 1))
 	{
+	  wide_int min = r.lower_bound ();
 	  wide_int ilowi = wi::to_wide (lowi);
 	  if (wi::lt_p (min, ilowi, TYPE_SIGN (TREE_TYPE (lowi))))
 	    {
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index c7b5e2c6e6b..2f85a609107 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -196,7 +196,7 @@ static void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator *);
 /* Sets MINMAX to either the constant value or the range VAL is in
    and returns either the constant value or VAL on success or null
    when the range couldn't be determined.  Uses RVALS when nonnull
-   to determine the range, otherwise get_range_info.  */
+   to determine the range, otherwise uses global range info.  */
 
 tree
 get_range (tree val, gimple *stmt, wide_int minmax[2],
@@ -211,9 +211,9 @@ get_range (tree val, gimple *stmt, wide_int minmax[2],
   if (TREE_CODE (val) != SSA_NAME)
     return NULL_TREE;
 
+  value_range vr;
   if (rvals && stmt)
     {
-      value_range vr;
       if (!rvals->range_of_expr (vr, val, stmt))
 	return NULL_TREE;
       value_range_kind rng = vr.kind ();
@@ -225,7 +225,15 @@ get_range (tree val, gimple *stmt, wide_int minmax[2],
       return val;
     }
 
-  value_range_kind rng = get_range_info (val, minmax, minmax + 1);
+  // ?? This entire function should use RANGE_QUERY or GLOBAL_RANGE_QUERY,
+  // instead of doing something different for RVALS and global ranges.
+
+  if (!GLOBAL_RANGE_QUERY->range_of_expr (vr, val) || vr.undefined_p ())
+    return NULL_TREE;
+
+  minmax[0] = wi::to_wide (vr.min ());
+  minmax[1] = wi::to_wide (vr.max ());
+  value_range_kind rng = vr.kind ();
   if (rng == VR_RANGE)
     /* This may be an inverted range whose MINMAX[1] < MINMAX[0].  */
     return val;
@@ -929,7 +937,17 @@ dump_strlen_info (FILE *fp, gimple *stmt, range_query *rvals)
 			    rng = VR_UNDEFINED;
 			}
 		      else
-			rng = get_range_info (si->nonzero_chars, &min, &max);
+			{
+			  value_range vr;
+			  GLOBAL_RANGE_QUERY->range_of_expr (vr,
+							     si->nonzero_chars);
+			  rng = vr.kind ();
+			  if (!vr.undefined_p ())
+			    {
+			      min = wi::to_wide (vr.min ());
+			      max = wi::to_wide (vr.max ());
+			    }
+			}
 
 		      if (rng == VR_RANGE || rng == VR_ANTI_RANGE)
 			{
@@ -1809,18 +1827,17 @@ set_strlen_range (tree lhs, wide_int min, wide_int max,
 	}
       else if (TREE_CODE (bound) == SSA_NAME)
 	{
-	  wide_int minbound, maxbound;
-	  // FIXME: Use range_query instead of global ranges.
-	  value_range_kind rng = get_range_info (bound, &minbound, &maxbound);
-	  if (rng == VR_RANGE)
+	  value_range r;
+	  RANGE_QUERY (cfun)->range_of_expr (r, bound);
+	  if (!r.undefined_p ())
 	    {
 	      /* For a bound in a known range, adjust the range determined
 		 above as necessary.  For a bound in some anti-range or
 		 in an unknown range, use the range determined by callers.  */
-	      if (wi::ltu_p (minbound, min))
-		min = minbound;
-	      if (wi::ltu_p (maxbound, max))
-		max = maxbound;
+	      if (wi::ltu_p (r.lower_bound (), min))
+		min = r.lower_bound ();
+	      if (wi::ltu_p (r.upper_bound (), max))
+		max = r.upper_bound ();
 	    }
 	}
     }
@@ -2780,12 +2797,15 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
     return false;
 
   wide_int cntrange[2];
+  value_range r;
+  if (!RANGE_QUERY (cfun)->range_of_expr (r, cnt)
+      || r.varying_p ()
+      || r.undefined_p ())
+    return false;
 
-  // FIXME: Use range_query instead of global ranges.
-  enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1);
-  if (rng == VR_RANGE)
-    ;
-  else if (rng == VR_ANTI_RANGE)
+  cntrange[0] = wi::to_wide (r.min ());
+  cntrange[1] = wi::to_wide (r.max ());
+  if (r.kind () == VR_ANTI_RANGE)
     {
       wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node));
 
@@ -2800,8 +2820,6 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
 	  cntrange[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt)));
 	}
     }
-  else
-    return false;
 
   /* Negative value is the constant string length.  If it's less than
      the lower bound there is no truncation.  Avoid calling get_stridx()
@@ -3923,13 +3941,12 @@ get_len_or_size (gimple *stmt, tree arg, int idx,
 	}
       else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
 	{
-	  wide_int min, max;
-	  // FIXME: Use range_query instead of global ranges.
-	  value_range_kind rng = get_range_info (si->nonzero_chars, &min, &max);
-	  if (rng == VR_RANGE)
+	  value_range r;
+	  RANGE_QUERY (cfun)->range_of_expr (r, si->nonzero_chars);
+	  if (r.kind () == VR_RANGE)
 	    {
-	      lenrng[0] = min.to_uhwi ();
-	      lenrng[1] = max.to_uhwi ();
+	      lenrng[0] = r.lower_bound ().to_uhwi ();
+	      lenrng[1] = r.upper_bound ().to_uhwi ();
 	      *nulterm = si->full_string_p;
 	    }
 	}
@@ -5301,17 +5318,13 @@ handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
 		  /* Reading a character before the final '\0'
 		     character.  Just set the value range to ~[0, 0]
 		     if we don't have anything better.  */
-		  wide_int min, max;
-		  signop sign = TYPE_SIGN (lhs_type);
-		  int prec = TYPE_PRECISION (lhs_type);
-		  // FIXME: Use range_query instead of global ranges.
-		  value_range_kind vr = get_range_info (lhs, &min, &max);
-		  if (vr == VR_VARYING
-		      || (vr == VR_RANGE
-			  && min == wi::min_value (prec, sign)
-			  && max == wi::max_value (prec, sign)))
-		    set_range_info (lhs, VR_ANTI_RANGE,
-				    wi::zero (prec), wi::zero (prec));
+		  value_range r;
+		  if (!RANGE_QUERY (cfun)->range_of_expr (r, lhs)
+		      || r.varying_p ())
+		    {
+		      r.set_nonzero (lhs_type);
+		      set_range_info (lhs, r);
+		    }
 		}
 	    }
 	}
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index a0238710e72..d8292777647 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -43,6 +43,7 @@
 #include "attribs.h"
 #include "tree-ssa.h"
 #include "tree-cfg.h"
+#include "gimple-range.h"
 
 /* The idea behind this analyzer is to generate set constraints from the
    program, then solve the resulting constraints in order to generate the
@@ -6740,7 +6741,9 @@ find_what_p_points_to (tree fndecl, tree p)
   struct ptr_info_def *pi;
   tree lookup_p = p;
   varinfo_t vi;
-  bool nonnull = get_ptr_nonnull (p);
+  value_range vr;
+  RANGE_QUERY (DECL_STRUCT_FUNCTION (fndecl))->range_of_expr (vr, p);
+  bool nonnull = vr.nonzero_p ();
 
   /* For parameters, get at the points-to set for the actual parm
      decl.  */
@@ -6758,8 +6761,7 @@ find_what_p_points_to (tree fndecl, tree p)
   pi->pt = find_what_var_points_to (fndecl, vi);
   /* Conservatively set to NULL from PTA (to true). */
   pi->pt.null = 1;
-  /* Preserve pointer nonnull computed by VRP.  See get_ptr_nonnull
-     in gcc/tree-ssaname.c for more information.  */
+  /* Preserve pointer nonnull globally computed.  */
   if (nonnull)
     set_ptr_nonnull (p);
 }
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index f55ce1939ac..b352f68b1b7 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "builtins.h"
 #include "calls.h"
+#include "gimple-range.h"
 
 /* This implements the pass that does predicate aware warning on uses of
    possibly uninitialized variables.  The pass first collects the set of
@@ -1606,11 +1607,14 @@ find_var_cmp_const (pred_chain_union preds, gphi *phi, gimple **flag_def,
 	       flag_var <= [min, max] ->  flag_var < [min, max+1]
 	       flag_var >= [min, max] ->  flag_var > [min-1, max]
 	     if no overflow/wrap.  */
-	  wide_int min, max;
 	  tree type = TREE_TYPE (cond_lhs);
+	  value_range r;
 	  if (!INTEGRAL_TYPE_P (type)
-	      || get_range_info (cond_rhs, &min, &max) != VR_RANGE)
+	      || !RANGE_QUERY (cfun)->range_of_expr (r, cond_rhs)
+	      || r.kind () != VR_RANGE)
 	    continue;
+	  wide_int min = r.lower_bound ();
+	  wide_int max = r.upper_bound ();
 	  if (code == LE_EXPR
 	      && max != wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type)))
 	    {
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 7f65c4ce839..225d831003f 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -50,6 +50,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "target.h"
 #include "tree-into-ssa.h"
 #include "omp-general.h"
+#include "gimple-range.h"
 
 /* ??? For lang_hooks.types.type_for_mode, but is there a word_mode
    type in the GIMPLE type system that is language-independent?  */
@@ -1553,12 +1554,15 @@ bit_test_cluster::emit (tree index_expr, tree index_type,
 
   /* If every possible relative value of the index expression is a valid shift
      amount, then we can merge the entry test in the bit test.  */
-  wide_int min, max;
   bool entry_test_needed;
+  value_range r;
   if (TREE_CODE (index_expr) == SSA_NAME
-      && get_range_info (index_expr, &min, &max) == VR_RANGE
-      && wi::leu_p (max - min, prec - 1))
+      && RANGE_QUERY (cfun)->range_of_expr (r, index_expr)
+      && r.kind () == VR_RANGE
+      && wi::leu_p (r.upper_bound () - r.lower_bound (), prec - 1))
     {
+      wide_int min = r.lower_bound ();
+      wide_int max = r.upper_bound ();
       tree index_type = TREE_TYPE (index_expr);
       minval = fold_convert (index_type, minval);
       wide_int iminval = wi::to_wide (minval);
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 803de3fc287..99be2314029 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "predict.h"
 #include "tree-vector-builder.h"
 #include "vec-perm-indices.h"
+#include "gimple-range.h"
 
 /* Return true if we have a useful VR_RANGE range for VAR, storing it
    in *MIN_VALUE and *MAX_VALUE if so.  Note the range in the dump files.  */
@@ -55,7 +56,13 @@ along with GCC; see the file COPYING3.  If not see
 static bool
 vect_get_range_info (tree var, wide_int *min_value, wide_int *max_value)
 {
-  value_range_kind vr_type = get_range_info (var, min_value, max_value);
+  value_range vr;
+  RANGE_QUERY (cfun)->range_of_expr (vr, var);
+  if (vr.undefined_p ())
+    vr.set_varying (TREE_TYPE (var));
+  *min_value = wi::to_wide (vr.min ());
+  *max_value = wi::to_wide (vr.max ());
+  value_range_kind vr_type = vr.kind ();
   wide_int nonzero = get_nonzero_bits (var);
   signop sgn = TYPE_SIGN (TREE_TYPE (var));
   if (intersect_range_with_nonzero_bits (vr_type, min_value, max_value,
@@ -3437,13 +3444,14 @@ vect_recog_divmod_pattern (vec_info *vinfo,
       else
 	t3 = t2;
 
-      wide_int oprnd0_min, oprnd0_max;
       int msb = 1;
-      if (get_range_info (oprnd0, &oprnd0_min, &oprnd0_max) == VR_RANGE)
+      value_range r;
+      RANGE_QUERY (cfun)->range_of_expr (r, oprnd0);
+      if (r.kind () == VR_RANGE)
 	{
-	  if (!wi::neg_p (oprnd0_min, TYPE_SIGN (itype)))
+	  if (!wi::neg_p (r.lower_bound (), TYPE_SIGN (itype)))
 	    msb = 0;
-	  else if (wi::neg_p (oprnd0_max, TYPE_SIGN (itype)))
+	  else if (wi::neg_p (r.upper_bound (), TYPE_SIGN (itype)))
 	    msb = -1;
 	}
 
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index b0f1c47f05c..6a723efc0d8 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -228,7 +228,7 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type,
 	  vr_type = VR_RANGE;
 	}
     }
-  if (vr_type == VR_RANGE)
+  if (vr_type == VR_RANGE || vr_type == VR_VARYING)
     {
       *max = wi::round_down_for_mask (*max, nonzero_bits);
 
@@ -1717,7 +1717,7 @@ register_edge_assert_for_2 (tree name, edge e,
          simply register the same assert for it.  */
       if (CONVERT_EXPR_CODE_P (rhs_code))
 	{
-	  wide_int rmin, rmax;
+	  value_range vr;
 	  tree rhs1 = gimple_assign_rhs1 (def_stmt);
 	  if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
 	      && TREE_CODE (rhs1) == SSA_NAME
@@ -1739,13 +1739,14 @@ register_edge_assert_for_2 (tree name, edge e,
 	      && int_fits_type_p (val, TREE_TYPE (rhs1))
 	      && ((TYPE_PRECISION (TREE_TYPE (name))
 		   > TYPE_PRECISION (TREE_TYPE (rhs1)))
-		  || (get_range_info (rhs1, &rmin, &rmax) == VR_RANGE
+		  || ((RANGE_QUERY (cfun)->range_of_expr (vr, rhs1)
+		       && vr.kind () == VR_RANGE)
 		      && wi::fits_to_tree_p
-			   (widest_int::from (rmin,
+			   (widest_int::from (vr.lower_bound (),
 					      TYPE_SIGN (TREE_TYPE (rhs1))),
 			    TREE_TYPE (name))
 		      && wi::fits_to_tree_p
-			   (widest_int::from (rmax,
+			   (widest_int::from (vr.upper_bound (),
 					      TYPE_SIGN (TREE_TYPE (rhs1))),
 			    TREE_TYPE (name)))))
 	    add_assert_info (asserts, rhs1, rhs1,
@@ -4631,16 +4632,14 @@ determine_value_range_1 (value_range *vr, tree expr)
     vr->set (expr);
   else
     {
-      value_range_kind kind;
-      wide_int min, max;
+      value_range r;
       /* For SSA names try to extract range info computed by VRP.  Otherwise
 	 fall back to varying.  */
       if (TREE_CODE (expr) == SSA_NAME
 	  && INTEGRAL_TYPE_P (TREE_TYPE (expr))
-	  && (kind = get_range_info (expr, &min, &max)) != VR_VARYING)
-	vr->set (wide_int_to_tree (TREE_TYPE (expr), min),
-		 wide_int_to_tree (TREE_TYPE (expr), max),
-		 kind);
+	  && RANGE_QUERY (cfun)->range_of_expr (r, expr)
+	  && !r.undefined_p ())
+	*vr = r;
       else
 	vr->set_varying (TREE_TYPE (expr));
     }
diff --git a/gcc/tree.c b/gcc/tree.c
index 31ac4245c9c..3d5111628b5 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -68,6 +68,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-vector-builder.h"
 #include "gimple-fold.h"
 #include "escaped_string.h"
+#include "gimple-range.h"
 
 /* Tree code classes.  */
 
@@ -13834,8 +13835,8 @@ get_range_pos_neg (tree arg)
 
   if (TREE_CODE (arg) != SSA_NAME)
     return 3;
-  wide_int arg_min, arg_max;
-  while (get_range_info (arg, &arg_min, &arg_max) != VR_RANGE)
+  value_range r;
+  while (!GLOBAL_RANGE_QUERY->range_of_expr (r, arg) || r.kind () != VR_RANGE)
     {
       gimple *g = SSA_NAME_DEF_STMT (arg);
       if (is_gimple_assign (g)
@@ -13861,16 +13862,16 @@ get_range_pos_neg (tree arg)
     {
       /* For unsigned values, the "positive" range comes
 	 below the "negative" range.  */
-      if (!wi::neg_p (wi::sext (arg_max, prec), SIGNED))
+      if (!wi::neg_p (wi::sext (r.upper_bound (), prec), SIGNED))
 	return 1;
-      if (wi::neg_p (wi::sext (arg_min, prec), SIGNED))
+      if (wi::neg_p (wi::sext (r.lower_bound (), prec), SIGNED))
 	return 2;
     }
   else
     {
-      if (!wi::neg_p (wi::sext (arg_min, prec), SIGNED))
+      if (!wi::neg_p (wi::sext (r.lower_bound (), prec), SIGNED))
 	return 1;
-      if (wi::neg_p (wi::sext (arg_max, prec), SIGNED))
+      if (wi::neg_p (wi::sext (r.upper_bound (), prec), SIGNED))
 	return 2;
     }
   return 3;
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index a89f0b646ae..02acb46cb20 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -117,14 +117,16 @@ vr_values::get_lattice_entry (const_tree var)
 	     default definitions of PARM_DECLs.  */
 	  if (POINTER_TYPE_P (TREE_TYPE (sym))
 	      && (nonnull_arg_p (sym)
-		  || get_ptr_nonnull (var)))
+		  || (GLOBAL_RANGE_QUERY->range_of_expr (*vr,
+						const_cast <tree> (var))
+		      && vr->nonzero_p ())))
 	    {
 	      vr->set_nonzero (TREE_TYPE (sym));
 	      vr->equiv_clear ();
 	    }
 	  else if (INTEGRAL_TYPE_P (TREE_TYPE (sym)))
 	    {
-	      get_range_info (var, *vr);
+	      GLOBAL_RANGE_QUERY->range_of_expr (*vr, const_cast <tree> (var));
 	      if (vr->undefined_p ())
 		vr->set_varying (TREE_TYPE (sym));
 	    }
@@ -262,7 +264,7 @@ vr_values::update_value_range (const_tree var, value_range_equiv *new_vr)
   if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
     {
       value_range_equiv nr;
-      get_range_info (var, nr);
+      GLOBAL_RANGE_QUERY->range_of_expr (nr, const_cast <tree> (var));
       if (!nr.undefined_p ())
 	new_vr->intersect (&nr);
     }
@@ -3829,13 +3831,13 @@ simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
     return false;
 
-  /* Get the value-range of the inner operand.  Use get_range_info in
+  /* Get the value-range of the inner operand.  Use global ranges in
      case innerop was created during substitute-and-fold.  */
   wide_int imin, imax;
   value_range vr;
   if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop)))
     return false;
-  get_range_info (innerop, vr);
+  RANGE_QUERY (cfun)->range_of_expr (vr, innerop, stmt);
   if (vr.undefined_p () || vr.varying_p ())
     return false;
   innermin = widest_int::from (vr.lower_bound (), TYPE_SIGN (TREE_TYPE (innerop)));
-- 
2.31.1


  parent reply	other threads:[~2021-05-25 11:26 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-21 11:39 [PATCH 1/5] Common API for accessing global and on-demand ranges Aldy Hernandez
2021-05-21 11:39 ` [PATCH 2/5] Convert Walloca pass to RANGE_QUERY(cfun) Aldy Hernandez
2021-05-25  8:43   ` Richard Biener
2021-05-25 16:17   ` Aldy Hernandez
2021-05-25 16:28     ` Jeff Law
2021-05-25 17:28     ` Martin Sebor
2021-05-27  7:38     ` Christophe Lyon
2021-05-27  8:34       ` Aldy Hernandez
2021-05-21 11:39 ` [PATCH 3/5] Convert evrp " Aldy Hernandez
2021-05-25 16:18   ` Aldy Hernandez
2021-05-27  2:34     ` H.J. Lu
2021-05-21 11:39 ` [PATCH 4/5] Convert remaining passes to RANGE_QUERY Aldy Hernandez
2021-05-24 19:34   ` Martin Sebor
2021-05-25  8:47     ` Richard Biener
2021-05-25  9:15       ` Aldy Hernandez
2021-05-25 11:26       ` Aldy Hernandez [this message]
2021-05-25  8:48     ` Aldy Hernandez
2021-05-25 16:19   ` Aldy Hernandez
2021-05-21 11:39 ` [PATCH 5/5] Cleanup get_range_info Aldy Hernandez
2021-05-25 16:20   ` Aldy Hernandez
2021-05-24 16:09 ` [PATCH 1/5] Common API for accessing global and on-demand ranges Aldy Hernandez
2021-05-25  8:57   ` Richard Biener
2021-05-25  9:36     ` Aldy Hernandez
2021-05-25  9:46       ` Richard Biener
2021-05-25 10:53         ` Aldy Hernandez
2021-05-25 11:06           ` Richard Biener
2021-05-25 16:16             ` Aldy Hernandez
2021-05-26 13:40               ` Andrew MacLeod
2021-05-29  4:35               ` Jeff Law
2021-05-24 19:13 ` Martin Sebor
2021-05-25  7:06   ` Aldy Hernandez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e44a5c3f-c9b4-b01e-4ce3-16966ef7d679@redhat.com \
    --to=aldyh@redhat.com \
    --cc=amacleod@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=msebor@gmail.com \
    --cc=msebor@redhat.com \
    --cc=richard.guenther@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).