Convert remaining passes to get_range_query.
This patch converts the remaining users of get_range_info and get_ptr_nonnull to the get_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 get_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 get_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.
This commit is contained in:
parent
fe9a499cb8
commit
45f4e2b01b
|
@ -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
|
||||
|
@ -1218,14 +1219,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;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -3831,9 +3833,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;
|
||||
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)
|
||||
{
|
||||
|
@ -3901,7 +3906,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;
|
||||
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 ())
|
||||
|
@ -4920,8 +4934,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
|
||||
|
|
|
@ -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)
|
||||
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;
|
||||
|
|
|
@ -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)
|
||||
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 ();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
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))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
;
|
||||
&& 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));
|
||||
|
|
|
@ -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 (!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)
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
&& 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;
|
||||
|
@ -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))
|
||||
&& 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
|
||||
|
|
19
gcc/match.pd
19
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)
|
||||
&& 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;
|
||||
|
@ -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 (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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|| !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);
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
@ -535,14 +536,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 = 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
|
||||
|
|
|
@ -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)
|
||||
|| !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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
&& 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
|
||||
{
|
||||
|
@ -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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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 (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);
|
||||
|
@ -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 (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);
|
||||
|
@ -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;
|
||||
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);
|
||||
|
@ -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;
|
||||
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
|
||||
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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));
|
||||
|
|
|
@ -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 (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)));
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
&& 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))))
|
||||
{
|
||||
|
|
|
@ -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 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;
|
||||
|
@ -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;
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 (!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));
|
||||
|
||||
|
@ -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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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 (!get_range_query (cfun)->range_of_expr (r, lhs)
|
||||
|| r.varying_p ())
|
||||
{
|
||||
r.set_nonzero (lhs_type);
|
||||
set_range_info (lhs, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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. */
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|| !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)))
|
||||
{
|
||||
|
|
|
@ -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))
|
||||
&& 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);
|
||||
|
|
|
@ -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;
|
||||
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,
|
||||
|
@ -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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|| ((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,
|
||||
|
@ -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);
|
||||
&& get_range_query (cfun)->range_of_expr (r, expr)
|
||||
&& !r.undefined_p ())
|
||||
*vr = r;
|
||||
else
|
||||
vr->set_varying (TREE_TYPE (expr));
|
||||
}
|
||||
|
|
13
gcc/tree.c
13
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. */
|
||||
|
||||
|
@ -13831,8 +13832,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 (!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)
|
||||
|
@ -13858,16 +13859,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;
|
||||
|
|
|
@ -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)))
|
||||
|| (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));
|
||||
}
|
||||
|
@ -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);
|
||||
get_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);
|
||||
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)));
|
||||
|
|
Loading…
Reference in New Issue