Commit 27922d51 by Richard Biener Committed by Richard Biener

2018-11=12 Richard Biener <rguenther@suse.de>

	* tree-vrp.h (value_range[_base]::set): Make public.  Provide
	overload for single value.
	(value_range[_base]::set_nonnull): New.
	(value_range[_base]::set_null): Likewise.
	(value_range): Document bitmap copying behavior, mark
	copy constructor and assignment operator deleted.
	(value_range::move): New.
	(value_range::set_and_canonicalize): Default bitmap to zero.
	(set_value_range_to_nonnull): Remove.
	(set_value_range_to_null): Likewise.
	(set_value_range): Likewise.
	(set_value_range_to_value): Likewise.
	(extract_range_from_unary_expr): Work on value_range_base.
	(extract_range_from_binary_expr_1): Likewise.  Rename to...
	(extract_range_from_binary_expr): ... this.
	* tree-vrp.c (value_range::update): Clear equiv bitmap
	if required.
	(value_range::move): New, move equiv bitmap.
	(value_range_base::set_undefined): Avoid assignment.
	(value_range::set_undefined): Likewise.
	(value_range_base::set_varying): Likewise.
	(value_range::set_varying): Likewise.
	(set_value_range): Remove.
	(value_range_base::set): New overload for value.
	(value_range::set): Likewise.
	(set_value_range_to_nonnull): Remove.
	(value_range_base::set_nonnull): New.
	(value_range::set_nonnull): Likewise.
	(set_value_range_to_null): Remove.
	(value_range_base::set_null): New.
	(value_range::set_null): Likewise.
	(range_is_null): Work on value_range_base.
	(range_is_nonnull): Likewise.
	(ranges_from_anti_range): Likewise.
	(extract_range_into_wide_ints): Likewise.
	(extract_range_from_multiplicative_op): Likewise.
	(extract_range_from_binary_expr): Likewise.  Update for API changes.
	(extract_range_from_unary_expr): Likewise.  Remove OBJ_TYPE_REF
	handling.
	(value_range::intersect_helper): Avoid copy and assignment.
	(value_range::union_helper): Likewise.
	(determine_value_range_1): Adjust.
	* gimple-ssa-evrp-analyze.c (evrp_range_analyzer::try_find_new_range):
	Avoid assignment by using move.
	(evrp_range_analyzer::record_ranges_from_stmt): Avoid assignment.
	* tree-ssa-threadedge.c (record_temporary_equivalences_from_phis):
	Likewise.
	* tree-ssanames.c (get_range_info): Likewise.
	* vr-values.h (vr_values::get_vr_for_comparison): Adjust API.
	* vr-values.c (vr_values::get_value_range): Adjust.
	(vr_values::update_value_range): Likewise.
	(symbolic_range_based_on_p): Work on value_range_base.
	(vr_values::extract_range_from_binary_expr): Use value_range_base.
	(vr_values::extract_range_from_unary_expr): Likewise.
	(vr_values::extract_range_from_cond_expr): Avoid assignment.
	(vr_values::extract_range_from_comparison): Adjust.
	(vr_values::check_for_binary_op_overflow): Use value_range_base.
	(vr_values::extract_range_basic): Adjust.
	(vr_values::adjust_range_with_scev): Likewise.
	(vr_values::vrp_visit_assignment_or_call): Likewise.
	(vr_values::get_vr_for_comparison): Change API to avoid
	assignment and copy construction.
	(vr_values::compare_name_with_value): Adjust accordingly.
	(vr_values::compare_names): Likewise.
	(vr_values::extract_range_from_phi_node): Avoid assignment and
	bogus in-place modify of equiv bitmap.
	(vr_values::simplify_bit_ops_using_ranges): Use value_range_base.
	* ipa-prop.c (ipa_compute_jump_functions_for_edge): Adjust
	for extract_range_from_unary_expr API change.
	* ipa-cp.c (ipa_vr_operation_and_type_effects): Likewise.

From-SVN: r266030
parent 03564d3f
2018-11-12 Richard Biener <rguenther@suse.de>
* tree-vrp.h (value_range[_base]::set): Make public. Provide
overload for single value.
(value_range[_base]::set_nonnull): New.
(value_range[_base]::set_null): Likewise.
(value_range): Document bitmap copying behavior, mark
copy constructor and assignment operator deleted.
(value_range::move): New.
(value_range::set_and_canonicalize): Default bitmap to zero.
(set_value_range_to_nonnull): Remove.
(set_value_range_to_null): Likewise.
(set_value_range): Likewise.
(set_value_range_to_value): Likewise.
(extract_range_from_unary_expr): Work on value_range_base.
(extract_range_from_binary_expr_1): Likewise. Rename to...
(extract_range_from_binary_expr): ... this.
* tree-vrp.c (value_range::update): Clear equiv bitmap
if required.
(value_range::move): New, move equiv bitmap.
(value_range_base::set_undefined): Avoid assignment.
(value_range::set_undefined): Likewise.
(value_range_base::set_varying): Likewise.
(value_range::set_varying): Likewise.
(set_value_range): Remove.
(value_range_base::set): New overload for value.
(value_range::set): Likewise.
(set_value_range_to_nonnull): Remove.
(value_range_base::set_nonnull): New.
(value_range::set_nonnull): Likewise.
(set_value_range_to_null): Remove.
(value_range_base::set_null): New.
(value_range::set_null): Likewise.
(range_is_null): Work on value_range_base.
(range_is_nonnull): Likewise.
(ranges_from_anti_range): Likewise.
(extract_range_into_wide_ints): Likewise.
(extract_range_from_multiplicative_op): Likewise.
(extract_range_from_binary_expr): Likewise. Update for API changes.
(extract_range_from_unary_expr): Likewise. Remove OBJ_TYPE_REF
handling.
(value_range::intersect_helper): Avoid copy and assignment.
(value_range::union_helper): Likewise.
(determine_value_range_1): Adjust.
* gimple-ssa-evrp-analyze.c (evrp_range_analyzer::try_find_new_range):
Avoid assignment by using move.
(evrp_range_analyzer::record_ranges_from_stmt): Avoid assignment.
* tree-ssa-threadedge.c (record_temporary_equivalences_from_phis):
Likewise.
* tree-ssanames.c (get_range_info): Likewise.
* vr-values.h (vr_values::get_vr_for_comparison): Adjust API.
* vr-values.c (vr_values::get_value_range): Adjust.
(vr_values::update_value_range): Likewise.
(symbolic_range_based_on_p): Work on value_range_base.
(vr_values::extract_range_from_binary_expr): Use value_range_base.
(vr_values::extract_range_from_unary_expr): Likewise.
(vr_values::extract_range_from_cond_expr): Avoid assignment.
(vr_values::extract_range_from_comparison): Adjust.
(vr_values::check_for_binary_op_overflow): Use value_range_base.
(vr_values::extract_range_basic): Adjust.
(vr_values::adjust_range_with_scev): Likewise.
(vr_values::vrp_visit_assignment_or_call): Likewise.
(vr_values::get_vr_for_comparison): Change API to avoid
assignment and copy construction.
(vr_values::compare_name_with_value): Adjust accordingly.
(vr_values::compare_names): Likewise.
(vr_values::extract_range_from_phi_node): Avoid assignment and
bogus in-place modify of equiv bitmap.
(vr_values::simplify_bit_ops_using_ranges): Use value_range_base.
* ipa-prop.c (ipa_compute_jump_functions_for_edge): Adjust
for extract_range_from_unary_expr API change.
* ipa-cp.c (ipa_vr_operation_and_type_effects): Likewise.
2018-11-12 Eric Botcazou <ebotcazou@adacore.com> 2018-11-12 Eric Botcazou <ebotcazou@adacore.com>
* config/mcore/mcore.h (WORD_REGISTER_OPERATIONS): Remove duplicate. * config/mcore/mcore.h (WORD_REGISTER_OPERATIONS): Remove duplicate.
...@@ -97,7 +97,7 @@ evrp_range_analyzer::try_find_new_range (tree name, ...@@ -97,7 +97,7 @@ evrp_range_analyzer::try_find_new_range (tree name,
&& vrp_operand_equal_p (old_vr->max (), vr.max ())) && vrp_operand_equal_p (old_vr->max (), vr.max ()))
return NULL; return NULL;
value_range *new_vr = vr_values->allocate_value_range (); value_range *new_vr = vr_values->allocate_value_range ();
*new_vr = vr; new_vr->move (&vr);
return new_vr; return new_vr;
} }
return NULL; return NULL;
...@@ -319,8 +319,8 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary) ...@@ -319,8 +319,8 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
also have to be very careful about sharing the underlying also have to be very careful about sharing the underlying
bitmaps. Ugh. */ bitmaps. Ugh. */
value_range *new_vr = vr_values->allocate_value_range (); value_range *new_vr = vr_values->allocate_value_range ();
*new_vr = vr; new_vr->set (vr.kind (), vr.min (), vr.max ());
new_vr->equiv_clear (); vr.equiv_clear ();
push_value_range (output, new_vr); push_value_range (output, new_vr);
} }
} }
......
...@@ -1876,12 +1876,8 @@ ipa_vr_operation_and_type_effects (value_range_base *dst_vr, ...@@ -1876,12 +1876,8 @@ ipa_vr_operation_and_type_effects (value_range_base *dst_vr,
enum tree_code operation, enum tree_code operation,
tree dst_type, tree src_type) tree dst_type, tree src_type)
{ {
/* ??? We'd want to use value_range_base on the VRP workers. */ extract_range_from_unary_expr (dst_vr, operation, dst_type,
value_range dst_tem; src_vr, src_type);
value_range src_tem (*src_vr);
extract_range_from_unary_expr (&dst_tem, operation, dst_type,
&src_tem, src_type);
*dst_vr = value_range_base (dst_tem.kind (), dst_tem.min (), dst_tem.max ());
if (dst_vr->varying_p () || dst_vr->undefined_p ()) if (dst_vr->varying_p () || dst_vr->undefined_p ())
return false; return false;
return true; return true;
......
...@@ -1885,12 +1885,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, ...@@ -1885,12 +1885,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
&& (type = get_range_info (arg, &min, &max)) && (type = get_range_info (arg, &min, &max))
&& (type == VR_RANGE || type == VR_ANTI_RANGE)) && (type == VR_RANGE || type == VR_ANTI_RANGE))
{ {
/* ??? We'd want to use value_range_base here but the value_range_base resvr;
VRP workers need to be adjusted first. */ value_range_base tmpvr (type,
value_range resvr; wide_int_to_tree (TREE_TYPE (arg), min),
value_range tmpvr (type, wide_int_to_tree (TREE_TYPE (arg), max));
wide_int_to_tree (TREE_TYPE (arg), min),
wide_int_to_tree (TREE_TYPE (arg), max));
extract_range_from_unary_expr (&resvr, NOP_EXPR, param_type, extract_range_from_unary_expr (&resvr, NOP_EXPR, param_type,
&tmpvr, TREE_TYPE (arg)); &tmpvr, TREE_TYPE (arg));
if (!resvr.undefined_p () && !resvr.varying_p ()) if (!resvr.undefined_p () && !resvr.varying_p ())
......
...@@ -166,7 +166,7 @@ record_temporary_equivalences_from_phis (edge e, ...@@ -166,7 +166,7 @@ record_temporary_equivalences_from_phis (edge e,
away in the VR stack. */ away in the VR stack. */
vr_values *vr_values = evrp_range_analyzer->get_vr_values (); vr_values *vr_values = evrp_range_analyzer->get_vr_values ();
value_range *new_vr = vr_values->allocate_value_range (); value_range *new_vr = vr_values->allocate_value_range ();
*new_vr = value_range (); new (new_vr) value_range ();
/* There are three cases to consider: /* There are three cases to consider:
...@@ -181,7 +181,7 @@ record_temporary_equivalences_from_phis (edge e, ...@@ -181,7 +181,7 @@ record_temporary_equivalences_from_phis (edge e,
if (TREE_CODE (src) == SSA_NAME) if (TREE_CODE (src) == SSA_NAME)
new_vr->deep_copy (vr_values->get_value_range (src)); new_vr->deep_copy (vr_values->get_value_range (src));
else if (TREE_CODE (src) == INTEGER_CST) else if (TREE_CODE (src) == INTEGER_CST)
set_value_range_to_value (new_vr, src, NULL); new_vr->set (src);
else else
new_vr->set_varying (); new_vr->set_varying ();
......
...@@ -447,7 +447,7 @@ get_range_info (const_tree name, value_range &vr) ...@@ -447,7 +447,7 @@ get_range_info (const_tree name, value_range &vr)
min = wide_int_to_tree (TREE_TYPE (name), wmin); min = wide_int_to_tree (TREE_TYPE (name), wmin);
max = wide_int_to_tree (TREE_TYPE (name), wmax); max = wide_int_to_tree (TREE_TYPE (name), wmax);
} }
vr = value_range (kind, min, max); vr.set (kind, min, max);
return kind; return kind;
} }
......
...@@ -134,12 +134,13 @@ value_range::value_range (const value_range_base &other) ...@@ -134,12 +134,13 @@ value_range::value_range (const value_range_base &other)
set (other.kind (), other.min(), other.max (), NULL); set (other.kind (), other.min(), other.max (), NULL);
} }
/* Like above, but keep the equivalences intact. */ /* Like set, but keep the equivalences in place. */
void void
value_range::update (value_range_kind kind, tree min, tree max) value_range::update (value_range_kind kind, tree min, tree max)
{ {
set (kind, min, max, m_equiv); set (kind, min, max,
(kind != VR_UNDEFINED && kind != VR_VARYING) ? m_equiv : NULL);
} }
/* Copy value_range in FROM into THIS while avoiding bitmap sharing. /* Copy value_range in FROM into THIS while avoiding bitmap sharing.
...@@ -154,6 +155,14 @@ value_range::deep_copy (const value_range *from) ...@@ -154,6 +155,14 @@ value_range::deep_copy (const value_range *from)
set (from->m_kind, from->min (), from->max (), from->m_equiv); set (from->m_kind, from->min (), from->max (), from->m_equiv);
} }
void
value_range::move (value_range *from)
{
set (from->m_kind, from->min (), from->max ());
m_equiv = from->m_equiv;
from->m_equiv = NULL;
}
/* Check the validity of the range. */ /* Check the validity of the range. */
void void
...@@ -262,27 +271,25 @@ value_range_base::constant_p () const ...@@ -262,27 +271,25 @@ value_range_base::constant_p () const
void void
value_range_base::set_undefined () value_range_base::set_undefined ()
{ {
*this = value_range_base (VR_UNDEFINED, NULL, NULL); set (VR_UNDEFINED, NULL, NULL);
} }
void void
value_range::set_undefined () value_range::set_undefined ()
{ {
equiv_clear (); set (VR_UNDEFINED, NULL, NULL, NULL);
*this = value_range (VR_UNDEFINED, NULL, NULL, NULL);
} }
void void
value_range_base::set_varying () value_range_base::set_varying ()
{ {
*this = value_range_base (VR_VARYING, NULL, NULL); set (VR_VARYING, NULL, NULL);
} }
void void
value_range::set_varying () value_range::set_varying ()
{ {
equiv_clear (); set (VR_VARYING, NULL, NULL, NULL);
*this = value_range (VR_VARYING, NULL, NULL, NULL);
} }
/* Return TRUE if it is possible that range contains VAL. */ /* Return TRUE if it is possible that range contains VAL. */
...@@ -598,15 +605,6 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type, ...@@ -598,15 +605,6 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type,
return vr_type; return vr_type;
} }
/* Set value range VR to {T, MIN, MAX, EQUIV}. */
void
set_value_range (value_range *vr, enum value_range_kind kind,
tree min, tree max, bitmap equiv)
{
*vr = value_range (kind, min, max, equiv);
}
/* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}. /* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}.
This means adjusting VRTYPE, MIN and MAX representing the case of a This means adjusting VRTYPE, MIN and MAX representing the case of a
...@@ -739,35 +737,52 @@ value_range::set_and_canonicalize (enum value_range_kind kind, ...@@ -739,35 +737,52 @@ value_range::set_and_canonicalize (enum value_range_kind kind,
equiv_clear (); equiv_clear ();
} }
/* Set value range VR to a single value. This function is only called void
with values we get from statements, and exists to clear the value_range_base::set (tree val)
TREE_OVERFLOW flag. */ {
gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val));
if (TREE_OVERFLOW_P (val))
val = drop_tree_overflow (val);
set (VR_RANGE, val, val);
}
void void
set_value_range_to_value (value_range *vr, tree val, bitmap equiv) value_range::set (tree val)
{ {
gcc_assert (is_gimple_min_invariant (val)); gcc_assert (TREE_CODE (val) == SSA_NAME || is_gimple_min_invariant (val));
if (TREE_OVERFLOW_P (val)) if (TREE_OVERFLOW_P (val))
val = drop_tree_overflow (val); val = drop_tree_overflow (val);
set_value_range (vr, VR_RANGE, val, val, equiv); set (VR_RANGE, val, val, NULL);
} }
/* Set value range VR to a non-NULL range of type TYPE. */ /* Set value range VR to a non-NULL range of type TYPE. */
void void
set_value_range_to_nonnull (value_range *vr, tree type) value_range_base::set_nonnull (tree type)
{ {
tree zero = build_int_cst (type, 0); tree zero = build_int_cst (type, 0);
set_value_range (vr, VR_ANTI_RANGE, zero, zero, NULL); set (VR_ANTI_RANGE, zero, zero);
} }
void
value_range::set_nonnull (tree type)
{
tree zero = build_int_cst (type, 0);
set (VR_ANTI_RANGE, zero, zero, NULL);
}
/* Set value range VR to a NULL range of type TYPE. */ /* Set value range VR to a NULL range of type TYPE. */
void void
set_value_range_to_null (value_range *vr, tree type) value_range_base::set_null (tree type)
{
set (build_int_cst (type, 0));
}
void
value_range::set_null (tree type)
{ {
set_value_range_to_value (vr, build_int_cst (type, 0), NULL); set (build_int_cst (type, 0));
} }
/* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */ /* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */
...@@ -797,13 +812,13 @@ vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2) ...@@ -797,13 +812,13 @@ vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
/* Return true if VR is [0, 0]. */ /* Return true if VR is [0, 0]. */
static inline bool static inline bool
range_is_null (const value_range *vr) range_is_null (const value_range_base *vr)
{ {
return vr->zero_p (); return vr->zero_p ();
} }
static inline bool static inline bool
range_is_nonnull (const value_range *vr) range_is_nonnull (const value_range_base *vr)
{ {
return (vr->kind () == VR_ANTI_RANGE return (vr->kind () == VR_ANTI_RANGE
&& vr->min () == vr->max () && vr->min () == vr->max ()
...@@ -1195,8 +1210,8 @@ vrp_set_zero_nonzero_bits (const tree expr_type, ...@@ -1195,8 +1210,8 @@ vrp_set_zero_nonzero_bits (const tree expr_type,
*VR1 will be VR_UNDEFINED. */ *VR1 will be VR_UNDEFINED. */
static bool static bool
ranges_from_anti_range (const value_range *ar, ranges_from_anti_range (const value_range_base *ar,
value_range *vr0, value_range *vr1) value_range_base *vr0, value_range_base *vr1)
{ {
tree type = ar->type (); tree type = ar->type ();
...@@ -1237,7 +1252,7 @@ ranges_from_anti_range (const value_range *ar, ...@@ -1237,7 +1252,7 @@ ranges_from_anti_range (const value_range *ar,
resulting wide ints are set to [-MIN, +MAX] for the type. */ resulting wide ints are set to [-MIN, +MAX] for the type. */
static void inline static void inline
extract_range_into_wide_ints (const value_range *vr, extract_range_into_wide_ints (const value_range_base *vr,
signop sign, unsigned prec, signop sign, unsigned prec,
wide_int &wmin, wide_int &wmax) wide_int &wmin, wide_int &wmax)
{ {
...@@ -1259,10 +1274,10 @@ extract_range_into_wide_ints (const value_range *vr, ...@@ -1259,10 +1274,10 @@ extract_range_into_wide_ints (const value_range *vr,
*VR = *VR0 .CODE. *VR1. */ *VR = *VR0 .CODE. *VR1. */
static void static void
extract_range_from_multiplicative_op (value_range *vr, extract_range_from_multiplicative_op (value_range_base *vr,
enum tree_code code, enum tree_code code,
const value_range *vr0, const value_range_base *vr0,
const value_range *vr1) const value_range_base *vr1)
{ {
gcc_assert (code == MULT_EXPR gcc_assert (code == MULT_EXPR
|| code == TRUNC_DIV_EXPR || code == TRUNC_DIV_EXPR
...@@ -1290,7 +1305,7 @@ extract_range_from_multiplicative_op (value_range *vr, ...@@ -1290,7 +1305,7 @@ extract_range_from_multiplicative_op (value_range *vr,
overflow_undefined)) overflow_undefined))
vr->set_and_canonicalize (VR_RANGE, vr->set_and_canonicalize (VR_RANGE,
wide_int_to_tree (type, res_lb), wide_int_to_tree (type, res_lb),
wide_int_to_tree (type, res_ub), NULL); wide_int_to_tree (type, res_ub));
else else
vr->set_varying (); vr->set_varying ();
} }
...@@ -1411,7 +1426,7 @@ set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max, ...@@ -1411,7 +1426,7 @@ set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max,
{ {
/* If the limits are swapped, we wrapped around and cover /* If the limits are swapped, we wrapped around and cover
the entire range. We have a similar check at the end of the entire range. We have a similar check at the end of
extract_range_from_binary_expr_1. */ extract_range_from_binary_expr. */
if (wi::gt_p (tmin, tmax, sgn)) if (wi::gt_p (tmin, tmax, sgn))
kind = VR_VARYING; kind = VR_VARYING;
else else
...@@ -1485,15 +1500,15 @@ set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max, ...@@ -1485,15 +1500,15 @@ set_value_range_with_overflow (value_range_kind &kind, tree &min, tree &max,
type EXPR_TYPE. The resulting range is stored in *VR. */ type EXPR_TYPE. The resulting range is stored in *VR. */
void void
extract_range_from_binary_expr_1 (value_range *vr, extract_range_from_binary_expr (value_range_base *vr,
enum tree_code code, tree expr_type, enum tree_code code, tree expr_type,
const value_range *vr0_, const value_range_base *vr0_,
const value_range *vr1_) const value_range_base *vr1_)
{ {
signop sign = TYPE_SIGN (expr_type); signop sign = TYPE_SIGN (expr_type);
unsigned int prec = TYPE_PRECISION (expr_type); unsigned int prec = TYPE_PRECISION (expr_type);
value_range vr0 = *vr0_, vr1 = *vr1_; value_range_base vr0 = *vr0_, vr1 = *vr1_;
value_range vrtem0, vrtem1; value_range_base vrtem0, vrtem1;
enum value_range_kind type; enum value_range_kind type;
tree min = NULL_TREE, max = NULL_TREE; tree min = NULL_TREE, max = NULL_TREE;
int cmp; int cmp;
...@@ -1550,7 +1565,7 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1550,7 +1565,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
easier to special case when vr0 is ~[0,0] for EXACT_DIV_EXPR. */ easier to special case when vr0 is ~[0,0] for EXACT_DIV_EXPR. */
if (code == EXACT_DIV_EXPR && range_is_nonnull (&vr0)) if (code == EXACT_DIV_EXPR && range_is_nonnull (&vr0))
{ {
set_value_range_to_nonnull (vr, expr_type); vr->set_nonnull (expr_type);
return; return;
} }
...@@ -1559,11 +1574,12 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1559,11 +1574,12 @@ extract_range_from_binary_expr_1 (value_range *vr,
if (vr0.kind () == VR_ANTI_RANGE if (vr0.kind () == VR_ANTI_RANGE
&& ranges_from_anti_range (&vr0, &vrtem0, &vrtem1)) && ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))
{ {
extract_range_from_binary_expr_1 (vr, code, expr_type, &vrtem0, vr1_); extract_range_from_binary_expr (vr, code, expr_type, &vrtem0, vr1_);
if (!vrtem1.undefined_p ()) if (!vrtem1.undefined_p ())
{ {
value_range vrres; value_range_base vrres;
extract_range_from_binary_expr_1 (&vrres, code, expr_type, &vrtem1, vr1_); extract_range_from_binary_expr (&vrres, code, expr_type,
&vrtem1, vr1_);
vr->union_ (&vrres); vr->union_ (&vrres);
} }
return; return;
...@@ -1572,12 +1588,12 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1572,12 +1588,12 @@ extract_range_from_binary_expr_1 (value_range *vr,
if (vr1.kind () == VR_ANTI_RANGE if (vr1.kind () == VR_ANTI_RANGE
&& ranges_from_anti_range (&vr1, &vrtem0, &vrtem1)) && ranges_from_anti_range (&vr1, &vrtem0, &vrtem1))
{ {
extract_range_from_binary_expr_1 (vr, code, expr_type, vr0_, &vrtem0); extract_range_from_binary_expr (vr, code, expr_type, vr0_, &vrtem0);
if (!vrtem1.undefined_p ()) if (!vrtem1.undefined_p ())
{ {
value_range vrres; value_range_base vrres;
extract_range_from_binary_expr_1 (&vrres, code, expr_type, extract_range_from_binary_expr (&vrres, code, expr_type,
vr0_, &vrtem1); vr0_, &vrtem1);
vr->union_ (&vrres); vr->union_ (&vrres);
} }
return; return;
...@@ -1627,9 +1643,9 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1627,9 +1643,9 @@ extract_range_from_binary_expr_1 (value_range *vr,
If both are null, then the result is null. Otherwise they If both are null, then the result is null. Otherwise they
are varying. */ are varying. */
if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1)) if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1))
set_value_range_to_nonnull (vr, expr_type); vr->set_nonnull (expr_type);
else if (range_is_null (&vr0) && range_is_null (&vr1)) else if (range_is_null (&vr0) && range_is_null (&vr1))
set_value_range_to_null (vr, expr_type); vr->set_null (expr_type);
else else
vr->set_varying (); vr->set_varying ();
} }
...@@ -1639,9 +1655,9 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1639,9 +1655,9 @@ extract_range_from_binary_expr_1 (value_range *vr,
whether the expression evaluates to non-NULL. */ whether the expression evaluates to non-NULL. */
if (!range_includes_zero_p (&vr0) if (!range_includes_zero_p (&vr0)
|| !range_includes_zero_p (&vr1)) || !range_includes_zero_p (&vr1))
set_value_range_to_nonnull (vr, expr_type); vr->set_nonnull (expr_type);
else if (range_is_null (&vr0) && range_is_null (&vr1)) else if (range_is_null (&vr0) && range_is_null (&vr1))
set_value_range_to_null (vr, expr_type); vr->set_null (expr_type);
else else
vr->set_varying (); vr->set_varying ();
} }
...@@ -1650,9 +1666,9 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1650,9 +1666,9 @@ extract_range_from_binary_expr_1 (value_range *vr,
/* For pointer types, we are really only interested in asserting /* For pointer types, we are really only interested in asserting
whether the expression evaluates to non-NULL. */ whether the expression evaluates to non-NULL. */
if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1)) if (!range_includes_zero_p (&vr0) && !range_includes_zero_p (&vr1))
set_value_range_to_nonnull (vr, expr_type); vr->set_nonnull (expr_type);
else if (range_is_null (&vr0) || range_is_null (&vr1)) else if (range_is_null (&vr0) || range_is_null (&vr1))
set_value_range_to_null (vr, expr_type); vr->set_null (expr_type);
else else
vr->set_varying (); vr->set_varying ();
} }
...@@ -1670,13 +1686,9 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1670,13 +1686,9 @@ extract_range_from_binary_expr_1 (value_range *vr,
[0,0] - VR_VARYING is not dropped to varying, but is [0,0] - VR_VARYING is not dropped to varying, but is
calculated as [MIN+1, MAX]. */ calculated as [MIN+1, MAX]. */
if (vr0.varying_p ()) if (vr0.varying_p ())
vr0.update (VR_RANGE, vr0.set (VR_RANGE, vrp_val_min (expr_type), vrp_val_max (expr_type));
vrp_val_min (expr_type),
vrp_val_max (expr_type));
if (vr1.varying_p ()) if (vr1.varying_p ())
vr1.update (VR_RANGE, vr1.set (VR_RANGE, vrp_val_min (expr_type), vrp_val_max (expr_type));
vrp_val_min (expr_type),
vrp_val_max (expr_type));
const bool minus_p = (code == MINUS_EXPR); const bool minus_p = (code == MINUS_EXPR);
tree min_op0 = vr0.min (); tree min_op0 = vr0.min ();
...@@ -1779,8 +1791,8 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1779,8 +1791,8 @@ extract_range_from_binary_expr_1 (value_range *vr,
extract_range_into_wide_ints (&vr1, sign, prec, vr1_min, vr1_max); extract_range_into_wide_ints (&vr1, sign, prec, vr1_min, vr1_max);
if (wide_int_range_min_max (wmin, wmax, code, sign, prec, if (wide_int_range_min_max (wmin, wmax, code, sign, prec,
vr0_min, vr0_max, vr1_min, vr1_max)) vr0_min, vr0_max, vr1_min, vr1_max))
vr->update (VR_RANGE, wide_int_to_tree (expr_type, wmin), vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin),
wide_int_to_tree (expr_type, wmax)); wide_int_to_tree (expr_type, wmax));
else else
vr->set_varying (); vr->set_varying ();
return; return;
...@@ -1812,9 +1824,8 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1812,9 +1824,8 @@ extract_range_from_binary_expr_1 (value_range *vr,
useful ranges just from the shift count. E.g. useful ranges just from the shift count. E.g.
x >> 63 for signed 64-bit x is always [-1, 0]. */ x >> 63 for signed 64-bit x is always [-1, 0]. */
if (vr0.kind () != VR_RANGE || vr0.symbolic_p ()) if (vr0.kind () != VR_RANGE || vr0.symbolic_p ())
vr0.update (VR_RANGE, vr0.set (VR_RANGE, vrp_val_min (expr_type),
vrp_val_min (expr_type), vrp_val_max (expr_type));
vrp_val_max (expr_type));
extract_range_from_multiplicative_op (vr, code, &vr0, &vr1); extract_range_from_multiplicative_op (vr, code, &vr0, &vr1);
return; return;
} }
...@@ -1831,7 +1842,7 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1831,7 +1842,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
{ {
min = wide_int_to_tree (expr_type, res_lb); min = wide_int_to_tree (expr_type, res_lb);
max = wide_int_to_tree (expr_type, res_ub); max = wide_int_to_tree (expr_type, res_ub);
vr->set_and_canonicalize (VR_RANGE, min, max, NULL); vr->set_and_canonicalize (VR_RANGE, min, max);
return; return;
} }
} }
...@@ -1876,15 +1887,13 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1876,15 +1887,13 @@ extract_range_from_binary_expr_1 (value_range *vr,
vr->set_undefined (); vr->set_undefined ();
return; return;
} }
set_value_range (vr, VR_RANGE, vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin),
wide_int_to_tree (expr_type, wmin), wide_int_to_tree (expr_type, wmax));
wide_int_to_tree (expr_type, wmax), NULL);
if (extra_range_p) if (extra_range_p)
{ {
value_range extra_range; value_range_base
set_value_range (&extra_range, VR_RANGE, extra_range (VR_RANGE, wide_int_to_tree (expr_type, extra_min),
wide_int_to_tree (expr_type, extra_min), wide_int_to_tree (expr_type, extra_max));
wide_int_to_tree (expr_type, extra_max), NULL);
vr->union_ (&extra_range); vr->union_ (&extra_range);
} }
return; return;
...@@ -1904,7 +1913,7 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1904,7 +1913,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
vr0_min, vr0_max, vr1_min, vr1_max); vr0_min, vr0_max, vr1_min, vr1_max);
min = wide_int_to_tree (expr_type, wmin); min = wide_int_to_tree (expr_type, wmin);
max = wide_int_to_tree (expr_type, wmax); max = wide_int_to_tree (expr_type, wmax);
set_value_range (vr, VR_RANGE, min, max, NULL); vr->set (VR_RANGE, min, max);
return; return;
} }
else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR) else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR)
...@@ -1931,7 +1940,7 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1931,7 +1940,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
{ {
min = wide_int_to_tree (expr_type, wmin); min = wide_int_to_tree (expr_type, wmin);
max = wide_int_to_tree (expr_type, wmax); max = wide_int_to_tree (expr_type, wmax);
set_value_range (vr, VR_RANGE, min, max, NULL); vr->set (VR_RANGE, min, max);
} }
else else
vr->set_varying (); vr->set_varying ();
...@@ -1949,7 +1958,7 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1949,7 +1958,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
{ {
min = wide_int_to_tree (expr_type, wmin); min = wide_int_to_tree (expr_type, wmin);
max = wide_int_to_tree (expr_type, wmax); max = wide_int_to_tree (expr_type, wmax);
set_value_range (vr, VR_RANGE, min, max, NULL); vr->set (VR_RANGE, min, max);
} }
else else
vr->set_varying (); vr->set_varying ();
...@@ -1965,7 +1974,7 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -1965,7 +1974,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
{ {
min = wide_int_to_tree (expr_type, wmin); min = wide_int_to_tree (expr_type, wmin);
max = wide_int_to_tree (expr_type, wmax); max = wide_int_to_tree (expr_type, wmax);
set_value_range (vr, VR_RANGE, min, max, NULL); vr->set (VR_RANGE, min, max);
} }
else else
vr->set_varying (); vr->set_varying ();
...@@ -2004,7 +2013,7 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -2004,7 +2013,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
vr->set_varying (); vr->set_varying ();
} }
else else
set_value_range (vr, type, min, max, NULL); vr->set (type, min, max);
} }
/* Extract range information from a unary operation CODE based on /* Extract range information from a unary operation CODE based on
...@@ -2012,14 +2021,14 @@ extract_range_from_binary_expr_1 (value_range *vr, ...@@ -2012,14 +2021,14 @@ extract_range_from_binary_expr_1 (value_range *vr,
The resulting range is stored in *VR. */ The resulting range is stored in *VR. */
void void
extract_range_from_unary_expr (value_range *vr, extract_range_from_unary_expr (value_range_base *vr,
enum tree_code code, tree type, enum tree_code code, tree type,
const value_range *vr0_, tree op0_type) const value_range_base *vr0_, tree op0_type)
{ {
signop sign = TYPE_SIGN (type); signop sign = TYPE_SIGN (type);
unsigned int prec = TYPE_PRECISION (type); unsigned int prec = TYPE_PRECISION (type);
value_range vr0 = *vr0_; value_range_base vr0 = *vr0_;
value_range vrtem0, vrtem1; value_range_base vrtem0, vrtem1;
/* VRP only operates on integral and pointer types. */ /* VRP only operates on integral and pointer types. */
if (!(INTEGRAL_TYPE_P (op0_type) if (!(INTEGRAL_TYPE_P (op0_type)
...@@ -2039,29 +2048,28 @@ extract_range_from_unary_expr (value_range *vr, ...@@ -2039,29 +2048,28 @@ extract_range_from_unary_expr (value_range *vr,
} }
/* Handle operations that we express in terms of others. */ /* Handle operations that we express in terms of others. */
if (code == PAREN_EXPR || code == OBJ_TYPE_REF) if (code == PAREN_EXPR)
{ {
/* PAREN_EXPR and OBJ_TYPE_REF are simple copies. */ /* PAREN_EXPR and OBJ_TYPE_REF are simple copies. */
vr->deep_copy (&vr0); *vr = vr0;
return; return;
} }
else if (code == NEGATE_EXPR) else if (code == NEGATE_EXPR)
{ {
/* -X is simply 0 - X, so re-use existing code that also handles /* -X is simply 0 - X, so re-use existing code that also handles
anti-ranges fine. */ anti-ranges fine. */
value_range zero; value_range_base zero;
set_value_range_to_value (&zero, build_int_cst (type, 0), NULL); zero.set (build_int_cst (type, 0));
extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &zero, &vr0); extract_range_from_binary_expr (vr, MINUS_EXPR, type, &zero, &vr0);
return; return;
} }
else if (code == BIT_NOT_EXPR) else if (code == BIT_NOT_EXPR)
{ {
/* ~X is simply -1 - X, so re-use existing code that also handles /* ~X is simply -1 - X, so re-use existing code that also handles
anti-ranges fine. */ anti-ranges fine. */
value_range minusone; value_range_base minusone;
set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL); minusone.set (build_int_cst (type, -1));
extract_range_from_binary_expr_1 (vr, MINUS_EXPR, extract_range_from_binary_expr (vr, MINUS_EXPR, type, &minusone, &vr0);
type, &minusone, &vr0);
return; return;
} }
...@@ -2073,7 +2081,7 @@ extract_range_from_unary_expr (value_range *vr, ...@@ -2073,7 +2081,7 @@ extract_range_from_unary_expr (value_range *vr,
extract_range_from_unary_expr (vr, code, type, &vrtem0, op0_type); extract_range_from_unary_expr (vr, code, type, &vrtem0, op0_type);
if (!vrtem1.undefined_p ()) if (!vrtem1.undefined_p ())
{ {
value_range vrres; value_range_base vrres;
extract_range_from_unary_expr (&vrres, code, type, extract_range_from_unary_expr (&vrres, code, type,
&vrtem1, op0_type); &vrtem1, op0_type);
vr->union_ (&vrres); vr->union_ (&vrres);
...@@ -2096,9 +2104,9 @@ extract_range_from_unary_expr (value_range *vr, ...@@ -2096,9 +2104,9 @@ extract_range_from_unary_expr (value_range *vr,
if (POINTER_TYPE_P (type) || POINTER_TYPE_P (op0_type)) if (POINTER_TYPE_P (type) || POINTER_TYPE_P (op0_type))
{ {
if (!range_includes_zero_p (&vr0)) if (!range_includes_zero_p (&vr0))
set_value_range_to_nonnull (vr, type); vr->set_nonnull (type);
else if (range_is_null (&vr0)) else if (range_is_null (&vr0))
set_value_range_to_null (vr, type); vr->set_null (type);
else else
vr->set_varying (); vr->set_varying ();
return; return;
...@@ -2132,7 +2140,7 @@ extract_range_from_unary_expr (value_range *vr, ...@@ -2132,7 +2140,7 @@ extract_range_from_unary_expr (value_range *vr,
{ {
tree min = wide_int_to_tree (outer_type, wmin); tree min = wide_int_to_tree (outer_type, wmin);
tree max = wide_int_to_tree (outer_type, wmax); tree max = wide_int_to_tree (outer_type, wmax);
vr->set_and_canonicalize (VR_RANGE, min, max, NULL); vr->set_and_canonicalize (VR_RANGE, min, max);
} }
else else
vr->set_varying (); vr->set_varying ();
...@@ -2145,9 +2153,8 @@ extract_range_from_unary_expr (value_range *vr, ...@@ -2145,9 +2153,8 @@ extract_range_from_unary_expr (value_range *vr,
extract_range_into_wide_ints (&vr0, sign, prec, vr0_min, vr0_max); extract_range_into_wide_ints (&vr0, sign, prec, vr0_min, vr0_max);
if (wide_int_range_abs (wmin, wmax, sign, prec, vr0_min, vr0_max, if (wide_int_range_abs (wmin, wmax, sign, prec, vr0_min, vr0_max,
TYPE_OVERFLOW_UNDEFINED (type))) TYPE_OVERFLOW_UNDEFINED (type)))
set_value_range (vr, VR_RANGE, vr->set (VR_RANGE, wide_int_to_tree (type, wmin),
wide_int_to_tree (type, wmin), wide_int_to_tree (type, wmax));
wide_int_to_tree (type, wmax), NULL);
else else
vr->set_varying (); vr->set_varying ();
return; return;
...@@ -6024,24 +6031,21 @@ value_range::intersect_helper (value_range *vr0, const value_range *vr1) ...@@ -6024,24 +6031,21 @@ value_range::intersect_helper (value_range *vr0, const value_range *vr1)
return; return;
} }
/* Save the original vr0 so we can return it as conservative intersection
result when our worker turns things to varying. */
value_range saved (*vr0);
value_range_kind vr0type = vr0->kind (); value_range_kind vr0type = vr0->kind ();
tree vr0min = vr0->min (); tree vr0min = vr0->min ();
tree vr0max = vr0->max (); tree vr0max = vr0->max ();
intersect_ranges (&vr0type, &vr0min, &vr0max, intersect_ranges (&vr0type, &vr0min, &vr0max,
vr1->kind (), vr1->min (), vr1->max ()); vr1->kind (), vr1->min (), vr1->max ());
/* Make sure to canonicalize the result though as the inversion of a /* Make sure to canonicalize the result though as the inversion of a
VR_RANGE can still be a VR_RANGE. */ VR_RANGE can still be a VR_RANGE. Work on a temporary so we can
vr0->set_and_canonicalize (vr0type, vr0min, vr0max, vr0->m_equiv); fall back to vr0 when this turns things to varying. */
value_range tem;
tem.set_and_canonicalize (vr0type, vr0min, vr0max);
/* If that failed, use the saved original VR0. */ /* If that failed, use the saved original VR0. */
if (vr0->varying_p ()) if (tem.varying_p ())
{ return;
*vr0 = saved; vr0->update (tem.kind (), tem.min (), tem.max ());
return;
}
/* If the result is VR_UNDEFINED there is no need to mess with /* If the result is VR_UNDEFINED there is no need to mess with
the equivalencies. */ the equivalencies. */
if (vr0->undefined_p ()) if (vr0->undefined_p ())
...@@ -6168,37 +6172,30 @@ value_range::union_helper (value_range *vr0, const value_range *vr1) ...@@ -6168,37 +6172,30 @@ value_range::union_helper (value_range *vr0, const value_range *vr1)
return; return;
} }
value_range saved (*vr0);
value_range_kind vr0type = vr0->kind (); value_range_kind vr0type = vr0->kind ();
tree vr0min = vr0->min (); tree vr0min = vr0->min ();
tree vr0max = vr0->max (); tree vr0max = vr0->max ();
union_ranges (&vr0type, &vr0min, &vr0max, union_ranges (&vr0type, &vr0min, &vr0max,
vr1->kind (), vr1->min (), vr1->max ()); vr1->kind (), vr1->min (), vr1->max ());
*vr0 = value_range (vr0type, vr0min, vr0max); /* Work on a temporary so we can still use vr0 when union returns varying. */
if (vr0->varying_p ()) value_range tem;
tem.set_and_canonicalize (vr0type, vr0min, vr0max);
if (tem.varying_p ())
{ {
/* Failed to find an efficient meet. Before giving up and setting /* Failed to find an efficient meet. Before giving up and setting
the result to VARYING, see if we can at least derive a useful the result to VARYING, see if we can at least derive a useful
anti-range. */ anti-range. */
if (range_includes_zero_p (&saved) == 0 if (range_includes_zero_p (vr0) == 0
&& range_includes_zero_p (vr1) == 0) && range_includes_zero_p (vr1) == 0)
{ {
set_value_range_to_nonnull (vr0, saved.type ()); vr0->set_nonnull (vr0->type ());
/* Since this meet operation did not result from the meeting of
two equivalent names, VR0 cannot have any equivalences. */
if (vr0->m_equiv)
bitmap_clear (vr0->m_equiv);
return; return;
} }
vr0->set_varying (); vr0->set_varying ();
return; return;
} }
vr0->set_and_canonicalize (vr0->kind (), vr0->min (), vr0->max (), vr0->update (tem.kind (), tem.min (), tem.max ());
vr0->equiv ());
if (vr0->varying_p ())
return;
/* The resulting set of equivalences is always the intersection of /* The resulting set of equivalences is always the intersection of
the two sets. */ the two sets. */
...@@ -6877,8 +6874,8 @@ determine_value_range_1 (value_range *vr, tree expr) ...@@ -6877,8 +6874,8 @@ determine_value_range_1 (value_range *vr, tree expr)
value_range vr0, vr1; value_range vr0, vr1;
determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0)); determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1)); determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1));
extract_range_from_binary_expr_1 (vr, TREE_CODE (expr), TREE_TYPE (expr), extract_range_from_binary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
&vr0, &vr1); &vr0, &vr1);
} }
else if (UNARY_CLASS_P (expr)) else if (UNARY_CLASS_P (expr))
{ {
...@@ -6888,7 +6885,7 @@ determine_value_range_1 (value_range *vr, tree expr) ...@@ -6888,7 +6885,7 @@ determine_value_range_1 (value_range *vr, tree expr)
&vr0, TREE_TYPE (TREE_OPERAND (expr, 0))); &vr0, TREE_TYPE (TREE_OPERAND (expr, 0)));
} }
else if (TREE_CODE (expr) == INTEGER_CST) else if (TREE_CODE (expr) == INTEGER_CST)
set_value_range_to_value (vr, expr, NULL); vr->set (expr);
else else
{ {
value_range_kind kind; value_range_kind kind;
...@@ -6898,8 +6895,8 @@ determine_value_range_1 (value_range *vr, tree expr) ...@@ -6898,8 +6895,8 @@ determine_value_range_1 (value_range *vr, tree expr)
if (TREE_CODE (expr) == SSA_NAME if (TREE_CODE (expr) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (expr)) && INTEGRAL_TYPE_P (TREE_TYPE (expr))
&& (kind = get_range_info (expr, &min, &max)) != VR_VARYING) && (kind = get_range_info (expr, &min, &max)) != VR_VARYING)
set_value_range (vr, kind, wide_int_to_tree (TREE_TYPE (expr), min), vr->set (kind, wide_int_to_tree (TREE_TYPE (expr), min),
wide_int_to_tree (TREE_TYPE (expr), max), NULL); wide_int_to_tree (TREE_TYPE (expr), max));
else else
vr->set_varying (); vr->set_varying ();
} }
......
...@@ -44,6 +44,11 @@ public: ...@@ -44,6 +44,11 @@ public:
value_range_base (); value_range_base ();
value_range_base (value_range_kind, tree, tree); value_range_base (value_range_kind, tree, tree);
void set (value_range_kind, tree, tree);
void set (tree);
void set_nonnull (tree);
void set_null (tree);
enum value_range_kind kind () const; enum value_range_kind kind () const;
tree min () const; tree min () const;
tree max () const; tree max () const;
...@@ -71,7 +76,6 @@ public: ...@@ -71,7 +76,6 @@ public:
void dump () const; void dump () const;
protected: protected:
void set (value_range_kind, tree, tree);
void check (); void check ();
enum value_range_kind m_kind; enum value_range_kind m_kind;
...@@ -96,8 +100,25 @@ class GTY((user)) value_range : public value_range_base ...@@ -96,8 +100,25 @@ class GTY((user)) value_range : public value_range_base
public: public:
value_range (); value_range ();
value_range (const value_range_base &); value_range (const value_range_base &);
/* Deep-copies equiv bitmap argument. */
value_range (value_range_kind, tree, tree, bitmap = NULL); value_range (value_range_kind, tree, tree, bitmap = NULL);
/* Shallow-copies equiv bitmap. */
value_range (const value_range &) /* = delete */;
/* Shallow-copies equiv bitmap. */
value_range& operator=(const value_range&) /* = delete */;
/* Move equiv bitmap from source range. */
void move (value_range *);
/* Leaves equiv bitmap alone. */
void update (value_range_kind, tree, tree); void update (value_range_kind, tree, tree);
/* Deep-copies equiv bitmap argument. */
void set (value_range_kind, tree, tree, bitmap = NULL);
void set (tree);
void set_nonnull (tree);
void set_null (tree);
bool operator== (const value_range &) const; bool operator== (const value_range &) const;
bool operator!= (const value_range &) const; bool operator!= (const value_range &) const;
void intersect (const value_range *); void intersect (const value_range *);
...@@ -114,12 +135,12 @@ class GTY((user)) value_range : public value_range_base ...@@ -114,12 +135,12 @@ class GTY((user)) value_range : public value_range_base
/* Misc methods. */ /* Misc methods. */
void deep_copy (const value_range *); void deep_copy (const value_range *);
void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap); void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap = NULL);
void dump (FILE *) const; void dump (FILE *) const;
void dump () const; void dump () const;
private: private:
void set (value_range_kind, tree, tree, bitmap); /* Deep-copies bitmap argument. */
void set_equiv (bitmap); void set_equiv (bitmap);
void check (); void check ();
bool equal_p (const value_range &, bool ignore_equivs) const; bool equal_p (const value_range &, bool ignore_equivs) const;
...@@ -225,12 +246,6 @@ extern bool stmt_interesting_for_vrp (gimple *); ...@@ -225,12 +246,6 @@ extern bool stmt_interesting_for_vrp (gimple *);
extern bool range_includes_zero_p (const value_range_base *); extern bool range_includes_zero_p (const value_range_base *);
extern bool infer_value_range (gimple *, tree, tree_code *, tree *); extern bool infer_value_range (gimple *, tree, tree_code *, tree *);
extern void set_value_range_to_nonnull (value_range *, tree);
extern void set_value_range_to_null (value_range *, tree);
extern void set_value_range (value_range *, enum value_range_kind, tree,
tree, bitmap);
extern void set_value_range_to_value (value_range *, tree, bitmap);
extern bool vrp_bitmap_equal_p (const_bitmap, const_bitmap); extern bool vrp_bitmap_equal_p (const_bitmap, const_bitmap);
extern tree value_range_constant_singleton (const value_range_base *); extern tree value_range_constant_singleton (const value_range_base *);
...@@ -247,14 +262,15 @@ extern int value_inside_range (tree, tree, tree); ...@@ -247,14 +262,15 @@ extern int value_inside_range (tree, tree, tree);
extern tree vrp_val_min (const_tree); extern tree vrp_val_min (const_tree);
extern tree vrp_val_max (const_tree); extern tree vrp_val_max (const_tree);
extern void extract_range_from_unary_expr (value_range *vr, extern void extract_range_from_unary_expr (value_range_base *vr,
enum tree_code code, enum tree_code code,
tree type, tree type,
const value_range *vr0_, const value_range_base *vr0_,
tree op0_type); tree op0_type);
extern void extract_range_from_binary_expr_1 (value_range *, enum tree_code, extern void extract_range_from_binary_expr (value_range_base *,
tree, const value_range *, enum tree_code,
const value_range *); tree, const value_range_base *,
const value_range_base *);
extern bool vrp_operand_equal_p (const_tree, const_tree); extern bool vrp_operand_equal_p (const_tree, const_tree);
extern enum value_range_kind intersect_range_with_nonzero_bits extern enum value_range_kind intersect_range_with_nonzero_bits
......
...@@ -118,7 +118,7 @@ vr_values::get_value_range (const_tree var) ...@@ -118,7 +118,7 @@ vr_values::get_value_range (const_tree var)
if (POINTER_TYPE_P (TREE_TYPE (sym)) if (POINTER_TYPE_P (TREE_TYPE (sym))
&& (nonnull_arg_p (sym) && (nonnull_arg_p (sym)
|| get_ptr_nonnull (var))) || get_ptr_nonnull (var)))
set_value_range_to_nonnull (vr, TREE_TYPE (sym)); vr->set_nonnull (TREE_TYPE (sym));
else if (INTEGRAL_TYPE_P (TREE_TYPE (sym))) else if (INTEGRAL_TYPE_P (TREE_TYPE (sym)))
{ {
get_range_info (var, *vr); get_range_info (var, *vr);
...@@ -130,7 +130,7 @@ vr_values::get_value_range (const_tree var) ...@@ -130,7 +130,7 @@ vr_values::get_value_range (const_tree var)
} }
else if (TREE_CODE (sym) == RESULT_DECL else if (TREE_CODE (sym) == RESULT_DECL
&& DECL_BY_REFERENCE (sym)) && DECL_BY_REFERENCE (sym))
set_value_range_to_nonnull (vr, TREE_TYPE (sym)); vr->set_nonnull (TREE_TYPE (sym));
} }
return vr; return vr;
...@@ -197,8 +197,8 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) ...@@ -197,8 +197,8 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
return true; return true;
} }
else else
set_value_range (old_vr, new_vr->kind (), old_vr->set (new_vr->kind (),
new_vr->min (), new_vr->max (), new_vr->equiv ()); new_vr->min (), new_vr->max (), new_vr->equiv ());
} }
new_vr->equiv_clear (); new_vr->equiv_clear ();
...@@ -209,7 +209,7 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) ...@@ -209,7 +209,7 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
/* Return true if value range VR involves exactly one symbol SYM. */ /* Return true if value range VR involves exactly one symbol SYM. */
static bool static bool
symbolic_range_based_on_p (value_range *vr, const_tree sym) symbolic_range_based_on_p (value_range_base *vr, const_tree sym)
{ {
bool neg, min_has_symbol, max_has_symbol; bool neg, min_has_symbol, max_has_symbol;
tree inv; tree inv;
...@@ -672,7 +672,7 @@ vr_values::extract_range_from_ssa_name (value_range *vr, tree var) ...@@ -672,7 +672,7 @@ vr_values::extract_range_from_ssa_name (value_range *vr, tree var)
if (!var_vr->varying_p ()) if (!var_vr->varying_p ())
vr->deep_copy (var_vr); vr->deep_copy (var_vr);
else else
set_value_range (vr, VR_RANGE, var, var, NULL); vr->set (var);
vr->equiv_add (var, get_value_range (var), &vrp_equiv_obstack); vr->equiv_add (var, get_value_range (var), &vrp_equiv_obstack);
} }
...@@ -688,18 +688,18 @@ vr_values::extract_range_from_binary_expr (value_range *vr, ...@@ -688,18 +688,18 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
{ {
/* Get value ranges for each operand. For constant operands, create /* Get value ranges for each operand. For constant operands, create
a new value range with the operand to simplify processing. */ a new value range with the operand to simplify processing. */
value_range vr0, vr1; value_range_base vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME) if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0)); vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0)) else if (is_gimple_min_invariant (op0))
set_value_range_to_value (&vr0, op0, NULL); vr0.set (op0);
else else
vr0.set_varying (); vr0.set_varying ();
if (TREE_CODE (op1) == SSA_NAME) if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1)); vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1)) else if (is_gimple_min_invariant (op1))
set_value_range_to_value (&vr1, op1, NULL); vr1.set (op1);
else else
vr1.set_varying (); vr1.set_varying ();
...@@ -718,7 +718,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr, ...@@ -718,7 +718,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
vrp_val_max (expr_type)); vrp_val_max (expr_type));
} }
extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1); ::extract_range_from_binary_expr (vr, code, expr_type, &vr0, &vr1);
/* Set value_range for n in following sequence: /* Set value_range for n in following sequence:
def = __builtin_memchr (arg, 0, sz) def = __builtin_memchr (arg, 0, sz)
...@@ -748,7 +748,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr, ...@@ -748,7 +748,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max))); wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
tree range_min = build_zero_cst (expr_type); tree range_min = build_zero_cst (expr_type);
tree range_max = wide_int_to_tree (expr_type, wmax - 1); tree range_max = wide_int_to_tree (expr_type, wmax - 1);
set_value_range (vr, VR_RANGE, range_min, range_max, NULL); vr->set (VR_RANGE, range_min, range_max);
return; return;
} }
} }
...@@ -769,17 +769,17 @@ vr_values::extract_range_from_binary_expr (value_range *vr, ...@@ -769,17 +769,17 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
/* Try with VR0 and [-INF, OP1]. */ /* Try with VR0 and [-INF, OP1]. */
if (is_gimple_min_invariant (minus_p ? vr0.max () : vr0.min ())) if (is_gimple_min_invariant (minus_p ? vr0.max () : vr0.min ()))
set_value_range (&n_vr1, VR_RANGE, vrp_val_min (expr_type), op1, NULL); n_vr1.set (VR_RANGE, vrp_val_min (expr_type), op1);
/* Try with VR0 and [OP1, +INF]. */ /* Try with VR0 and [OP1, +INF]. */
else if (is_gimple_min_invariant (minus_p ? vr0.min () : vr0.max ())) else if (is_gimple_min_invariant (minus_p ? vr0.min () : vr0.max ()))
set_value_range (&n_vr1, VR_RANGE, op1, vrp_val_max (expr_type), NULL); n_vr1.set (VR_RANGE, op1, vrp_val_max (expr_type));
/* Try with VR0 and [OP1, OP1]. */ /* Try with VR0 and [OP1, OP1]. */
else else
set_value_range (&n_vr1, VR_RANGE, op1, op1, NULL); n_vr1.set (VR_RANGE, op1, op1);
extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &n_vr1); ::extract_range_from_binary_expr (vr, code, expr_type, &vr0, &n_vr1);
} }
if (vr->varying_p () if (vr->varying_p ()
...@@ -793,17 +793,17 @@ vr_values::extract_range_from_binary_expr (value_range *vr, ...@@ -793,17 +793,17 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
/* Try with [-INF, OP0] and VR1. */ /* Try with [-INF, OP0] and VR1. */
if (is_gimple_min_invariant (minus_p ? vr1.max () : vr1.min ())) if (is_gimple_min_invariant (minus_p ? vr1.max () : vr1.min ()))
set_value_range (&n_vr0, VR_RANGE, vrp_val_min (expr_type), op0, NULL); n_vr0.set (VR_RANGE, vrp_val_min (expr_type), op0);
/* Try with [OP0, +INF] and VR1. */ /* Try with [OP0, +INF] and VR1. */
else if (is_gimple_min_invariant (minus_p ? vr1.min (): vr1.max ())) else if (is_gimple_min_invariant (minus_p ? vr1.min (): vr1.max ()))
set_value_range (&n_vr0, VR_RANGE, op0, vrp_val_max (expr_type), NULL); n_vr0.set (VR_RANGE, op0, vrp_val_max (expr_type));
/* Try with [OP0, OP0] and VR1. */ /* Try with [OP0, OP0] and VR1. */
else else
set_value_range (&n_vr0, VR_RANGE, op0, op0, NULL); n_vr0.set (op0);
extract_range_from_binary_expr_1 (vr, code, expr_type, &n_vr0, &vr1); ::extract_range_from_binary_expr (vr, code, expr_type, &n_vr0, &vr1);
} }
/* If we didn't derive a range for MINUS_EXPR, and /* If we didn't derive a range for MINUS_EXPR, and
...@@ -819,7 +819,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr, ...@@ -819,7 +819,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
|| (vr1.kind () == VR_ANTI_RANGE || (vr1.kind () == VR_ANTI_RANGE
&& vr1.min () == op0 && vr1.min () == op0
&& vr1.min () == vr1.max ()))) && vr1.min () == vr1.max ())))
set_value_range_to_nonnull (vr, expr_type); vr->set_nonnull (expr_type);
} }
/* Extract range information from a unary expression CODE OP0 based on /* Extract range information from a unary expression CODE OP0 based on
...@@ -830,14 +830,14 @@ void ...@@ -830,14 +830,14 @@ void
vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code, vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
tree type, tree op0) tree type, tree op0)
{ {
value_range vr0; value_range_base vr0;
/* Get value ranges for the operand. For constant operands, create /* Get value ranges for the operand. For constant operands, create
a new value range with the operand to simplify processing. */ a new value range with the operand to simplify processing. */
if (TREE_CODE (op0) == SSA_NAME) if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0)); vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0)) else if (is_gimple_min_invariant (op0))
set_value_range_to_value (&vr0, op0, NULL); vr0.set (op0);
else else
vr0.set_varying (); vr0.set_varying ();
...@@ -854,26 +854,28 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt) ...@@ -854,26 +854,28 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
/* Get value ranges for each operand. For constant operands, create /* Get value ranges for each operand. For constant operands, create
a new value range with the operand to simplify processing. */ a new value range with the operand to simplify processing. */
tree op0 = gimple_assign_rhs2 (stmt); tree op0 = gimple_assign_rhs2 (stmt);
value_range vr0; value_range tem0;
value_range *vr0 = &tem0;
if (TREE_CODE (op0) == SSA_NAME) if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0)); vr0 = get_value_range (op0);
else if (is_gimple_min_invariant (op0)) else if (is_gimple_min_invariant (op0))
set_value_range_to_value (&vr0, op0, NULL); tem0.set (op0);
else else
vr0.set_varying (); tem0.set_varying ();
tree op1 = gimple_assign_rhs3 (stmt); tree op1 = gimple_assign_rhs3 (stmt);
value_range vr1; value_range tem1;
value_range *vr1 = &tem1;
if (TREE_CODE (op1) == SSA_NAME) if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1)); vr1 = get_value_range (op1);
else if (is_gimple_min_invariant (op1)) else if (is_gimple_min_invariant (op1))
set_value_range_to_value (&vr1, op1, NULL); tem1.set (op1);
else else
vr1.set_varying (); tem1.set_varying ();
/* The resulting value range is the union of the operand ranges */ /* The resulting value range is the union of the operand ranges */
vr->deep_copy (&vr0); vr->deep_copy (vr0);
vr->union_ (&vr1); vr->union_ (vr1);
} }
...@@ -896,7 +898,7 @@ vr_values::extract_range_from_comparison (value_range *vr, enum tree_code code, ...@@ -896,7 +898,7 @@ vr_values::extract_range_from_comparison (value_range *vr, enum tree_code code,
type. */ type. */
val = fold_convert (type, val); val = fold_convert (type, val);
if (is_gimple_min_invariant (val)) if (is_gimple_min_invariant (val))
set_value_range_to_value (vr, val, NULL); vr->set (val);
else else
vr->update (VR_RANGE, val, val); vr->update (VR_RANGE, val, val);
} }
...@@ -915,18 +917,18 @@ bool ...@@ -915,18 +917,18 @@ bool
vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type, vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
tree op0, tree op1, bool *ovf) tree op0, tree op1, bool *ovf)
{ {
value_range vr0, vr1; value_range_base vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME) if (TREE_CODE (op0) == SSA_NAME)
vr0 = *get_value_range (op0); vr0 = *get_value_range (op0);
else if (TREE_CODE (op0) == INTEGER_CST) else if (TREE_CODE (op0) == INTEGER_CST)
set_value_range_to_value (&vr0, op0, NULL); vr0.set (op0);
else else
vr0.set_varying (); vr0.set_varying ();
if (TREE_CODE (op1) == SSA_NAME) if (TREE_CODE (op1) == SSA_NAME)
vr1 = *get_value_range (op1); vr1 = *get_value_range (op1);
else if (TREE_CODE (op1) == INTEGER_CST) else if (TREE_CODE (op1) == INTEGER_CST)
set_value_range_to_value (&vr1, op1, NULL); vr1.set (op1);
else else
vr1.set_varying (); vr1.set_varying ();
...@@ -1044,7 +1046,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1044,7 +1046,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
&& TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL
&& cfun->after_inlining) && cfun->after_inlining)
{ {
set_value_range_to_null (vr, type); vr->set_null (type);
return; return;
} }
break; break;
...@@ -1185,8 +1187,8 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1185,8 +1187,8 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
maxi = prec - 1; maxi = prec - 1;
goto bitop_builtin; goto bitop_builtin;
bitop_builtin: bitop_builtin:
set_value_range (vr, VR_RANGE, build_int_cst (type, mini), vr->set (VR_RANGE, build_int_cst (type, mini),
build_int_cst (type, maxi), NULL); build_int_cst (type, maxi));
return; return;
case CFN_UBSAN_CHECK_ADD: case CFN_UBSAN_CHECK_ADD:
subcode = PLUS_EXPR; subcode = PLUS_EXPR;
...@@ -1213,10 +1215,9 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1213,10 +1215,9 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
size = targetm.goacc.dim_limit (axis); size = targetm.goacc.dim_limit (axis);
tree type = TREE_TYPE (gimple_call_lhs (stmt)); tree type = TREE_TYPE (gimple_call_lhs (stmt));
set_value_range (vr, VR_RANGE, vr->set(VR_RANGE, build_int_cst (type, is_pos ? 0 : 1),
build_int_cst (type, is_pos ? 0 : 1), size
size ? build_int_cst (type, size - is_pos) ? build_int_cst (type, size - is_pos) : vrp_val_max (type));
: vrp_val_max (type), NULL);
} }
return; return;
case CFN_BUILT_IN_STRLEN: case CFN_BUILT_IN_STRLEN:
...@@ -1230,7 +1231,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1230,7 +1231,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max))); wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
tree range_min = build_zero_cst (type); tree range_min = build_zero_cst (type);
tree range_max = wide_int_to_tree (type, wmax - 1); tree range_max = wide_int_to_tree (type, wmax - 1);
set_value_range (vr, VR_RANGE, range_min, range_max, NULL); vr->set (VR_RANGE, range_min, range_max);
return; return;
} }
break; break;
...@@ -1292,8 +1293,8 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1292,8 +1293,8 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
{ {
/* This is the boolean return value whether compare and /* This is the boolean return value whether compare and
exchange changed anything or not. */ exchange changed anything or not. */
set_value_range (vr, VR_RANGE, build_int_cst (type, 0), vr->set (VR_RANGE, build_int_cst (type, 0),
build_int_cst (type, 1), NULL); build_int_cst (type, 1));
return; return;
} }
break; break;
...@@ -1309,15 +1310,13 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1309,15 +1310,13 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
bool ovf = false; bool ovf = false;
if (check_for_binary_op_overflow (subcode, type, if (check_for_binary_op_overflow (subcode, type,
op0, op1, &ovf)) op0, op1, &ovf))
set_value_range_to_value (vr, vr->set (build_int_cst (type, ovf));
build_int_cst (type, ovf),
NULL);
else if (TYPE_PRECISION (type) == 1 else if (TYPE_PRECISION (type) == 1
&& !TYPE_UNSIGNED (type)) && !TYPE_UNSIGNED (type))
vr->set_varying (); vr->set_varying ();
else else
set_value_range (vr, VR_RANGE, build_int_cst (type, 0), vr->set (VR_RANGE, build_int_cst (type, 0),
build_int_cst (type, 1), NULL); build_int_cst (type, 1));
} }
else if (types_compatible_p (type, TREE_TYPE (op0)) else if (types_compatible_p (type, TREE_TYPE (op0))
&& types_compatible_p (type, TREE_TYPE (op1))) && types_compatible_p (type, TREE_TYPE (op1)))
...@@ -1341,7 +1340,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1341,7 +1340,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
type, op0); type, op0);
extract_range_from_unary_expr (&vr1, NOP_EXPR, extract_range_from_unary_expr (&vr1, NOP_EXPR,
type, op1); type, op1);
extract_range_from_binary_expr_1 (vr, subcode, type, ::extract_range_from_binary_expr (vr, subcode, type,
&vr0, &vr1); &vr0, &vr1);
flag_wrapv = saved_flag_wrapv; flag_wrapv = saved_flag_wrapv;
} }
...@@ -1354,7 +1353,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1354,7 +1353,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
&& gimple_stmt_nonnegative_warnv_p (stmt, &sop)) && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
set_value_range_to_nonnegative (vr, type); set_value_range_to_nonnegative (vr, type);
else if (vrp_stmt_computes_nonzero (stmt)) else if (vrp_stmt_computes_nonzero (stmt))
set_value_range_to_nonnull (vr, type); vr->set_nonnull (type);
else else
vr->set_varying (); vr->set_varying ();
} }
...@@ -1390,7 +1389,7 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt) ...@@ -1390,7 +1389,7 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt)
gimple_assign_rhs2 (stmt)); gimple_assign_rhs2 (stmt));
else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
&& is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
set_value_range_to_value (vr, gimple_assign_rhs1 (stmt), NULL); vr->set (gimple_assign_rhs1 (stmt));
else else
vr->set_varying (); vr->set_varying ();
...@@ -1672,7 +1671,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, ...@@ -1672,7 +1671,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
/* Like in PR19590, scev can return a constant function. */ /* Like in PR19590, scev can return a constant function. */
if (is_gimple_min_invariant (chrec)) if (is_gimple_min_invariant (chrec))
{ {
set_value_range_to_value (vr, chrec, NULL); vr->set (chrec);
return; return;
} }
...@@ -1751,12 +1750,12 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop, ...@@ -1751,12 +1750,12 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
/* Likewise if the addition did. */ /* Likewise if the addition did. */
if (maxvr.kind () == VR_RANGE) if (maxvr.kind () == VR_RANGE)
{ {
value_range initvr; value_range_base initvr;
if (TREE_CODE (init) == SSA_NAME) if (TREE_CODE (init) == SSA_NAME)
initvr = *(get_value_range (init)); initvr = *(get_value_range (init));
else if (is_gimple_min_invariant (init)) else if (is_gimple_min_invariant (init))
set_value_range_to_value (&initvr, init, NULL); initvr.set (init);
else else
return; return;
...@@ -1993,7 +1992,7 @@ vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p, ...@@ -1993,7 +1992,7 @@ vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p,
} }
else if (is_gimple_min_invariant (tem)) else if (is_gimple_min_invariant (tem))
{ {
set_value_range_to_value (vr, tem, NULL); vr->set (tem);
return; return;
} }
} }
...@@ -2007,18 +2006,22 @@ vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p, ...@@ -2007,18 +2006,22 @@ vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p,
/* Helper that gets the value range of the SSA_NAME with version I /* Helper that gets the value range of the SSA_NAME with version I
or a symbolic range containing the SSA_NAME only if the value range or a symbolic range containing the SSA_NAME only if the value range
is varying or undefined. */ is varying or undefined. Uses TEM as storage for the alternate range. */
value_range value_range *
vr_values::get_vr_for_comparison (int i) vr_values::get_vr_for_comparison (int i, value_range *tem)
{ {
value_range vr = *get_value_range (ssa_name (i)); /* Shallow-copy equiv bitmap. */
value_range *vr = get_value_range (ssa_name (i));
/* If name N_i does not have a valid range, use N_i as its own /* If name N_i does not have a valid range, use N_i as its own
range. This allows us to compare against names that may range. This allows us to compare against names that may
have N_i in their ranges. */ have N_i in their ranges. */
if (vr.varying_p () || vr.undefined_p ()) if (vr->varying_p () || vr->undefined_p ())
vr = value_range (VR_RANGE, ssa_name (i), ssa_name (i), NULL); {
tem->set (ssa_name (i));
return tem;
}
return vr; return vr;
} }
...@@ -2038,7 +2041,7 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val, ...@@ -2038,7 +2041,7 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
tree retval, t; tree retval, t;
int used_strict_overflow; int used_strict_overflow;
bool sop; bool sop;
value_range equiv_vr; value_range *equiv_vr, tem_vr;
/* Get the set of equivalences for VAR. */ /* Get the set of equivalences for VAR. */
e = get_value_range (var)->equiv (); e = get_value_range (var)->equiv ();
...@@ -2048,9 +2051,9 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val, ...@@ -2048,9 +2051,9 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
used_strict_overflow = -1; used_strict_overflow = -1;
/* Compare vars' value range with val. */ /* Compare vars' value range with val. */
equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var)); equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var), &tem_vr);
sop = false; sop = false;
retval = compare_range_with_value (comp, &equiv_vr, val, &sop); retval = compare_range_with_value (comp, equiv_vr, val, &sop);
if (retval) if (retval)
used_strict_overflow = sop ? 1 : 0; used_strict_overflow = sop ? 1 : 0;
...@@ -2074,9 +2077,9 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val, ...@@ -2074,9 +2077,9 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
&& prop_simulate_again_p (SSA_NAME_DEF_STMT (name))) && prop_simulate_again_p (SSA_NAME_DEF_STMT (name)))
continue; continue;
equiv_vr = get_vr_for_comparison (i); equiv_vr = get_vr_for_comparison (i, &tem_vr);
sop = false; sop = false;
t = compare_range_with_value (comp, &equiv_vr, val, &sop); t = compare_range_with_value (comp, equiv_vr, val, &sop);
if (t) if (t)
{ {
/* If we get different answers from different members /* If we get different answers from different members
...@@ -2173,7 +2176,8 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2, ...@@ -2173,7 +2176,8 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
if (! ssa_name (i1)) if (! ssa_name (i1))
continue; continue;
value_range vr1 = get_vr_for_comparison (i1); value_range tem_vr1;
value_range *vr1 = get_vr_for_comparison (i1, &tem_vr1);
t = retval = NULL_TREE; t = retval = NULL_TREE;
EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2) EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
...@@ -2183,9 +2187,10 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2, ...@@ -2183,9 +2187,10 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
bool sop = false; bool sop = false;
value_range vr2 = get_vr_for_comparison (i2); value_range tem_vr2;
value_range *vr2 = get_vr_for_comparison (i2, &tem_vr2);
t = compare_ranges (comp, &vr1, &vr2, &sop); t = compare_ranges (comp, vr1, vr2, &sop);
if (t) if (t)
{ {
/* If we get different answers from different members /* If we get different answers from different members
...@@ -2737,7 +2742,8 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) ...@@ -2737,7 +2742,8 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
if (e->flags & EDGE_EXECUTABLE) if (e->flags & EDGE_EXECUTABLE)
{ {
tree arg = PHI_ARG_DEF (phi, i); tree arg = PHI_ARG_DEF (phi, i);
value_range vr_arg; value_range vr_arg_tem;
value_range *vr_arg = &vr_arg_tem;
++edges; ++edges;
...@@ -2750,30 +2756,35 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) ...@@ -2750,30 +2756,35 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
&& e->flags & EDGE_DFS_BACK) && e->flags & EDGE_DFS_BACK)
may_simulate_backedge_again = true; may_simulate_backedge_again = true;
vr_arg = *(get_value_range (arg)); value_range *vr_arg_ = get_value_range (arg);
/* Do not allow equivalences or symbolic ranges to leak in from /* Do not allow equivalences or symbolic ranges to leak in from
backedges. That creates invalid equivalencies. backedges. That creates invalid equivalencies.
See PR53465 and PR54767. */ See PR53465 and PR54767. */
if (e->flags & EDGE_DFS_BACK) if (e->flags & EDGE_DFS_BACK)
{ {
if (!vr_arg.varying_p () && !vr_arg.undefined_p ()) if (!vr_arg_->varying_p () && !vr_arg_->undefined_p ())
{ {
vr_arg.equiv_clear (); vr_arg_tem.set (vr_arg_->kind (), vr_arg_->min (),
if (vr_arg.symbolic_p ()) vr_arg_->max (), NULL);
vr_arg.set_varying (); if (vr_arg_tem.symbolic_p ())
vr_arg_tem.set_varying ();
} }
else
vr_arg = vr_arg_;
} }
/* If the non-backedge arguments range is VR_VARYING then /* If the non-backedge arguments range is VR_VARYING then
we can still try recording a simple equivalence. */ we can still try recording a simple equivalence. */
else if (vr_arg.varying_p ()) else if (vr_arg_->varying_p ())
vr_arg = value_range (VR_RANGE, arg, arg, NULL); vr_arg_tem.set (arg);
else
vr_arg = vr_arg_;
} }
else else
{ {
if (TREE_OVERFLOW_P (arg)) if (TREE_OVERFLOW_P (arg))
arg = drop_tree_overflow (arg); arg = drop_tree_overflow (arg);
vr_arg = value_range (VR_RANGE, arg, arg); vr_arg_tem.set (arg);
} }
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -2781,14 +2792,14 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) ...@@ -2781,14 +2792,14 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
fprintf (dump_file, "\t"); fprintf (dump_file, "\t");
print_generic_expr (dump_file, arg, dump_flags); print_generic_expr (dump_file, arg, dump_flags);
fprintf (dump_file, ": "); fprintf (dump_file, ": ");
dump_value_range (dump_file, &vr_arg); dump_value_range (dump_file, vr_arg);
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
if (first) if (first)
vr_result->deep_copy (&vr_arg); vr_result->deep_copy (vr_arg);
else else
vr_result->union_ (&vr_arg); vr_result->union_ (vr_arg);
first = false; first = false;
if (vr_result->varying_p ()) if (vr_result->varying_p ())
...@@ -2860,8 +2871,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) ...@@ -2860,8 +2871,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
vrp_val_max (vr_result->type ()), vrp_val_max (vr_result->type ()),
build_int_cst (vr_result->type (), 1)); build_int_cst (vr_result->type (), 1));
*vr_result = value_range (vr_result->kind (), new_min, new_max, vr_result->update (vr_result->kind (), new_min, new_max);
vr_result->equiv ());
/* If we dropped either bound to +-INF then if this is a loop /* If we dropped either bound to +-INF then if this is a loop
PHI node SCEV may known more about its value-range. */ PHI node SCEV may known more about its value-range. */
...@@ -3219,7 +3229,7 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, ...@@ -3219,7 +3229,7 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi,
tree op0 = gimple_assign_rhs1 (stmt); tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt); tree op1 = gimple_assign_rhs2 (stmt);
tree op = NULL_TREE; tree op = NULL_TREE;
value_range vr0, vr1; value_range_base vr0, vr1;
wide_int may_be_nonzero0, may_be_nonzero1; wide_int may_be_nonzero0, may_be_nonzero1;
wide_int must_be_nonzero0, must_be_nonzero1; wide_int must_be_nonzero0, must_be_nonzero1;
wide_int mask; wide_int mask;
...@@ -3227,14 +3237,14 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, ...@@ -3227,14 +3237,14 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi,
if (TREE_CODE (op0) == SSA_NAME) if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0)); vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0)) else if (is_gimple_min_invariant (op0))
set_value_range_to_value (&vr0, op0, NULL); vr0.set (op0);
else else
return false; return false;
if (TREE_CODE (op1) == SSA_NAME) if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1)); vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1)) else if (is_gimple_min_invariant (op1))
set_value_range_to_value (&vr1, op1, NULL); vr1.set (op1);
else else
return false; return false;
......
...@@ -75,7 +75,7 @@ class vr_values ...@@ -75,7 +75,7 @@ class vr_values
bool vrp_stmt_computes_nonzero (gimple *); bool vrp_stmt_computes_nonzero (gimple *);
bool op_with_boolean_value_range_p (tree); bool op_with_boolean_value_range_p (tree);
bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *); bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *);
value_range get_vr_for_comparison (int); value_range *get_vr_for_comparison (int, value_range *);
tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool); tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool);
tree compare_names (enum tree_code, tree, tree, bool *); tree compare_names (enum tree_code, tree, tree, bool *);
bool two_valued_val_range_p (tree, tree *, tree *); bool two_valued_val_range_p (tree, tree *, tree *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment