#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
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;
+
+ get_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)
{
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;
+ get_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)
{
*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;
+ get_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 ())
/* 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
#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. */
case SSA_NAME:
if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
return false;
- get_range_info (t, vr);
+
+ if (cfun)
+ get_range_query (cfun)->range_of_expr (vr, t);
+ else
+ get_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;
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)
+ get_range_query (cfun)->range_of_expr (vr, size);
+ else
+ get_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 ();
}
#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
#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. */
&& 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;
+ get_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)
/* 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);
+ get_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))
{
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)
- ;
+ && get_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));
#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[] = {
}
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 (!get_global_range_query ()->range_of_expr (r, arg)
+ || r.kind () != VR_RANGE)
{
gimple *g = SSA_NAME_DEF_STMT (arg);
if (is_gimple_assign (g)
}
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);
#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;
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;
+
+ get_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)
{
#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;
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;
if (TREE_CODE (arg) == SSA_NAME
&& param_type
- && get_ptr_nonnull (arg))
+ && get_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;
}
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))
+ && get_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
(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)
+ && get_global_range_query ()->range_of_expr (vr0, @0)
+ && get_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;
= 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 (get_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);
}
*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;
+ get_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);
}
}
/* 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)
+ || !get_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);
#include "gimple-iterator.h"
#include "gimple-walk.h"
#include "tree-dfa.h"
+#include "gimple-range.h"
/* Build and maintain data flow information for trees. */
index. */
seen_variable_array_ref = true;
- wide_int min, max;
+ value_range vr;
+ range_query *query;
+ if (cfun)
+ query = get_range_query (cfun);
+ else
+ query = get_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
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)
+ || !get_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)
+ || !get_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;
#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
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);
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))
{
}
else if (TREE_CODE (varc1) == SSA_NAME
&& INTEGRAL_TYPE_P (type)
- && get_range_info (varc1, &minv, &maxv) == VR_RANGE)
+ && get_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
{
gphi_iterator gsi;
/* Either for VAR itself... */
- rtype = get_range_info (var, &minv, &maxv);
+ value_range var_range;
+ get_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))
+ && get_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;
+ get_range_query (cfun)->range_of_expr (vr, var);
+ rtype = vr.kind ();
+ if (!vr.undefined_p ())
+ {
+ minv = vr.lower_bound ();
+ maxv = vr.upper_bound ();
+ }
break;
}
}
if (tree_int_cst_sign_bit (step))
{
- wide_int min, max;
+ wide_int max;
+ value_range base_range;
+ if (get_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);
}
else
{
- wide_int min, max;
+ wide_int min;
+ value_range base_range;
+ if (get_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);
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;
+ get_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);
{
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;
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;
+ get_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
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));
}
#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 *,
return false;
wide_int min, max;
- if (get_range_info (lhs, &min, &max) != VR_RANGE)
+ value_range r;
+ get_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));
#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
>= 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 (get_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)));
}
#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
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))
+ && get_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))))
{
/* 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],
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 ();
return val;
}
- value_range_kind rng = get_range_info (val, minmax, minmax + 1);
+ // ?? This entire function should use get_range_query or get_global_range_query (),
+ // instead of doing something different for RVALS and global ranges.
+
+ if (!get_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;
rng = VR_UNDEFINED;
}
else
- rng = get_range_info (si->nonzero_chars, &min, &max);
+ {
+ value_range vr;
+ get_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)
{
}
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;
+ get_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 ();
}
}
}
return false;
wide_int cntrange[2];
+ value_range r;
+ if (!get_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));
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()
}
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;
+ get_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;
}
}
/* 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 (!get_range_query (cfun)->range_of_expr (r, lhs)
+ || r.varying_p ())
+ {
+ r.set_nonzero (lhs_type);
+ set_range_info (lhs, r);
+ }
}
}
}
#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
struct ptr_info_def *pi;
tree lookup_p = p;
varinfo_t vi;
- bool nonnull = get_ptr_nonnull (p);
+ value_range vr;
+ get_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. */
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);
}
#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
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)
+ || !get_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)))
{
#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? */
/* 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))
+ && get_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);
#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. */
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;
+ get_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,
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;
+ get_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;
}
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);
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
&& 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
+ || ((get_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,
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);
+ && get_range_query (cfun)->range_of_expr (r, expr)
+ && !r.undefined_p ())
+ *vr = r;
else
vr->set_varying (TREE_TYPE (expr));
}
#include "tree-vector-builder.h"
#include "gimple-fold.h"
#include "escaped_string.h"
+#include "gimple-range.h"
/* Tree code classes. */
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 (!get_global_range_query ()->range_of_expr (r, arg) || r.kind () != VR_RANGE)
{
gimple *g = SSA_NAME_DEF_STMT (arg);
if (is_gimple_assign (g)
{
/* 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;
default definitions of PARM_DECLs. */
if (POINTER_TYPE_P (TREE_TYPE (sym))
&& (nonnull_arg_p (sym)
- || get_ptr_nonnull (var)))
+ || (get_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);
+ get_global_range_query ()->range_of_expr (*vr, const_cast <tree> (var));
if (vr->undefined_p ())
vr->set_varying (TREE_TYPE (sym));
}
if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
{
value_range_equiv nr;
- get_range_info (var, nr);
+ get_global_range_query ()->range_of_expr (nr, const_cast <tree> (var));
if (!nr.undefined_p ())
new_vr->intersect (&nr);
}
|| 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);
+ get_global_range_query ()->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)));