aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog138
-rw-r--r--gcc/bitmap.c6
-rw-r--r--gcc/bitmap.h1
-rw-r--r--gcc/builtins.c6
-rw-r--r--gcc/calls.c2
-rw-r--r--gcc/coretypes.h1
-rw-r--r--gcc/fold-const.c2
-rw-r--r--gcc/gimple-fold.c2
-rw-r--r--gcc/gimple-pretty-print.c2
-rw-r--r--gcc/gimple-ssa-evrp-analyze.c27
-rw-r--r--gcc/gimple-ssa-evrp.c3
-rw-r--r--gcc/gimple-ssa-sprintf.c29
-rw-r--r--gcc/gimple-ssa-warn-alloca.c4
-rw-r--r--gcc/gimple-ssa-warn-restrict.c2
-rw-r--r--gcc/ipa-cp.c50
-rw-r--r--gcc/ipa-prop.c51
-rw-r--r--gcc/ipa-prop.h2
-rw-r--r--gcc/tree-data-ref.c2
-rw-r--r--gcc/tree-ssa-dom.c33
-rw-r--r--gcc/tree-ssa-loop-niter.c4
-rw-r--r--gcc/tree-ssa-strlen.c6
-rw-r--r--gcc/tree-ssa-threadedge.c4
-rw-r--r--gcc/tree-ssanames.c12
-rw-r--r--gcc/tree-ssanames.h8
-rw-r--r--gcc/tree-vect-patterns.c2
-rw-r--r--gcc/tree-vrp.c1026
-rw-r--r--gcc/tree-vrp.h164
-rw-r--r--gcc/vr-values.c638
-rw-r--r--gcc/vr-values.h3
29 files changed, 1272 insertions, 958 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1332e08..4cfd821 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,141 @@
+2018-10-09 Aldy Hernandez <aldyh@redhat.com>
+
+ * bitmap.c (bitmap_head::dump): New.
+ * bitmap.h (bitmap_head): Add dump().
+ * gimple-ssa-evrp-analyze.c
+ (evrp_range_analyzer::try_find_new_range): Adjust for value_range API.
+ (evrp_range_analyzer::set_ssa_range_info): Same.
+ (evrp_range_analyzer::record_ranges_from_phis): Same.
+ (evrp_range_analyzer::record_ranges_from_stmt): Same.
+ * gimple-ssa-evrp.c (evrp_dom_walker::before_dom_children): Same.
+ * gimple-ssa-sprintf.c (get_int_range): Same.
+ (format_integer): Same.
+ (sprintf_dom_walker::handle_gimple_call): Same.
+ * ipa-cp.c (ipcp_vr_lattice::meet_with_1): Same.
+ (ipcp_vr_lattice::top_p): Same.
+ (ipcp_vr_lattice::bottom_p): Same.
+ (ipcp_vr_lattice::set_to_bottom): Same.
+ (ipa_vr_operation_and_type_effects): Same.
+ (propagate_vr_across_jump_function): Same.
+ (ipcp_store_vr_results): Same.
+ * ipa-prop.c (struct ipa_vr_ggc_hash_traits): Same.
+ (ipa_print_node_jump_functions_for_edge): Same.
+ (ipa_get_value_range): Same.
+ (ipa_compute_jump_functions_for_edge): Same.
+ (ipa_write_jump_function): Same.
+ * tree-ssa-dom.c (simplify_stmt_for_jump_threading): Same.
+ * tree-ssa-threadedge.c (record_temporary_equivalences_from_phis):
+ Same.
+ * vr-values.c (set_value_range_to_nonnegative): Same.
+ (set_value_range_to_truthvalue): Same.
+ (vr_values::get_value_range): Same.
+ (vr_values::set_defs_to_varying): Same.
+ (vr_values::update_value_range): Same.
+ (symbolic_range_based_on_p): Same.
+ (vr_values::op_with_boolean_value_range_p): Same.
+ (vr_values::extract_range_for_var_from_comparison_expr): Same.
+ (vr_values::extract_range_from_ssa_name): Same.
+ (vr_values::extract_range_from_binary_expr): Same.
+ (vr_values::extract_range_from_unary_expr): Same.
+ (vr_values::extract_range_from_cond_expr): Same.
+ (vr_values::extract_range_from_comparison): Same.
+ (vr_values::check_for_binary_op_overflow): Same.
+ (vr_values::extract_range_basic): Same.
+ (vr_values::extract_range_from_assignment): Same.
+ (compare_ranges): Same.
+ (compare_range_with_value): Same.
+ (vr_values::adjust_range_with_scev): Same.
+ (vrp_valueize): Same.
+ (vrp_valueize_1): Same.
+ (vr_values::get_vr_for_comparison): Same.
+ (vr_values::compare_name_with_value): Same.
+ (vr_values::compare_names): Same.
+ (vr_values::vrp_evaluate_conditional): Same.
+ (find_case_label_ranges): Same.
+ (vr_values::vrp_visit_switch_stmt): Same.
+ (vr_values::extract_range_from_phi_node): Same.
+ (vr_values::simplify_div_or_mod_using_ranges): Same.
+ (vr_values::simplify_bit_ops_using_ranges): Same.
+ (test_for_singularity): Same.
+ (range_fits_type_p): Same.
+ (vr_values::simplify_cond_using_ranges_1): Same.
+ (vr_values::simplify_switch_using_ranges): Same.
+ (vr_values::simplify_float_conversion_using_ranges): Same.
+ (vr_values::two_valued_val_range_p): Same.
+ (vr_values::add_equivalence): Move to value_range::equiv_add.
+ * vr-values.h (vr_values::add_equivalence): Remove.
+ (VR_INITIALIZER): Remove.
+ * tree-vrp.c (value_range::set): New.
+ (value_range::equiv_add): New.
+ (value_range::value_range): New.
+ (value_range::deep_copy): New.
+ (value_range::check): New.
+ (value_range::equal_p): New.
+ (value_range::ignore_equivs_equal_p): New.
+ (value_range::operator==): New.
+ (value_range::operator!=): New.
+ (value_range::symbolic_p): New.
+ (value_range::numeric_p): New.
+ (value_range::set_undefined): New.
+ (value_range::set_varying): New.
+ (value_range::may_contain_p): New.
+ (value_range::equiv_clear): New.
+ (value_range::singleton_p): New.
+ (value_range::intersect): New.
+ (value_range::dump): New.
+ (value_range::set_and_canonicalize): New.
+ (set_value_range): Adjust for value_range API.
+ (set_value_range_to_undefined): Same.
+ (set_value_range_to_varying): Same.
+ (set_and_canonicalize_value_range): Same.
+ (set_value_range_to_nonnull): Same.
+ (set_value_range_to_null): Same.
+ (range_is_null): Same.
+ (range_is_nonnull): Same.
+ (range_int_cst_p): Same.
+ (range_int_cst_singleton_p): Same.
+ (symbolic_range_p): Same.
+ (range_includes_zero_p): Same.
+ (value_range_constant_singleton): Same.
+ (vrp_set_zero_nonzero_bits): Same.
+ (ranges_from_anti_range): Same.
+ (extract_range_into_wide_ints): Same.
+ (extract_range_from_multiplicative_op): Same.
+ (set_value_range_with_overflow): Same.
+ (extract_range_from_binary_expr_1): Same.
+ (extract_range_from_unary_expr): Same.
+ (dump_value_range): Same.
+ (debug_value_range): Same.
+ (vrp_prop::check_array_ref): Same.
+ (vrp_prop::check_mem_ref): Same.
+ (vrp_prop::vrp_initialize): Same.
+ (vrp_prop::visit_stmt): Same.
+ (intersect_ranges): Same.
+ (vrp_prop::visit_phi): Same.
+ (vrp_prop::vrp_finalize): Same.
+ (determine_value_range_1): Same.
+ (determine_value_range): Same.
+ (vrp_intersect_ranges_1): Rename to...
+ (vrp_intersect_1): this.
+ (vrp_intersect_ranges): Rename to...
+ (value_range::intersect_helper): ...this.
+ (vrp_meet_1): Rename to...
+ (value_range::union_helper): ...this.
+ (vrp_meet): Rename to...
+ (value_range::union_): ...this.
+ (copy_value_range): Remove.
+ * tree-vrp.h (struct value_range): Rewrite into a proper class.
+ (value_range::vrtype): New.
+ (value_range::type): New.
+ (value_range::equiv): New.
+ (value_range::min): New.
+ (value_range::max): New.
+ (value_range::varying_p): New.
+ (value_range::undefined_p): New.
+ (value_range::null_p): New.
+ (value_range::equiv_add): New.
+ (copy_value_range): Remove.
+
2018-10-17 David Malcolm <dmalcolm@redhat.com>
* Makefile.in (SELFTEST_TARGETS): New.
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index d7464d7..538c414 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -2164,6 +2164,12 @@ debug (const bitmap_head *ptr)
fprintf (stderr, "<nil>\n");
}
+void
+bitmap_head::dump ()
+{
+ debug (this);
+}
+
#if CHECKING_P
namespace selftest {
diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index bdf0747..57ae4a6 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -243,6 +243,7 @@ struct GTY(()) bitmap_head {
bitmap_element * GTY((skip(""))) current; /* Last element looked at. */
bitmap_obstack *obstack; /* Obstack to allocate elements from.
If NULL, then use GGC allocation. */
+ void dump ();
};
/* Global data */
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 25e01e4..f64b3d4 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3139,7 +3139,7 @@ expand_builtin_strnlen (tree exp, rtx target, machine_mode target_mode)
return NULL_RTX;
wide_int min, max;
- enum value_range_type rng = get_range_info (bound, &min, &max);
+ enum value_range_kind rng = get_range_info (bound, &min, &max);
if (rng != VR_RANGE)
return NULL_RTX;
@@ -3227,7 +3227,7 @@ determine_block_size (tree len, rtx len_rtx,
else
{
wide_int min, max;
- enum value_range_type range_type = VR_UNDEFINED;
+ enum value_range_kind range_type = VR_UNDEFINED;
/* Determine bounds from the type. */
if (tree_fits_uhwi_p (TYPE_MIN_VALUE (TREE_TYPE (len))))
@@ -3629,7 +3629,7 @@ compute_objsize (tree dest, int ostype)
&& INTEGRAL_TYPE_P (TREE_TYPE (off)))
{
wide_int min, max;
- enum value_range_type rng = get_range_info (off, &min, &max);
+ enum value_range_kind rng = get_range_info (off, &min, &max);
if (rng == VR_RANGE)
{
diff --git a/gcc/calls.c b/gcc/calls.c
index 80af5c3..8978d3b 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1255,7 +1255,7 @@ get_size_range (tree exp, tree range[2], bool allow_zero /* = false */)
bool integral = INTEGRAL_TYPE_P (exptype);
wide_int min, max;
- enum value_range_type range_type;
+ enum value_range_kind range_type;
if (integral)
range_type = determine_value_range (exp, &min, &max);
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 24f82d8..271cce8 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -46,6 +46,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
typedef int64_t gcov_type;
typedef uint64_t gcov_type_unsigned;
+struct bitmap_obstack;
struct bitmap_head;
typedef struct bitmap_head *bitmap;
typedef const struct bitmap_head *const_bitmap;
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 59cedea..4977eef 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -9255,7 +9255,7 @@ bool
expr_not_equal_to (tree t, const wide_int &w)
{
wide_int min, max, nz;
- value_range_type rtype;
+ value_range_kind rtype;
switch (TREE_CODE (t))
{
case INTEGER_CST:
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index fe6bc08..fd48bbf 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -649,7 +649,7 @@ size_must_be_zero_p (tree size)
return false;
wide_int min, max;
- enum value_range_type rtype = get_range_info (size, &min, &max);
+ enum value_range_kind rtype = get_range_info (size, &min, &max);
if (rtype != VR_ANTI_RANGE)
return false;
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 83e2273..7dfec91 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -2123,7 +2123,7 @@ dump_ssaname_info (pretty_printer *buffer, tree node, int spc)
&& SSA_NAME_RANGE_INFO (node))
{
wide_int min, max, nonzero_bits;
- value_range_type range_type = get_range_info (node, &min, &max);
+ value_range_kind range_type = get_range_info (node, &min, &max);
if (range_type == VR_VARYING)
pp_printf (buffer, "# RANGE VR_VARYING");
diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index e9afa80..83917f5 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -82,7 +82,7 @@ value_range *
evrp_range_analyzer::try_find_new_range (tree name,
tree op, tree_code code, tree limit)
{
- value_range vr = VR_INITIALIZER;
+ value_range vr;
value_range *old_vr = get_value_range (name);
/* Discover VR when condition is true. */
@@ -90,11 +90,11 @@ evrp_range_analyzer::try_find_new_range (tree name,
limit, &vr);
/* If we found any usable VR, set the VR to ssa_name and create a
PUSH old value in the stack with the old VR. */
- if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
+ if (!vr.undefined_p () && !vr.varying_p ())
{
- if (old_vr->type == vr.type
- && vrp_operand_equal_p (old_vr->min, vr.min)
- && vrp_operand_equal_p (old_vr->max, vr.max))
+ if (old_vr->kind () == vr.kind ()
+ && vrp_operand_equal_p (old_vr->min (), vr.min ())
+ && vrp_operand_equal_p (old_vr->max (), vr.max ()))
return NULL;
value_range *new_vr = vr_values->allocate_value_range ();
*new_vr = vr;
@@ -110,13 +110,10 @@ evrp_range_analyzer::set_ssa_range_info (tree lhs, value_range *vr)
/* Set the SSA with the value range. */
if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
{
- if ((vr->type == VR_RANGE
- || vr->type == VR_ANTI_RANGE)
- && (TREE_CODE (vr->min) == INTEGER_CST)
- && (TREE_CODE (vr->max) == INTEGER_CST))
- set_range_info (lhs, vr->type,
- wi::to_wide (vr->min),
- wi::to_wide (vr->max));
+ if (vr->constant_p ())
+ set_range_info (lhs, vr->kind (),
+ wi::to_wide (vr->min ()),
+ wi::to_wide (vr->max ()));
}
else if (POINTER_TYPE_P (TREE_TYPE (lhs))
&& range_includes_zero_p (vr) == 0)
@@ -241,7 +238,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
if (virtual_operand_p (lhs))
continue;
- value_range vr_result = VR_INITIALIZER;
+ value_range vr_result;
bool interesting = stmt_interesting_for_vrp (phi);
if (!has_unvisited_preds && interesting)
vr_values->extract_range_from_phi_node (phi, &vr_result);
@@ -284,7 +281,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
else if (stmt_interesting_for_vrp (stmt))
{
edge taken_edge;
- value_range vr = VR_INITIALIZER;
+ value_range vr;
vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
if (output)
{
@@ -315,7 +312,7 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt, bool temporary)
bitmaps. Ugh. */
value_range *new_vr = vr_values->allocate_value_range ();
*new_vr = vr;
- new_vr->equiv = NULL;
+ new_vr->equiv_clear ();
push_value_range (output, new_vr);
}
}
diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index 50e8adc..b075c105 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -161,8 +161,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
value_range *vr = evrp_range_analyzer.get_value_range (output);
/* Mark stmts whose output we fully propagate for removal. */
- if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
- && (val = value_range_constant_singleton (vr))
+ if ((val = value_range_constant_singleton (vr))
&& may_propagate_copy (output, val)
&& !stmt_could_throw_p (stmt)
&& !gimple_has_side_effects (stmt))
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 471bfc4..90f028d 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -1052,9 +1052,7 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
{
/* Try to determine the range of values of the integer argument. */
value_range *vr = vr_values->get_value_range (arg);
- if (vr->type == VR_RANGE
- && TREE_CODE (vr->min) == INTEGER_CST
- && TREE_CODE (vr->max) == INTEGER_CST)
+ if (range_int_cst_p (vr))
{
HOST_WIDE_INT type_min
= (TYPE_UNSIGNED (argtype)
@@ -1063,8 +1061,8 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
HOST_WIDE_INT type_max = tree_to_uhwi (TYPE_MAX_VALUE (argtype));
- *pmin = TREE_INT_CST_LOW (vr->min);
- *pmax = TREE_INT_CST_LOW (vr->max);
+ *pmin = TREE_INT_CST_LOW (vr->min ());
+ *pmax = TREE_INT_CST_LOW (vr->max ());
if (*pmin < *pmax)
{
@@ -1354,12 +1352,10 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values)
/* Try to determine the range of values of the integer argument
(range information is not available for pointers). */
value_range *vr = vr_values->get_value_range (arg);
- if (vr->type == VR_RANGE
- && TREE_CODE (vr->min) == INTEGER_CST
- && TREE_CODE (vr->max) == INTEGER_CST)
+ if (range_int_cst_p (vr))
{
- argmin = vr->min;
- argmax = vr->max;
+ argmin = vr->min ();
+ argmax = vr->max ();
/* Set KNOWNRANGE if the argument is in a known subrange
of the directive's type and neither width nor precision
@@ -1372,12 +1368,11 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values)
res.argmin = argmin;
res.argmax = argmax;
}
- else if (vr->type == VR_ANTI_RANGE)
+ else if (vr->kind () == VR_ANTI_RANGE)
{
/* Handle anti-ranges if/when bug 71690 is resolved. */
}
- else if (vr->type == VR_VARYING
- || vr->type == VR_UNDEFINED)
+ else if (vr->varying_p () || vr->undefined_p ())
{
/* The argument here may be the result of promoting the actual
argument to int. Try to determine the type of the actual
@@ -3903,12 +3898,10 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi)
and use the greater of the two at level 1 and the smaller
of them at level 2. */
value_range *vr = evrp_range_analyzer.get_value_range (size);
- if (vr->type == VR_RANGE
- && TREE_CODE (vr->min) == INTEGER_CST
- && TREE_CODE (vr->max) == INTEGER_CST)
+ if (range_int_cst_p (vr))
dstsize = (warn_level < 2
- ? TREE_INT_CST_LOW (vr->max)
- : TREE_INT_CST_LOW (vr->min));
+ ? TREE_INT_CST_LOW (vr->max ())
+ : TREE_INT_CST_LOW (vr->min ()));
/* The destination size is not constant. If the function is
bounded (e.g., snprintf) a lower bound of zero doesn't
diff --git a/gcc/gimple-ssa-warn-alloca.c b/gcc/gimple-ssa-warn-alloca.c
index d1b1de4..9d2d68a 100644
--- a/gcc/gimple-ssa-warn-alloca.c
+++ b/gcc/gimple-ssa-warn-alloca.c
@@ -272,7 +272,7 @@ alloca_call_type_by_arg (tree arg, tree arg_casted, edge e,
&& TREE_CODE (limit) == SSA_NAME)
{
wide_int min, max;
- value_range_type range_type = get_range_info (limit, &min, &max);
+ value_range_kind range_type = get_range_info (limit, &min, &max);
if (range_type == VR_UNDEFINED || range_type == VR_VARYING)
return alloca_type_and_limit (ALLOCA_BOUND_UNKNOWN);
@@ -364,7 +364,7 @@ alloca_call_type (gimple *stmt, bool is_vla, tree *invalid_casted_type)
// Check the range info if available.
if (TREE_CODE (len) == SSA_NAME)
{
- value_range_type range_type = get_range_info (len, &min, &max);
+ value_range_kind range_type = get_range_info (len, &min, &max);
if (range_type == VR_RANGE)
{
if (wi::leu_p (max, max_size))
diff --git a/gcc/gimple-ssa-warn-restrict.c b/gcc/gimple-ssa-warn-restrict.c
index ea30b71..e3cbf42 100644
--- a/gcc/gimple-ssa-warn-restrict.c
+++ b/gcc/gimple-ssa-warn-restrict.c
@@ -312,7 +312,7 @@ builtin_memref::extend_offset_range (tree offset)
if (TREE_CODE (offset) == SSA_NAME)
{
wide_int min, max;
- value_range_type rng = get_range_info (offset, &min, &max);
+ value_range_kind rng = get_range_info (offset, &min, &max);
if (rng == VR_RANGE)
{
offrange[0] += offset_int::from (min, SIGNED);
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 27ae8e0..4471bae 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -314,7 +314,7 @@ public:
inline bool set_to_bottom ();
bool meet_with (const value_range *p_vr);
bool meet_with (const ipcp_vr_lattice &other);
- void init () { m_vr.type = VR_UNDEFINED; }
+ void init () { gcc_assert (m_vr.undefined_p ()); }
void print (FILE * f);
private:
@@ -914,28 +914,21 @@ ipcp_vr_lattice::meet_with (const value_range *p_vr)
return meet_with_1 (p_vr);
}
-/* Meet the current value of the lattice with value ranfge described by
- OTHER_VR lattice. */
+/* Meet the current value of the lattice with value range described by
+ OTHER_VR lattice. Return TRUE if anything changed. */
bool
ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
{
- tree min = m_vr.min, max = m_vr.max;
- value_range_type type = m_vr.type;
-
if (bottom_p ())
return false;
- if (other_vr->type == VR_VARYING)
+ if (other_vr->varying_p ())
return set_to_bottom ();
- vrp_meet (&m_vr, other_vr);
- if (type != m_vr.type
- || min != m_vr.min
- || max != m_vr.max)
- return true;
- else
- return false;
+ value_range save (m_vr);
+ m_vr.union_ (other_vr);
+ return !m_vr.ignore_equivs_equal_p (save);
}
/* Return true if value range information in the lattice is yet unknown. */
@@ -943,7 +936,7 @@ ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
bool
ipcp_vr_lattice::top_p () const
{
- return m_vr.type == VR_UNDEFINED;
+ return m_vr.undefined_p ();
}
/* Return true if value range information in the lattice is known to be
@@ -952,7 +945,7 @@ ipcp_vr_lattice::top_p () const
bool
ipcp_vr_lattice::bottom_p () const
{
- return m_vr.type == VR_VARYING;
+ return m_vr.varying_p ();
}
/* Set value range information in the lattice to bottom. Return true if it
@@ -961,9 +954,9 @@ ipcp_vr_lattice::bottom_p () const
bool
ipcp_vr_lattice::set_to_bottom ()
{
- if (m_vr.type == VR_VARYING)
+ if (m_vr.varying_p ())
return false;
- m_vr.type = VR_VARYING;
+ m_vr.set_varying ();
return true;
}
@@ -1882,12 +1875,11 @@ ipa_vr_operation_and_type_effects (value_range *dst_vr, value_range *src_vr,
enum tree_code operation,
tree dst_type, tree src_type)
{
- memset (dst_vr, 0, sizeof (*dst_vr));
+ *dst_vr = value_range ();
extract_range_from_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
- if (dst_vr->type == VR_RANGE || dst_vr->type == VR_ANTI_RANGE)
- return true;
- else
+ if (dst_vr->varying_p () || dst_vr->undefined_p ())
return false;
+ return true;
}
/* Propagate value range across jump function JFUNC that is associated with
@@ -1940,11 +1932,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
if (TREE_OVERFLOW_P (val))
val = drop_tree_overflow (val);
- value_range tmpvr;
- memset (&tmpvr, 0, sizeof (tmpvr));
- tmpvr.type = VR_RANGE;
- tmpvr.min = val;
- tmpvr.max = val;
+ value_range tmpvr (VR_RANGE, val, val);
return dest_lat->meet_with (&tmpvr);
}
}
@@ -1953,7 +1941,7 @@ propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
if (jfunc->m_vr
&& ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
param_type,
- TREE_TYPE (jfunc->m_vr->min)))
+ jfunc->m_vr->type ()))
return dest_lat->meet_with (&vr);
else
return dest_lat->set_to_bottom ();
@@ -5028,9 +5016,9 @@ ipcp_store_vr_results (void)
&& !plats->m_value_range.top_p ())
{
vr.known = true;
- vr.type = plats->m_value_range.m_vr.type;
- vr.min = wi::to_wide (plats->m_value_range.m_vr.min);
- vr.max = wi::to_wide (plats->m_value_range.m_vr.max);
+ vr.type = plats->m_value_range.m_vr.kind ();
+ vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
+ vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
}
else
{
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 8b19fe3..1e40997 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -113,16 +113,16 @@ struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <value_range *>
static hashval_t
hash (const value_range *p)
{
- gcc_checking_assert (!p->equiv);
- inchash::hash hstate (p->type);
- hstate.add_ptr (p->min);
- hstate.add_ptr (p->max);
+ gcc_checking_assert (!p->equiv ());
+ inchash::hash hstate (p->kind ());
+ hstate.add_ptr (p->min ());
+ hstate.add_ptr (p->max ());
return hstate.end ();
}
static bool
equal (const value_range *a, const value_range *b)
{
- return a->type == b->type && a->min == b->min && a->max == b->max;
+ return a->ignore_equivs_equal_p (*b);
}
static void
mark_empty (value_range *&p)
@@ -398,10 +398,10 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
{
fprintf (f, " VR ");
fprintf (f, "%s[",
- (jump_func->m_vr->type == VR_ANTI_RANGE) ? "~" : "");
- print_decs (wi::to_wide (jump_func->m_vr->min), f);
+ (jump_func->m_vr->kind () == VR_ANTI_RANGE) ? "~" : "");
+ print_decs (wi::to_wide (jump_func->m_vr->min ()), f);
fprintf (f, ", ");
- print_decs (wi::to_wide (jump_func->m_vr->max), f);
+ print_decs (wi::to_wide (jump_func->m_vr->max ()), f);
fprintf (f, "]\n");
}
else
@@ -1789,13 +1789,9 @@ ipa_get_value_range (value_range *tmp)
value_ranges. */
static value_range *
-ipa_get_value_range (enum value_range_type type, tree min, tree max)
+ipa_get_value_range (enum value_range_kind type, tree min, tree max)
{
- value_range tmp;
- tmp.type = type;
- tmp.min = min;
- tmp.max = max;
- tmp.equiv = NULL;
+ value_range tmp (type, min, max);
return ipa_get_value_range (&tmp);
}
@@ -1804,7 +1800,7 @@ ipa_get_value_range (enum value_range_type type, tree min, tree max)
same value_range structures. */
static void
-ipa_set_jfunc_vr (ipa_jump_func *jf, enum value_range_type type,
+ipa_set_jfunc_vr (ipa_jump_func *jf, enum value_range_kind type,
tree min, tree max)
{
jf->m_vr = ipa_get_value_range (type, min, max);
@@ -1884,22 +1880,19 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
else
{
wide_int min, max;
- value_range_type type;
+ value_range_kind type;
if (TREE_CODE (arg) == SSA_NAME
&& param_type
&& (type = get_range_info (arg, &min, &max))
&& (type == VR_RANGE || type == VR_ANTI_RANGE))
{
- value_range tmpvr,resvr;
-
- tmpvr.type = type;
- tmpvr.min = wide_int_to_tree (TREE_TYPE (arg), min);
- tmpvr.max = wide_int_to_tree (TREE_TYPE (arg), max);
- tmpvr.equiv = NULL;
- memset (&resvr, 0, sizeof (resvr));
+ value_range resvr;
+ value_range tmpvr (type,
+ 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,
&tmpvr, TREE_TYPE (arg));
- if (resvr.type == VR_RANGE || resvr.type == VR_ANTI_RANGE)
+ if (!resvr.undefined_p () && !resvr.varying_p ())
ipa_set_jfunc_vr (jfunc, &resvr);
else
gcc_assert (!jfunc->m_vr);
@@ -4126,9 +4119,9 @@ ipa_write_jump_function (struct output_block *ob,
if (jump_func->m_vr)
{
streamer_write_enum (ob->main_stream, value_rang_type,
- VR_LAST, jump_func->m_vr->type);
- stream_write_tree (ob, jump_func->m_vr->min, true);
- stream_write_tree (ob, jump_func->m_vr->max, true);
+ VR_LAST, jump_func->m_vr->kind ());
+ stream_write_tree (ob, jump_func->m_vr->min (), true);
+ stream_write_tree (ob, jump_func->m_vr->max (), true);
}
}
@@ -4216,7 +4209,7 @@ ipa_read_jump_function (struct lto_input_block *ib,
bool vr_known = bp_unpack_value (&vr_bp, 1);
if (vr_known)
{
- enum value_range_type type = streamer_read_enum (ib, value_range_type,
+ enum value_range_kind type = streamer_read_enum (ib, value_range_kind,
VR_LAST);
tree min = stream_read_tree (ib, data_in);
tree max = stream_read_tree (ib, data_in);
@@ -4647,7 +4640,7 @@ read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
parm_vr->known = bp_unpack_value (&bp, 1);
if (parm_vr->known)
{
- parm_vr->type = streamer_read_enum (ib, value_range_type,
+ parm_vr->type = streamer_read_enum (ib, value_range_kind,
VR_LAST);
parm_vr->min = streamer_read_wide_int (ib);
parm_vr->max = streamer_read_wide_int (ib);
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 55e10cf..8a53bb8 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -160,7 +160,7 @@ struct GTY(()) ipa_vr
{
/* The data fields below are valid only if known is true. */
bool known;
- enum value_range_type type;
+ enum value_range_kind type;
wide_int min;
wide_int max;
};
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 69c5f7b..66e780d 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -721,7 +721,7 @@ split_constant_offset_1 (tree type, tree op0, enum tree_code code, tree op1,
if (TREE_CODE (tmp_var) != SSA_NAME)
return false;
wide_int var_min, var_max;
- value_range_type vr_type = get_range_info (tmp_var, &var_min,
+ value_range_kind vr_type = get_range_info (tmp_var, &var_min,
&var_max);
wide_int var_nonzero = get_nonzero_bits (tmp_var);
signop sgn = TYPE_SIGN (itype);
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index f7cc034..c50618d 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -882,25 +882,27 @@ simplify_stmt_for_jump_threading (gimple *stmt,
return NULL_TREE;
value_range *vr = x_vr_values->get_value_range (op);
- if ((vr->type != VR_RANGE && vr->type != VR_ANTI_RANGE)
- || symbolic_range_p (vr))
+ if (vr->undefined_p ()
+ || vr->varying_p ()
+ || vr->symbolic_p ())
return NULL_TREE;
- if (vr->type == VR_RANGE)
+ if (vr->kind () == VR_RANGE)
{
size_t i, j;
- find_case_label_range (switch_stmt, vr->min, vr->max, &i, &j);
+ find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j);
if (i == j)
{
tree label = gimple_switch_label (switch_stmt, i);
+ tree singleton;
if (CASE_HIGH (label) != NULL_TREE
- ? (tree_int_cst_compare (CASE_LOW (label), vr->min) <= 0
- && tree_int_cst_compare (CASE_HIGH (label), vr->max) >= 0)
- : (tree_int_cst_equal (CASE_LOW (label), vr->min)
- && tree_int_cst_equal (vr->min, vr->max)))
+ ? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0
+ && tree_int_cst_compare (CASE_HIGH (label), vr->max ()) >= 0)
+ : (vr->singleton_p (&singleton)
+ && tree_int_cst_equal (CASE_LOW (label), singleton)))
return label;
if (i > j)
@@ -908,7 +910,7 @@ simplify_stmt_for_jump_threading (gimple *stmt,
}
}
- if (vr->type == VR_ANTI_RANGE)
+ if (vr->kind () == VR_ANTI_RANGE)
{
unsigned n = gimple_switch_num_labels (switch_stmt);
tree min_label = gimple_switch_label (switch_stmt, 1);
@@ -917,10 +919,10 @@ simplify_stmt_for_jump_threading (gimple *stmt,
/* The default label will be taken only if the anti-range of the
operand is entirely outside the bounds of all the (non-default)
case labels. */
- if (tree_int_cst_compare (vr->min, CASE_LOW (min_label)) <= 0
+ if (tree_int_cst_compare (vr->min (), CASE_LOW (min_label)) <= 0
&& (CASE_HIGH (max_label) != NULL_TREE
- ? tree_int_cst_compare (vr->max, CASE_HIGH (max_label)) >= 0
- : tree_int_cst_compare (vr->max, CASE_LOW (max_label)) >= 0))
+ ? tree_int_cst_compare (vr->max (), CASE_HIGH (max_label)) >= 0
+ : tree_int_cst_compare (vr->max (), CASE_LOW (max_label)) >= 0))
return gimple_switch_label (switch_stmt, 0);
}
return NULL_TREE;
@@ -936,11 +938,12 @@ simplify_stmt_for_jump_threading (gimple *stmt,
{
edge dummy_e;
tree dummy_tree;
- value_range new_vr = VR_INITIALIZER;
+ value_range new_vr;
x_vr_values->extract_range_from_stmt (stmt, &dummy_e,
&dummy_tree, &new_vr);
- if (range_int_cst_singleton_p (&new_vr))
- return new_vr.min;
+ tree singleton;
+ if (new_vr.singleton_p (&singleton))
+ return singleton;
}
}
return NULL;
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index 7b6c91c..e2bc936 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -353,7 +353,7 @@ determine_value_range (struct loop *loop, tree type, tree var, mpz_t off,
mpz_t minm, maxm;
basic_block bb;
wide_int minv, maxv;
- enum value_range_type rtype = VR_VARYING;
+ enum value_range_kind rtype = VR_VARYING;
/* If the expression is a constant, we know its value exactly. */
if (integer_zerop (var))
@@ -4673,7 +4673,7 @@ scev_var_range_cant_overflow (tree var, tree step, struct loop *loop)
{
tree type;
wide_int minv, maxv, diff, step_wi;
- enum value_range_type rtype;
+ enum value_range_kind rtype;
if (TREE_CODE (step) != INTEGER_CST || !INTEGRAL_TYPE_P (TREE_TYPE (var)))
return false;
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 3fa5ef5..2db2823 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -1200,7 +1200,7 @@ maybe_set_strlen_range (tree lhs, tree src, tree bound)
else if (TREE_CODE (bound) == SSA_NAME)
{
wide_int minbound, maxbound;
- value_range_type rng = get_range_info (bound, &minbound, &maxbound);
+ value_range_kind rng = get_range_info (bound, &minbound, &maxbound);
if (rng == VR_RANGE)
{
/* For a bound in a known range, adjust the range determined
@@ -1856,7 +1856,7 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt)
cntrange[0] = cntrange[1] = wi::to_wide (cnt);
else if (TREE_CODE (cnt) == SSA_NAME)
{
- enum value_range_type rng = get_range_info (cnt, cntrange, cntrange + 1);
+ enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1);
if (rng == VR_RANGE)
;
else if (rng == VR_ANTI_RANGE)
@@ -3682,7 +3682,7 @@ strlen_check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh)
if we don't have anything better. */
wide_int min, max;
tree type = TREE_TYPE (lhs);
- enum value_range_type vr
+ enum value_range_kind vr
= get_range_info (lhs, &min, &max);
if (vr == VR_VARYING
|| (vr == VR_RANGE
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index a230449..0b1f973 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -166,7 +166,7 @@ record_temporary_equivalences_from_phis (edge e,
away in the VR stack. */
vr_values *vr_values = evrp_range_analyzer->get_vr_values ();
value_range *new_vr = vr_values->allocate_value_range ();
- memset (new_vr, 0, sizeof (value_range));
+ *new_vr = value_range ();
/* There are three cases to consider:
@@ -179,7 +179,7 @@ record_temporary_equivalences_from_phis (edge e,
Otherwise set NEW_VR to varying. This may be overly
conservative. */
if (TREE_CODE (src) == SSA_NAME)
- copy_value_range (new_vr, vr_values->get_value_range (src));
+ new_vr->deep_copy (vr_values->get_value_range (src));
else if (TREE_CODE (src) == INTEGER_CST)
set_value_range_to_value (new_vr, src, NULL);
else
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 6cce43b..66b2941 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -331,7 +331,7 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt,
NAME. */
void
-set_range_info_raw (tree name, enum value_range_type range_type,
+set_range_info_raw (tree name, enum value_range_kind range_type,
const wide_int_ref &min, const wide_int_ref &max)
{
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
@@ -372,7 +372,7 @@ set_range_info_raw (tree name, enum value_range_type range_type,
NAME while making sure we don't store useless range info. */
void
-set_range_info (tree name, enum value_range_type range_type,
+set_range_info (tree name, enum value_range_kind range_type,
const wide_int_ref &min, const wide_int_ref &max)
{
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
@@ -397,11 +397,11 @@ set_range_info (tree name, enum value_range_type range_type,
}
-/* Gets range information MIN, MAX and returns enum value_range_type
- corresponding to tree ssa_name NAME. enum value_range_type returned
+/* Gets range information MIN, MAX and returns enum value_range_kind
+ corresponding to tree ssa_name NAME. enum value_range_kind returned
is used to determine if MIN and MAX are valid values. */
-enum value_range_type
+enum value_range_kind
get_range_info (const_tree name, wide_int *min, wide_int *max)
{
gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
@@ -727,7 +727,7 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
/* Creates a duplicate of the range_info_def at RANGE_INFO of type
RANGE_TYPE for use by the SSA name NAME. */
void
-duplicate_ssa_name_range_info (tree name, enum value_range_type range_type,
+duplicate_ssa_name_range_info (tree name, enum value_range_kind range_type,
struct range_info_def *range_info)
{
struct range_info_def *new_range_info;
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index d39f396..18a001a 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -67,13 +67,13 @@ struct GTY ((variable_size)) range_info_def {
if (VAR)
/* Sets the value range to SSA. */
-extern void set_range_info (tree, enum value_range_type, const wide_int_ref &,
+extern void set_range_info (tree, enum value_range_kind, const wide_int_ref &,
const wide_int_ref &);
-extern void set_range_info_raw (tree, enum value_range_type,
+extern void set_range_info_raw (tree, enum value_range_kind,
const wide_int_ref &,
const wide_int_ref &);
/* Gets the value range from SSA. */
-extern enum value_range_type get_range_info (const_tree, wide_int *,
+extern enum value_range_kind get_range_info (const_tree, wide_int *,
wide_int *);
extern void set_nonzero_bits (tree, const wide_int_ref &);
extern wide_int get_nonzero_bits (const_tree);
@@ -97,7 +97,7 @@ extern bool get_ptr_nonnull (const_tree);
extern tree copy_ssa_name_fn (struct function *, tree, gimple *);
extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
extern tree duplicate_ssa_name_fn (struct function *, tree, gimple *);
-extern void duplicate_ssa_name_range_info (tree, enum value_range_type,
+extern void duplicate_ssa_name_range_info (tree, enum value_range_kind,
struct range_info_def *);
extern void reset_flow_sensitive_info (tree);
extern void reset_flow_sensitive_info_in_bb (basic_block);
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 7956c13..2be9456 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -53,7 +53,7 @@ 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_type vr_type = get_range_info (var, min_value, max_value);
+ value_range_kind vr_type = get_range_info (var, min_value, max_value);
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,
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 0a42da7..d327639 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -73,6 +73,303 @@ along with GCC; see the file COPYING3. If not see
for still active basic-blocks. */
static sbitmap *live;
+/* Initialize value_range. */
+
+void
+value_range::set (enum value_range_kind kind, tree min, tree max,
+ bitmap equiv)
+{
+ m_kind = kind;
+ m_min = min;
+ m_max = max;
+
+ /* Since updating the equivalence set involves deep copying the
+ bitmaps, only do it if absolutely necessary.
+
+ All equivalence bitmaps are allocated from the same obstack. So
+ we can use the obstack associated with EQUIV to allocate vr->equiv. */
+ if (m_equiv == NULL
+ && equiv != NULL)
+ m_equiv = BITMAP_ALLOC (equiv->obstack);
+
+ if (equiv != m_equiv)
+ {
+ if (equiv && !bitmap_empty_p (equiv))
+ bitmap_copy (m_equiv, equiv);
+ else
+ bitmap_clear (m_equiv);
+ }
+ if (flag_checking)
+ check ();
+}
+
+value_range::value_range (value_range_kind kind, tree min, tree max,
+ bitmap equiv)
+{
+ m_equiv = NULL;
+ set (kind, min, max, equiv);
+}
+
+/* Like above, but keep the equivalences intact. */
+
+void
+value_range::update (value_range_kind kind, tree min, tree max)
+{
+ set (kind, min, max, m_equiv);
+}
+
+/* Copy value_range in FROM into THIS while avoiding bitmap sharing.
+
+ Note: The code that avoids the bitmap sharing looks at the existing
+ this->m_equiv, so this function cannot be used to initalize an
+ object. Use the constructors for initialization. */
+
+void
+value_range::deep_copy (const value_range *from)
+{
+ set (from->m_kind, from->min (), from->max (), from->m_equiv);
+}
+
+/* Check the validity of the range. */
+
+void
+value_range::check ()
+{
+ switch (m_kind)
+ {
+ case VR_RANGE:
+ case VR_ANTI_RANGE:
+ {
+ int cmp;
+
+ gcc_assert (m_min && m_max);
+
+ gcc_assert (!TREE_OVERFLOW_P (m_min) && !TREE_OVERFLOW_P (m_max));
+
+ /* Creating ~[-MIN, +MAX] is stupid because that would be
+ the empty set. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (m_min)) && m_kind == VR_ANTI_RANGE)
+ gcc_assert (!vrp_val_is_min (m_min) || !vrp_val_is_max (m_max));
+
+ cmp = compare_values (m_min, m_max);
+ gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
+ break;
+ }
+ case VR_UNDEFINED:
+ case VR_VARYING:
+ gcc_assert (!m_min && !m_max);
+ gcc_assert (!m_equiv || bitmap_empty_p (m_equiv));
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Returns TRUE if THIS == OTHER. Ignores the equivalence bitmap if
+ IGNORE_EQUIVS is TRUE. */
+
+bool
+value_range::equal_p (const value_range &other, bool ignore_equivs) const
+{
+ return (m_kind == other.m_kind
+ && vrp_operand_equal_p (m_min, other.m_min)
+ && vrp_operand_equal_p (m_max, other.m_max)
+ && (ignore_equivs
+ || vrp_bitmap_equal_p (m_equiv, other.m_equiv)));
+}
+
+/* Return equality while ignoring equivalence bitmap. */
+
+bool
+value_range::ignore_equivs_equal_p (const value_range &other) const
+{
+ return equal_p (other, /*ignore_equivs=*/true);
+}
+
+bool
+value_range::operator== (const value_range &other) const
+{
+ return equal_p (other, /*ignore_equivs=*/false);
+}
+
+bool
+value_range::operator!= (const value_range &other) const
+{
+ return !(*this == other);
+}
+
+/* Return TRUE if this is a symbolic range. */
+
+bool
+value_range::symbolic_p () const
+{
+ return (!varying_p ()
+ && !undefined_p ()
+ && (!is_gimple_min_invariant (m_min)
+ || !is_gimple_min_invariant (m_max)));
+}
+
+/* NOTE: This is not the inverse of symbolic_p because the range
+ could also be varying or undefined. Ideally they should be inverse
+ of each other, with varying only applying to symbolics. Varying of
+ constants would be represented as [-MIN, +MAX]. */
+
+bool
+value_range::constant_p () const
+{
+ return (!varying_p ()
+ && !undefined_p ()
+ && TREE_CODE (m_min) == INTEGER_CST
+ && TREE_CODE (m_max) == INTEGER_CST);
+}
+
+void
+value_range::set_undefined ()
+{
+ equiv_clear ();
+ *this = value_range (VR_UNDEFINED, NULL, NULL, NULL);
+}
+
+void
+value_range::set_varying ()
+{
+ equiv_clear ();
+ *this = value_range (VR_VARYING, NULL, NULL, NULL);
+}
+
+/* Return TRUE if it is possible that range contains VAL. */
+
+bool
+value_range::may_contain_p (tree val) const
+{
+ if (varying_p ())
+ return true;
+
+ if (undefined_p ())
+ return true;
+
+ if (m_kind == VR_ANTI_RANGE)
+ {
+ int res = value_inside_range (val, m_min, m_max);
+ return res == 0 || res == -2;
+ }
+ return value_inside_range (val, m_min, m_max) != 0;
+}
+
+void
+value_range::equiv_clear ()
+{
+ if (m_equiv)
+ bitmap_clear (m_equiv);
+}
+
+/* Add VAR and VAR's equivalence set (VAR_VR) to the equivalence
+ bitmap. If no equivalence table has been created, OBSTACK is the
+ obstack to use (NULL for the default obstack).
+
+ This is the central point where equivalence processing can be
+ turned on/off. */
+
+void
+value_range::equiv_add (const_tree var,
+ const value_range *var_vr,
+ bitmap_obstack *obstack)
+{
+ if (!m_equiv)
+ m_equiv = BITMAP_ALLOC (obstack);
+ unsigned ver = SSA_NAME_VERSION (var);
+ bitmap_set_bit (m_equiv, ver);
+ if (var_vr && var_vr->m_equiv)
+ bitmap_ior_into (m_equiv, var_vr->m_equiv);
+}
+
+/* If range is a singleton, place it in RESULT and return TRUE.
+ Note: A singleton can be any gimple invariant, not just constants.
+ So, [&x, &x] counts as a singleton. */
+
+bool
+value_range::singleton_p (tree *result) const
+{
+ if (m_kind == VR_RANGE
+ && vrp_operand_equal_p (m_min, m_max)
+ && is_gimple_min_invariant (m_min))
+ {
+ if (result)
+ *result = m_min;
+ return true;
+ }
+ return false;
+}
+
+tree
+value_range::type () const
+{
+ /* Types are only valid for VR_RANGE and VR_ANTI_RANGE, which are
+ known to have non-zero min/max. */
+ gcc_assert (m_min);
+ return TREE_TYPE (m_min);
+}
+
+/* Dump value range to FILE. */
+
+void
+value_range::dump (FILE *file) const
+{
+ if (undefined_p ())
+ fprintf (file, "UNDEFINED");
+ else if (m_kind == VR_RANGE || m_kind == VR_ANTI_RANGE)
+ {
+ tree type = TREE_TYPE (min ());
+
+ fprintf (file, "%s[", (m_kind == VR_ANTI_RANGE) ? "~" : "");
+
+ if (INTEGRAL_TYPE_P (type)
+ && !TYPE_UNSIGNED (type)
+ && vrp_val_is_min (min ()))
+ fprintf (file, "-INF");
+ else
+ print_generic_expr (file, min ());
+
+ fprintf (file, ", ");
+
+ if (INTEGRAL_TYPE_P (type)
+ && vrp_val_is_max (max ()))
+ fprintf (file, "+INF");
+ else
+ print_generic_expr (file, max ());
+
+ fprintf (file, "]");
+
+ if (m_equiv)
+ {
+ bitmap_iterator bi;
+ unsigned i, c = 0;
+
+ fprintf (file, " EQUIVALENCES: { ");
+
+ EXECUTE_IF_SET_IN_BITMAP (m_equiv, 0, i, bi)
+ {
+ print_generic_expr (file, ssa_name (i));
+ fprintf (file, " ");
+ c++;
+ }
+
+ fprintf (file, "} (%u elements)", c);
+ }
+ }
+ else if (varying_p ())
+ fprintf (file, "VARYING");
+ else
+ fprintf (file, "INVALID RANGE");
+}
+
+void
+value_range::dump () const
+{
+ dump_value_range (stderr, this);
+ fprintf (stderr, "\n");
+}
+
/* Return true if the SSA name NAME is live on the edge E. */
static bool
@@ -175,8 +472,8 @@ vrp_val_is_min (const_tree val)
SGN gives the sign of the values described by the range. */
-enum value_range_type
-intersect_range_with_nonzero_bits (enum value_range_type vr_type,
+enum value_range_kind
+intersect_range_with_nonzero_bits (enum value_range_kind vr_type,
wide_int *min, wide_int *max,
const wide_int &nonzero_bits,
signop sgn)
@@ -245,10 +542,7 @@ intersect_range_with_nonzero_bits (enum value_range_type vr_type,
static inline void
set_value_range_to_undefined (value_range *vr)
{
- vr->type = VR_UNDEFINED;
- vr->min = vr->max = NULL_TREE;
- if (vr->equiv)
- bitmap_clear (vr->equiv);
+ vr->set_undefined ();
}
/* Set value range VR to VR_VARYING. */
@@ -256,67 +550,21 @@ set_value_range_to_undefined (value_range *vr)
void
set_value_range_to_varying (value_range *vr)
{
- vr->type = VR_VARYING;
- vr->min = vr->max = NULL_TREE;
- if (vr->equiv)
- bitmap_clear (vr->equiv);
+ vr->set_varying ();
}
/* Set value range VR to {T, MIN, MAX, EQUIV}. */
void
-set_value_range (value_range *vr, enum value_range_type t, tree min,
- tree max, bitmap equiv)
+set_value_range (value_range *vr, enum value_range_kind kind,
+ tree min, tree max, bitmap equiv)
{
- /* Check the validity of the range. */
- if (flag_checking
- && (t == VR_RANGE || t == VR_ANTI_RANGE))
- {
- int cmp;
-
- gcc_assert (min && max);
-
- gcc_assert (!TREE_OVERFLOW_P (min) && !TREE_OVERFLOW_P (max));
-
- if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
- gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));
-
- cmp = compare_values (min, max);
- gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
- }
-
- if (flag_checking
- && (t == VR_UNDEFINED || t == VR_VARYING))
- {
- gcc_assert (min == NULL_TREE && max == NULL_TREE);
- gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
- }
-
- vr->type = t;
- vr->min = min;
- vr->max = max;
-
- /* Since updating the equivalence set involves deep copying the
- bitmaps, only do it if absolutely necessary.
-
- All equivalence bitmaps are allocated from the same obstack. So
- we can use the obstack associated with EQUIV to allocate vr->equiv. */
- if (vr->equiv == NULL
- && equiv != NULL)
- vr->equiv = BITMAP_ALLOC (equiv->obstack);
-
- if (equiv != vr->equiv)
- {
- if (equiv && !bitmap_empty_p (equiv))
- bitmap_copy (vr->equiv, equiv);
- else
- bitmap_clear (vr->equiv);
- }
+ *vr = value_range (kind, min, max, equiv);
}
-/* Set value range VR to the canonical form of {T, MIN, MAX, EQUIV}.
- This means adjusting T, MIN and MAX representing the case of a
+/* Set value range to the canonical form of {VRTYPE, MIN, MAX, EQUIV}.
+ This means adjusting VRTYPE, MIN and MAX representing the case of a
wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
as anti-rage ~[MAX+1, MIN-1]. Likewise for wrapping anti-ranges.
In corner cases where MAX+1 or MIN-1 wraps this will fall back
@@ -325,18 +573,18 @@ set_value_range (value_range *vr, enum value_range_type t, tree min,
extract ranges from var + CST op limit. */
void
-set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
- tree min, tree max, bitmap equiv)
+value_range::set_and_canonicalize (enum value_range_kind kind,
+ tree min, tree max, bitmap equiv)
{
/* Use the canonical setters for VR_UNDEFINED and VR_VARYING. */
- if (t == VR_UNDEFINED)
+ if (kind == VR_UNDEFINED)
{
- set_value_range_to_undefined (vr);
+ set_undefined ();
return;
}
- else if (t == VR_VARYING)
+ else if (kind == VR_VARYING)
{
- set_value_range_to_varying (vr);
+ set_varying ();
return;
}
@@ -344,7 +592,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
if (TREE_CODE (min) != INTEGER_CST
|| TREE_CODE (max) != INTEGER_CST)
{
- set_value_range (vr, t, min, max, equiv);
+ set_value_range (this, kind, min, max, equiv);
return;
}
@@ -359,7 +607,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
for VR_ANTI_RANGE empty range, so drop to varying as well. */
if (TYPE_PRECISION (TREE_TYPE (min)) == 1)
{
- set_value_range_to_varying (vr);
+ set_varying ();
return;
}
@@ -373,15 +621,15 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
to varying in this case. */
if (tree_int_cst_lt (max, min))
{
- set_value_range_to_varying (vr);
+ set_varying ();
return;
}
- t = t == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
+ kind = kind == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
}
/* Anti-ranges that can be represented as ranges should be so. */
- if (t == VR_ANTI_RANGE)
+ if (kind == VR_ANTI_RANGE)
{
/* For -fstrict-enums we may receive out-of-range ranges so consider
values < -INF and values > INF as -INF/INF as well. */
@@ -395,7 +643,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
{
/* We cannot deal with empty ranges, drop to varying.
??? This could be VR_UNDEFINED instead. */
- set_value_range_to_varying (vr);
+ set_varying ();
return;
}
else if (TYPE_PRECISION (TREE_TYPE (min)) == 1
@@ -407,7 +655,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
min = max = vrp_val_max (TREE_TYPE (min));
else
min = max = vrp_val_min (TREE_TYPE (min));
- t = VR_RANGE;
+ kind = VR_RANGE;
}
else if (is_min
/* As a special exception preserve non-null ranges. */
@@ -417,14 +665,14 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
tree one = build_int_cst (TREE_TYPE (max), 1);
min = int_const_binop (PLUS_EXPR, max, one);
max = vrp_val_max (TREE_TYPE (max));
- t = VR_RANGE;
+ kind = VR_RANGE;
}
else if (is_max)
{
tree one = build_int_cst (TREE_TYPE (min), 1);
max = int_const_binop (MINUS_EXPR, min, one);
min = vrp_val_min (TREE_TYPE (min));
- t = VR_RANGE;
+ kind = VR_RANGE;
}
}
@@ -432,15 +680,7 @@ set_and_canonicalize_value_range (value_range *vr, enum value_range_type t,
to make sure VRP iteration terminates, otherwise we can get into
oscillations. */
- set_value_range (vr, t, min, max, equiv);
-}
-
-/* Copy value range FROM into value range TO. */
-
-void
-copy_value_range (value_range *to, const value_range *from)
-{
- set_value_range (to, from->type, from->min, from->max, from->equiv);
+ set_value_range (this, kind, min, max, equiv);
}
/* Set value range VR to a single value. This function is only called
@@ -462,7 +702,7 @@ void
set_value_range_to_nonnull (value_range *vr, tree type)
{
tree zero = build_int_cst (type, 0);
- set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv);
+ vr->update (VR_ANTI_RANGE, zero, zero);
}
@@ -471,7 +711,7 @@ set_value_range_to_nonnull (value_range *vr, tree type)
void
set_value_range_to_null (value_range *vr, tree type)
{
- set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv);
+ set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv ());
}
/* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */
@@ -503,9 +743,15 @@ vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
static inline bool
range_is_null (const value_range *vr)
{
- return vr->type == VR_RANGE
- && integer_zerop (vr->min)
- && integer_zerop (vr->max);
+ return vr->null_p ();
+}
+
+static inline bool
+range_is_nonnull (const value_range *vr)
+{
+ return (vr->kind () == VR_ANTI_RANGE
+ && vr->min () == vr->max ()
+ && integer_zerop (vr->min ()));
}
/* Return true if max and min of VR are INTEGER_CST. It's not necessary
@@ -514,9 +760,9 @@ range_is_null (const value_range *vr)
bool
range_int_cst_p (const value_range *vr)
{
- return (vr->type == VR_RANGE
- && TREE_CODE (vr->max) == INTEGER_CST
- && TREE_CODE (vr->min) == INTEGER_CST);
+ return (vr->kind () == VR_RANGE
+ && TREE_CODE (vr->min ()) == INTEGER_CST
+ && TREE_CODE (vr->max ()) == INTEGER_CST);
}
/* Return true if VR is a INTEGER_CST singleton. */
@@ -525,16 +771,7 @@ bool
range_int_cst_singleton_p (const value_range *vr)
{
return (range_int_cst_p (vr)
- && tree_int_cst_equal (vr->min, vr->max));
-}
-
-/* Return true if value range VR involves at least one symbol. */
-
-bool
-symbolic_range_p (const value_range *vr)
-{
- return (!is_gimple_min_invariant (vr->min)
- || !is_gimple_min_invariant (vr->max));
+ && tree_int_cst_equal (vr->min (), vr->max ()));
}
/* Return the single symbol (an SSA_NAME) contained in T if any, or NULL_TREE
@@ -849,34 +1086,25 @@ value_inside_range (tree val, tree min, tree max)
bool
range_includes_zero_p (const value_range *vr)
{
- if (vr->type == VR_VARYING)
- return true;
-
- /* Ughh, we don't know. We choose not to optimize. */
- if (vr->type == VR_UNDEFINED)
+ if (vr->varying_p () || vr->undefined_p ())
return true;
-
- tree zero = build_int_cst (TREE_TYPE (vr->min), 0);
- if (vr->type == VR_ANTI_RANGE)
- {
- int res = value_inside_range (zero, vr->min, vr->max);
- return res == 0 || res == -2;
- }
- return value_inside_range (zero, vr->min, vr->max) != 0;
+ tree zero = build_int_cst (vr->type (), 0);
+ return vr->may_contain_p (zero);
}
-/* If *VR has a value rante that is a single constant value return that,
- otherwise return NULL_TREE. */
+/* If *VR has a value range that is a single constant value return that,
+ otherwise return NULL_TREE.
+
+ ?? This actually returns TRUE for [&x, &x], so perhaps "constant"
+ is not the best name. */
tree
value_range_constant_singleton (const value_range *vr)
{
- if (vr->type == VR_RANGE
- && vrp_operand_equal_p (vr->min, vr->max)
- && is_gimple_min_invariant (vr->min))
- return vr->min;
-
- return NULL_TREE;
+ tree result = NULL;
+ if (vr->singleton_p (&result))
+ return result;
+ return NULL;
}
/* Value range wrapper for wide_int_range_set_zero_nonzero_bits.
@@ -899,8 +1127,8 @@ vrp_set_zero_nonzero_bits (const tree expr_type,
return false;
}
wide_int_range_set_zero_nonzero_bits (TYPE_SIGN (expr_type),
- wi::to_wide (vr->min),
- wi::to_wide (vr->max),
+ wi::to_wide (vr->min ()),
+ wi::to_wide (vr->max ()),
*may_be_nonzero, *must_be_nonzero);
return true;
}
@@ -914,40 +1142,36 @@ static bool
ranges_from_anti_range (const value_range *ar,
value_range *vr0, value_range *vr1)
{
- tree type = TREE_TYPE (ar->min);
+ tree type = ar->type ();
- vr0->type = VR_UNDEFINED;
- vr1->type = VR_UNDEFINED;
+ vr0->set_undefined ();
+ vr1->set_undefined ();
/* As a future improvement, we could handle ~[0, A] as: [-INF, -1] U
[A+1, +INF]. Not sure if this helps in practice, though. */
- if (ar->type != VR_ANTI_RANGE
- || TREE_CODE (ar->min) != INTEGER_CST
- || TREE_CODE (ar->max) != INTEGER_CST
+ if (ar->kind () != VR_ANTI_RANGE
+ || TREE_CODE (ar->min ()) != INTEGER_CST
+ || TREE_CODE (ar->max ()) != INTEGER_CST
|| !vrp_val_min (type)
|| !vrp_val_max (type))
return false;
- if (!vrp_val_is_min (ar->min))
- {
- vr0->type = VR_RANGE;
- vr0->min = vrp_val_min (type);
- vr0->max = wide_int_to_tree (type, wi::to_wide (ar->min) - 1);
- }
- if (!vrp_val_is_max (ar->max))
- {
- vr1->type = VR_RANGE;
- vr1->min = wide_int_to_tree (type, wi::to_wide (ar->max) + 1);
- vr1->max = vrp_val_max (type);
- }
- if (vr0->type == VR_UNDEFINED)
+ if (!vrp_val_is_min (ar->min ()))
+ *vr0 = value_range (VR_RANGE,
+ vrp_val_min (type),
+ wide_int_to_tree (type, wi::to_wide (ar->min ()) - 1));
+ if (!vrp_val_is_max (ar->max ()))
+ *vr1 = value_range (VR_RANGE,
+ wide_int_to_tree (type, wi::to_wide (ar->max ()) + 1),
+ vrp_val_max (type));
+ if (vr0->undefined_p ())
{
*vr0 = *vr1;
- vr1->type = VR_UNDEFINED;
+ vr1->set_undefined ();
}
- return vr0->type != VR_UNDEFINED;
+ return !vr0->undefined_p ();
}
/* Extract the components of a value range into a pair of wide ints in
@@ -961,13 +1185,11 @@ extract_range_into_wide_ints (const value_range *vr,
signop sign, unsigned prec,
wide_int &wmin, wide_int &wmax)
{
- if ((vr->type == VR_RANGE
- || vr->type == VR_ANTI_RANGE)
- && TREE_CODE (vr->min) == INTEGER_CST
- && TREE_CODE (vr->max) == INTEGER_CST)
+ gcc_assert (vr->kind () != VR_ANTI_RANGE || vr->symbolic_p ());
+ if (range_int_cst_p (vr))
{
- wmin = wi::to_wide (vr->min);
- wmax = wi::to_wide (vr->max);
+ wmin = wi::to_wide (vr->min ());
+ wmax = wi::to_wide (vr->max ());
}
else
{
@@ -994,14 +1216,15 @@ extract_range_from_multiplicative_op (value_range *vr,
|| code == ROUND_DIV_EXPR
|| code == RSHIFT_EXPR
|| code == LSHIFT_EXPR);
- gcc_assert (vr0->type == VR_RANGE && vr0->type == vr1->type);
+ gcc_assert (vr0->kind () == VR_RANGE
+ && vr0->kind () == vr1->kind ());
- tree type = TREE_TYPE (vr0->min);
+ tree type = vr0->type ();
wide_int res_lb, res_ub;
- wide_int vr0_lb = wi::to_wide (vr0->min);
- wide_int vr0_ub = wi::to_wide (vr0->max);
- wide_int vr1_lb = wi::to_wide (vr1->min);
- wide_int vr1_ub = wi::to_wide (vr1->max);
+ wide_int vr0_lb = wi::to_wide (vr0->min ());
+ wide_int vr0_ub = wi::to_wide (vr0->max ());
+ wide_int vr1_lb = wi::to_wide (vr1->min ());
+ wide_int vr1_ub = wi::to_wide (vr1->max ());
bool overflow_undefined = TYPE_OVERFLOW_UNDEFINED (type);
unsigned prec = TYPE_PRECISION (type);
@@ -1009,9 +1232,9 @@ extract_range_from_multiplicative_op (value_range *vr,
code, TYPE_SIGN (type), prec,
vr0_lb, vr0_ub, vr1_lb, vr1_ub,
overflow_undefined))
- set_and_canonicalize_value_range (vr, VR_RANGE,
- wide_int_to_tree (type, res_lb),
- wide_int_to_tree (type, res_ub), NULL);
+ vr->set_and_canonicalize (VR_RANGE,
+ wide_int_to_tree (type, res_lb),
+ wide_int_to_tree (type, res_ub), NULL);
else
set_value_range_to_varying (vr);
}
@@ -1113,8 +1336,6 @@ set_value_range_with_overflow (value_range &vr,
{
const signop sgn = TYPE_SIGN (type);
const unsigned int prec = TYPE_PRECISION (type);
- vr.type = VR_RANGE;
- vr.equiv = NULL;
/* For one bit precision if max < min, then the swapped
range covers all values. */
@@ -1132,10 +1353,18 @@ set_value_range_with_overflow (value_range &vr,
wide_int tmax = wide_int::from (wmax, prec, sgn);
if ((min_ovf != wi::OVF_NONE) == (max_ovf != wi::OVF_NONE))
{
- /* No overflow or both overflow or underflow. The
- range kind stays VR_RANGE. */
- vr.min = wide_int_to_tree (type, tmin);
- vr.max = wide_int_to_tree (type, tmax);
+ /* If the limits are swapped, we wrapped around and cover
+ the entire range. We have a similar check at the end of
+ extract_range_from_binary_expr_1. */
+ if (wi::gt_p (tmin, tmax, sgn))
+ vr.set_varying ();
+ else
+ /* No overflow or both overflow or underflow. The
+ range kind stays VR_RANGE. */
+ vr = value_range (VR_RANGE,
+ wide_int_to_tree (type, tmin),
+ wide_int_to_tree (type, tmax));
+ return;
}
else if ((min_ovf == wi::OVF_UNDERFLOW && max_ovf == wi::OVF_NONE)
|| (max_ovf == wi::OVF_OVERFLOW && min_ovf == wi::OVF_NONE))
@@ -1144,7 +1373,6 @@ set_value_range_with_overflow (value_range &vr,
changes to VR_ANTI_RANGE. */
bool covers = false;
wide_int tem = tmin;
- vr.type = VR_ANTI_RANGE;
tmin = tmax + 1;
if (wi::cmp (tmin, tmax, sgn) < 0)
covers = true;
@@ -1159,8 +1387,10 @@ set_value_range_with_overflow (value_range &vr,
set_value_range_to_varying (&vr);
return;
}
- vr.min = wide_int_to_tree (type, tmin);
- vr.max = wide_int_to_tree (type, tmax);
+ vr = value_range (VR_ANTI_RANGE,
+ wide_int_to_tree (type, tmin),
+ wide_int_to_tree (type, tmax));
+ return;
}
else
{
@@ -1175,19 +1405,21 @@ set_value_range_with_overflow (value_range &vr,
value. */
wide_int type_min = wi::min_value (prec, sgn);
wide_int type_max = wi::max_value (prec, sgn);
+ tree min, max;
if (min_ovf == wi::OVF_UNDERFLOW)
- vr.min = wide_int_to_tree (type, type_min);
+ min = wide_int_to_tree (type, type_min);
else if (min_ovf == wi::OVF_OVERFLOW)
- vr.min = wide_int_to_tree (type, type_max);
+ min = wide_int_to_tree (type, type_max);
else
- vr.min = wide_int_to_tree (type, wmin);
+ min = wide_int_to_tree (type, wmin);
if (max_ovf == wi::OVF_UNDERFLOW)
- vr.max = wide_int_to_tree (type, type_min);
+ max = wide_int_to_tree (type, type_min);
else if (max_ovf == wi::OVF_OVERFLOW)
- vr.max = wide_int_to_tree (type, type_max);
+ max = wide_int_to_tree (type, type_max);
else
- vr.max = wide_int_to_tree (type, wmax);
+ max = wide_int_to_tree (type, wmax);
+ vr = value_range (VR_RANGE, min, max);
}
}
@@ -1204,8 +1436,8 @@ extract_range_from_binary_expr_1 (value_range *vr,
signop sign = TYPE_SIGN (expr_type);
unsigned int prec = TYPE_PRECISION (expr_type);
value_range vr0 = *vr0_, vr1 = *vr1_;
- value_range vrtem0 = VR_INITIALIZER, vrtem1 = VR_INITIALIZER;
- enum value_range_type type;
+ value_range vrtem0, vrtem1;
+ enum value_range_kind type;
tree min = NULL_TREE, max = NULL_TREE;
int cmp;
@@ -1241,7 +1473,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
}
/* If both ranges are UNDEFINED, so is the result. */
- if (vr0.type == VR_UNDEFINED && vr1.type == VR_UNDEFINED)
+ if (vr0.undefined_p () && vr1.undefined_p ())
{
set_value_range_to_undefined (vr);
return;
@@ -1250,19 +1482,16 @@ extract_range_from_binary_expr_1 (value_range *vr,
code. At some point we may want to special-case operations that
have UNDEFINED result for all or some value-ranges of the not UNDEFINED
operand. */
- else if (vr0.type == VR_UNDEFINED)
+ else if (vr0.undefined_p ())
set_value_range_to_varying (&vr0);
- else if (vr1.type == VR_UNDEFINED)
+ else if (vr1.undefined_p ())
set_value_range_to_varying (&vr1);
/* We get imprecise results from ranges_from_anti_range when
code is EXACT_DIV_EXPR. We could mask out bits in the resulting
- range, but then we also need to hack up vrp_meet. It's just
+ range, but then we also need to hack up vrp_union. It's just
easier to special case when vr0 is ~[0,0] for EXACT_DIV_EXPR. */
- if (code == EXACT_DIV_EXPR
- && vr0.type == VR_ANTI_RANGE
- && vr0.min == vr0.max
- && integer_zerop (vr0.min))
+ if (code == EXACT_DIV_EXPR && range_is_nonnull (&vr0))
{
set_value_range_to_nonnull (vr, expr_type);
return;
@@ -1270,36 +1499,35 @@ extract_range_from_binary_expr_1 (value_range *vr,
/* Now canonicalize anti-ranges to ranges when they are not symbolic
and express ~[] op X as ([]' op X) U ([]'' op X). */
- if (vr0.type == VR_ANTI_RANGE
+ if (vr0.kind () == VR_ANTI_RANGE
&& ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))
{
extract_range_from_binary_expr_1 (vr, code, expr_type, &vrtem0, vr1_);
- if (vrtem1.type != VR_UNDEFINED)
+ if (!vrtem1.undefined_p ())
{
- value_range vrres = VR_INITIALIZER;
- extract_range_from_binary_expr_1 (&vrres, code, expr_type,
- &vrtem1, vr1_);
- vrp_meet (vr, &vrres);
+ value_range vrres;
+ extract_range_from_binary_expr_1 (&vrres, code, expr_type, &vrtem1, vr1_);
+ vr->union_ (&vrres);
}
return;
}
/* Likewise for X op ~[]. */
- if (vr1.type == VR_ANTI_RANGE
+ if (vr1.kind () == VR_ANTI_RANGE
&& ranges_from_anti_range (&vr1, &vrtem0, &vrtem1))
{
extract_range_from_binary_expr_1 (vr, code, expr_type, vr0_, &vrtem0);
- if (vrtem1.type != VR_UNDEFINED)
+ if (!vrtem1.undefined_p ())
{
- value_range vrres = VR_INITIALIZER;
+ value_range vrres;
extract_range_from_binary_expr_1 (&vrres, code, expr_type,
vr0_, &vrtem1);
- vrp_meet (vr, &vrres);
+ vr->union_ (&vrres);
}
return;
}
/* The type of the resulting value range defaults to VR0.TYPE. */
- type = vr0.type;
+ type = vr0.kind ();
/* Refuse to operate on VARYING ranges, ranges of different kinds
and symbolic ranges. As an exception, we allow BIT_{AND,IOR}
@@ -1322,11 +1550,11 @@ extract_range_from_binary_expr_1 (value_range *vr,
&& code != MINUS_EXPR
&& code != RSHIFT_EXPR
&& code != POINTER_PLUS_EXPR
- && (vr0.type == VR_VARYING
- || vr1.type == VR_VARYING
- || vr0.type != vr1.type
- || symbolic_range_p (&vr0)
- || symbolic_range_p (&vr1)))
+ && (vr0.varying_p ()
+ || vr1.varying_p ()
+ || vr0.kind () != vr1.kind ()
+ || vr0.symbolic_p ()
+ || vr1.symbolic_p ()))
{
set_value_range_to_varying (vr);
return;
@@ -1384,24 +1612,20 @@ extract_range_from_binary_expr_1 (value_range *vr,
/* This will normalize things such that calculating
[0,0] - VR_VARYING is not dropped to varying, but is
calculated as [MIN+1, MAX]. */
- if (vr0.type == VR_VARYING)
- {
- vr0.type = VR_RANGE;
- vr0.min = vrp_val_min (expr_type);
- vr0.max = vrp_val_max (expr_type);
- }
- if (vr1.type == VR_VARYING)
- {
- vr1.type = VR_RANGE;
- vr1.min = vrp_val_min (expr_type);
- vr1.max = vrp_val_max (expr_type);
- }
+ if (vr0.varying_p ())
+ vr0.update (VR_RANGE,
+ vrp_val_min (expr_type),
+ vrp_val_max (expr_type));
+ if (vr1.varying_p ())
+ vr1.update (VR_RANGE,
+ vrp_val_min (expr_type),
+ vrp_val_max (expr_type));
const bool minus_p = (code == MINUS_EXPR);
- tree min_op0 = vr0.min;
- tree min_op1 = minus_p ? vr1.max : vr1.min;
- tree max_op0 = vr0.max;
- tree max_op1 = minus_p ? vr1.min : vr1.max;
+ tree min_op0 = vr0.min ();
+ tree min_op1 = minus_p ? vr1.max () : vr1.min ();
+ tree max_op0 = vr0.max ();
+ tree max_op1 = minus_p ? vr1.min () : vr1.max ();
tree sym_min_op0 = NULL_TREE;
tree sym_min_op1 = NULL_TREE;
tree sym_max_op0 = NULL_TREE;
@@ -1414,7 +1638,7 @@ extract_range_from_binary_expr_1 (value_range *vr,
single-symbolic ranges, try to compute the precise resulting range,
but only if we know that this resulting range will also be constant
or single-symbolic. */
- if (vr0.type == VR_RANGE && vr1.type == VR_RANGE
+ if (vr0.kind () == VR_RANGE && vr1.kind () == VR_RANGE
&& (TREE_CODE (min_op0) == INTEGER_CST
|| (sym_min_op0
= get_single_symbol (min_op0, &neg_min_op0, &min_op0)))
@@ -1454,21 +1678,19 @@ extract_range_from_binary_expr_1 (value_range *vr,
/* Adjust the range for possible overflow. */
set_value_range_with_overflow (*vr, expr_type,
wmin, wmax, min_ovf, max_ovf);
- if (vr->type == VR_VARYING)
+ if (vr->varying_p ())
return;
/* Build the symbolic bounds if needed. */
- adjust_symbolic_bound (vr->min, code, expr_type,
+ min = vr->min ();
+ max = vr->max ();
+ adjust_symbolic_bound (min, code, expr_type,
sym_min_op0, sym_min_op1,
neg_min_op0, neg_min_op1);
- adjust_symbolic_bound (vr->max, code, expr_type,
+ adjust_symbolic_bound (max, code, expr_type,
sym_max_op0, sym_max_op1,
neg_max_op0, neg_max_op1);
- /* ?? It would probably be cleaner to eliminate min/max/type
- entirely and hold these values in VR directly. */
- min = vr->min;
- max = vr->max;
- type = vr->type;
+ type = vr->kind ();
}
else
{
@@ -1498,9 +1720,8 @@ extract_range_from_binary_expr_1 (value_range *vr,
extract_range_into_wide_ints (&vr1, sign, prec, vr1_min, vr1_max);
if (wide_int_range_min_max (wmin, wmax, code, sign, prec,
vr0_min, vr0_max, vr1_min, vr1_max))
- set_value_range (vr, VR_RANGE,
- wide_int_to_tree (expr_type, wmin),
- wide_int_to_tree (expr_type, wmax), NULL);
+ vr->update (VR_RANGE, wide_int_to_tree (expr_type, wmin),
+ wide_int_to_tree (expr_type, wmax));
else
set_value_range_to_varying (vr);
return;
@@ -1520,22 +1741,21 @@ extract_range_from_binary_expr_1 (value_range *vr,
|| code == LSHIFT_EXPR)
{
if (range_int_cst_p (&vr1)
- && !wide_int_range_shift_undefined_p (TYPE_SIGN (TREE_TYPE (vr1.min)),
- prec,
- wi::to_wide (vr1.min),
- wi::to_wide (vr1.max)))
+ && !wide_int_range_shift_undefined_p
+ (TYPE_SIGN (TREE_TYPE (vr1.min ())),
+ prec,
+ wi::to_wide (vr1.min ()),
+ wi::to_wide (vr1.max ())))
{
if (code == RSHIFT_EXPR)
{
/* Even if vr0 is VARYING or otherwise not usable, we can derive
useful ranges just from the shift count. E.g.
x >> 63 for signed 64-bit x is always [-1, 0]. */
- if (vr0.type != VR_RANGE || symbolic_range_p (&vr0))
- {
- vr0.type = type = VR_RANGE;
- vr0.min = vrp_val_min (expr_type);
- vr0.max = vrp_val_max (expr_type);
- }
+ if (vr0.kind () != VR_RANGE || vr0.symbolic_p ())
+ vr0.update (VR_RANGE,
+ vrp_val_min (expr_type),
+ vrp_val_max (expr_type));
extract_range_from_multiplicative_op (vr, code, &vr0, &vr1);
return;
}
@@ -1544,16 +1764,15 @@ extract_range_from_binary_expr_1 (value_range *vr,
{
wide_int res_lb, res_ub;
if (wide_int_range_lshift (res_lb, res_ub, sign, prec,
- wi::to_wide (vr0.min),
- wi::to_wide (vr0.max),
- wi::to_wide (vr1.min),
- wi::to_wide (vr1.max),
+ wi::to_wide (vr0.min ()),
+ wi::to_wide (vr0.max ()),
+ wi::to_wide (vr1.min ()),
+ wi::to_wide (vr1.max ()),
TYPE_OVERFLOW_UNDEFINED (expr_type)))
{
min = wide_int_to_tree (expr_type, res_lb);
max = wide_int_to_tree (expr_type, res_ub);
- set_and_canonicalize_value_range (vr, VR_RANGE,
- min, max, NULL);
+ vr->set_and_canonicalize (VR_RANGE, min, max, NULL);
return;
}
}
@@ -1603,11 +1822,11 @@ extract_range_from_binary_expr_1 (value_range *vr,
wide_int_to_tree (expr_type, wmax), NULL);
if (extra_range_p)
{
- value_range extra_range = VR_INITIALIZER;
+ value_range extra_range;
set_value_range (&extra_range, VR_RANGE,
wide_int_to_tree (expr_type, extra_min),
wide_int_to_tree (expr_type, extra_max), NULL);
- vrp_meet (vr, &extra_range);
+ vr->union_ (&extra_range);
}
return;
}
@@ -1740,7 +1959,8 @@ extract_range_from_unary_expr (value_range *vr,
{
signop sign = TYPE_SIGN (type);
unsigned int prec = TYPE_PRECISION (type);
- value_range vr0 = *vr0_, vrtem0 = VR_INITIALIZER, vrtem1 = VR_INITIALIZER;
+ value_range vr0 = *vr0_;
+ value_range vrtem0, vrtem1;
/* VRP only operates on integral and pointer types. */
if (!(INTEGRAL_TYPE_P (op0_type)
@@ -1753,7 +1973,7 @@ extract_range_from_unary_expr (value_range *vr,
}
/* If VR0 is UNDEFINED, so is the result. */
- if (vr0.type == VR_UNDEFINED)
+ if (vr0.undefined_p ())
{
set_value_range_to_undefined (vr);
return;
@@ -1763,14 +1983,14 @@ extract_range_from_unary_expr (value_range *vr,
if (code == PAREN_EXPR || code == OBJ_TYPE_REF)
{
/* PAREN_EXPR and OBJ_TYPE_REF are simple copies. */
- copy_value_range (vr, &vr0);
+ vr->deep_copy (&vr0);
return;
}
else if (code == NEGATE_EXPR)
{
/* -X is simply 0 - X, so re-use existing code that also handles
anti-ranges fine. */
- value_range zero = VR_INITIALIZER;
+ value_range zero;
set_value_range_to_value (&zero, build_int_cst (type, 0), NULL);
extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &zero, &vr0);
return;
@@ -1779,7 +1999,7 @@ extract_range_from_unary_expr (value_range *vr,
{
/* ~X is simply -1 - X, so re-use existing code that also handles
anti-ranges fine. */
- value_range minusone = VR_INITIALIZER;
+ value_range minusone;
set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL);
extract_range_from_binary_expr_1 (vr, MINUS_EXPR,
type, &minusone, &vr0);
@@ -1788,16 +2008,16 @@ extract_range_from_unary_expr (value_range *vr,
/* Now canonicalize anti-ranges to ranges when they are not symbolic
and express op ~[] as (op []') U (op []''). */
- if (vr0.type == VR_ANTI_RANGE
+ if (vr0.kind () == VR_ANTI_RANGE
&& ranges_from_anti_range (&vr0, &vrtem0, &vrtem1))
{
extract_range_from_unary_expr (vr, code, type, &vrtem0, op0_type);
- if (vrtem1.type != VR_UNDEFINED)
+ if (!vrtem1.undefined_p ())
{
- value_range vrres = VR_INITIALIZER;
+ value_range vrres;
extract_range_from_unary_expr (&vrres, code, type,
&vrtem1, op0_type);
- vrp_meet (vr, &vrres);
+ vr->union_ (&vrres);
}
return;
}
@@ -1829,8 +2049,8 @@ extract_range_from_unary_expr (value_range *vr,
pointer anti-ranges. Any remaining anti-ranges at this point
will be integer conversions from SSA names that will be
normalized into VARYING. For instance: ~[x_55, x_55]. */
- gcc_assert (vr0.type != VR_ANTI_RANGE
- || TREE_CODE (vr0.min) != INTEGER_CST);
+ gcc_assert (vr0.kind () != VR_ANTI_RANGE
+ || TREE_CODE (vr0.min ()) != INTEGER_CST);
/* NOTES: Previously we were returning VARYING for all symbolics, but
we can do better by treating them as [-MIN, +MAX]. For
@@ -1853,7 +2073,7 @@ extract_range_from_unary_expr (value_range *vr,
{
tree min = wide_int_to_tree (outer_type, wmin);
tree max = wide_int_to_tree (outer_type, wmax);
- set_and_canonicalize_value_range (vr, VR_RANGE, min, max, NULL);
+ vr->set_and_canonicalize (VR_RANGE, min, max, NULL);
}
else
set_value_range_to_varying (vr);
@@ -1887,76 +2107,21 @@ void dump_all_value_ranges (FILE *);
void dump_vr_equiv (FILE *, bitmap);
void debug_vr_equiv (bitmap);
-
-/* Dump value range VR to FILE. */
-
void
dump_value_range (FILE *file, const value_range *vr)
{
- if (vr == NULL)
+ if (!vr)
fprintf (file, "[]");
- else if (vr->type == VR_UNDEFINED)
- fprintf (file, "UNDEFINED");
- else if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
- {
- tree type = TREE_TYPE (vr->min);
-
- fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");
-
- if (INTEGRAL_TYPE_P (type)
- && !TYPE_UNSIGNED (type)
- && vrp_val_is_min (vr->min))
- fprintf (file, "-INF");
- else
- print_generic_expr (file, vr->min);
-
- fprintf (file, ", ");
-
- if (INTEGRAL_TYPE_P (type)
- && vrp_val_is_max (vr->max))
- fprintf (file, "+INF");
- else
- print_generic_expr (file, vr->max);
-
- fprintf (file, "]");
-
- if (vr->equiv)
- {
- bitmap_iterator bi;
- unsigned i, c = 0;
-
- fprintf (file, " EQUIVALENCES: { ");
-
- EXECUTE_IF_SET_IN_BITMAP (vr->equiv, 0, i, bi)
- {
- print_generic_expr (file, ssa_name (i));
- fprintf (file, " ");
- c++;
- }
-
- fprintf (file, "} (%u elements)", c);
- }
- }
- else if (vr->type == VR_VARYING)
- fprintf (file, "VARYING");
else
- fprintf (file, "INVALID RANGE");
+ vr->dump (file);
}
-
/* Dump value range VR to stderr. */
DEBUG_FUNCTION void
debug_value_range (const value_range *vr)
{
- dump_value_range (stderr, vr);
- fprintf (stderr, "\n");
-}
-
-void
-value_range::dump () const
-{
- debug_value_range (this);
+ vr->dump ();
}
@@ -4200,14 +4365,14 @@ vrp_prop::check_array_ref (location_t location, tree ref,
if (TREE_CODE (low_sub) == SSA_NAME)
{
vr = get_value_range (low_sub);
- if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
+ if (!vr->undefined_p () && !vr->varying_p ())
{
- low_sub = vr->type == VR_RANGE ? vr->max : vr->min;
- up_sub = vr->type == VR_RANGE ? vr->min : vr->max;
+ low_sub = vr->kind () == VR_RANGE ? vr->max () : vr->min ();
+ up_sub = vr->kind () == VR_RANGE ? vr->min () : vr->max ();
}
}
- if (vr && vr->type == VR_ANTI_RANGE)
+ if (vr && vr->kind () == VR_ANTI_RANGE)
{
if (up_bound
&& TREE_CODE (up_sub) == INTEGER_CST
@@ -4335,21 +4500,20 @@ vrp_prop::check_mem_ref (location_t location, tree ref,
break;
vr = get_value_range (varoff);
- if (!vr || vr->type == VR_UNDEFINED || !vr->min || !vr->max)
+ if (!vr || vr->undefined_p () || vr->varying_p ())
break;
- if (TREE_CODE (vr->min) != INTEGER_CST
- || TREE_CODE (vr->max) != INTEGER_CST)
+ if (!vr->constant_p ())
break;
- if (vr->type == VR_RANGE)
+ if (vr->kind () == VR_RANGE)
{
- if (tree_int_cst_lt (vr->min, vr->max))
+ if (tree_int_cst_lt (vr->min (), vr->max ()))
{
offset_int min
- = wi::to_offset (fold_convert (ptrdiff_type_node, vr->min));
+ = wi::to_offset (fold_convert (ptrdiff_type_node, vr->min ()));
offset_int max
- = wi::to_offset (fold_convert (ptrdiff_type_node, vr->max));
+ = wi::to_offset (fold_convert (ptrdiff_type_node, vr->max ()));
if (min < max)
{
offrange[0] += min;
@@ -5121,8 +5285,8 @@ find_case_label_range (gswitch *stmt, tree min, tree max, size_t *min_idx,
enum ssa_prop_result
vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
{
- value_range vr = VR_INITIALIZER;
tree lhs = gimple_get_lhs (stmt);
+ value_range vr;
extract_range_from_stmt (stmt, taken_edge_p, output_p, &vr);
if (*output_p)
@@ -5138,7 +5302,7 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
fprintf (dump_file, "\n");
}
- if (vr.type == VR_VARYING)
+ if (vr.varying_p ())
return SSA_PROP_VARYING;
return SSA_PROP_INTERESTING;
@@ -5191,17 +5355,14 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
SSA_PROP_NOT_INTERESTING. If there are no
{REAL,IMAG}PART_EXPR uses at all,
return SSA_PROP_VARYING. */
- value_range new_vr = VR_INITIALIZER;
+ value_range new_vr;
extract_range_basic (&new_vr, use_stmt);
const value_range *old_vr = get_value_range (use_lhs);
- if (old_vr->type != new_vr.type
- || !vrp_operand_equal_p (old_vr->min, new_vr.min)
- || !vrp_operand_equal_p (old_vr->max, new_vr.max)
- || !vrp_bitmap_equal_p (old_vr->equiv, new_vr.equiv))
+ if (*old_vr != new_vr)
res = SSA_PROP_INTERESTING;
else
res = SSA_PROP_NOT_INTERESTING;
- BITMAP_FREE (new_vr.equiv);
+ new_vr.equiv_clear ();
if (res == SSA_PROP_INTERESTING)
{
*output_p = lhs;
@@ -5229,9 +5390,9 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
possible such range. The resulting range is not canonicalized. */
static void
-union_ranges (enum value_range_type *vr0type,
+union_ranges (enum value_range_kind *vr0type,
tree *vr0min, tree *vr0max,
- enum value_range_type vr1type,
+ enum value_range_kind vr1type,
tree vr1min, tree vr1max)
{
bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
@@ -5500,9 +5661,9 @@ give_up:
possible such range. The resulting range is not canonicalized. */
static void
-intersect_ranges (enum value_range_type *vr0type,
+intersect_ranges (enum value_range_kind *vr0type,
tree *vr0min, tree *vr0max,
- enum value_range_type vr1type,
+ enum value_range_kind vr1type,
tree vr1min, tree vr1max)
{
bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
@@ -5812,33 +5973,29 @@ intersect_ranges (enum value_range_type *vr0type,
*vr0min = vr1min;
*vr0max = vr1max;
}
-
- return;
}
/* Intersect the two value-ranges *VR0 and *VR1 and store the result
in *VR0. This may not be the smallest possible such range. */
-static void
-vrp_intersect_ranges_1 (value_range *vr0, const value_range *vr1)
+void
+value_range::intersect_helper (value_range *vr0, const value_range *vr1)
{
- value_range saved;
-
/* If either range is VR_VARYING the other one wins. */
- if (vr1->type == VR_VARYING)
+ if (vr1->varying_p ())
return;
- if (vr0->type == VR_VARYING)
+ if (vr0->varying_p ())
{
- copy_value_range (vr0, vr1);
+ vr0->deep_copy (vr1);
return;
}
/* When either range is VR_UNDEFINED the resulting range is
VR_UNDEFINED, too. */
- if (vr0->type == VR_UNDEFINED)
+ if (vr0->undefined_p ())
return;
- if (vr1->type == VR_UNDEFINED)
+ if (vr1->undefined_p ())
{
set_value_range_to_undefined (vr0);
return;
@@ -5846,53 +6003,56 @@ vrp_intersect_ranges_1 (value_range *vr0, const value_range *vr1)
/* Save the original vr0 so we can return it as conservative intersection
result when our worker turns things to varying. */
- saved = *vr0;
- intersect_ranges (&vr0->type, &vr0->min, &vr0->max,
- vr1->type, vr1->min, vr1->max);
+ value_range saved (*vr0);
+
+ value_range_kind vr0type = vr0->kind ();
+ tree vr0min = vr0->min ();
+ tree vr0max = vr0->max ();
+ intersect_ranges (&vr0type, &vr0min, &vr0max,
+ vr1->kind (), vr1->min (), vr1->max ());
/* Make sure to canonicalize the result though as the inversion of a
VR_RANGE can still be a VR_RANGE. */
- set_and_canonicalize_value_range (vr0, vr0->type,
- vr0->min, vr0->max, vr0->equiv);
+ vr0->set_and_canonicalize (vr0type, vr0min, vr0max, vr0->m_equiv);
/* If that failed, use the saved original VR0. */
- if (vr0->type == VR_VARYING)
+ if (vr0->varying_p ())
{
*vr0 = saved;
return;
}
/* If the result is VR_UNDEFINED there is no need to mess with
the equivalencies. */
- if (vr0->type == VR_UNDEFINED)
+ if (vr0->undefined_p ())
return;
/* The resulting set of equivalences for range intersection is the union of
the two sets. */
- if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
- bitmap_ior_into (vr0->equiv, vr1->equiv);
- else if (vr1->equiv && !vr0->equiv)
+ if (vr0->m_equiv && vr1->m_equiv && vr0->m_equiv != vr1->m_equiv)
+ bitmap_ior_into (vr0->m_equiv, vr1->m_equiv);
+ else if (vr1->m_equiv && !vr0->m_equiv)
{
/* All equivalence bitmaps are allocated from the same obstack. So
we can use the obstack associated with VR to allocate vr0->equiv. */
- vr0->equiv = BITMAP_ALLOC (vr1->equiv->obstack);
- bitmap_copy (vr0->equiv, vr1->equiv);
+ vr0->m_equiv = BITMAP_ALLOC (vr1->m_equiv->obstack);
+ bitmap_copy (m_equiv, vr1->m_equiv);
}
}
void
-vrp_intersect_ranges (value_range *vr0, const value_range *vr1)
+value_range::intersect (const value_range *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Intersecting\n ");
- dump_value_range (dump_file, vr0);
+ dump_value_range (dump_file, this);
fprintf (dump_file, "\nand\n ");
- dump_value_range (dump_file, vr1);
+ dump_value_range (dump_file, other);
fprintf (dump_file, "\n");
}
- vrp_intersect_ranges_1 (vr0, vr1);
+ intersect_helper (this, other);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");
- dump_value_range (dump_file, vr0);
+ dump_value_range (dump_file, this);
fprintf (dump_file, "\n");
}
}
@@ -5901,39 +6061,41 @@ vrp_intersect_ranges (value_range *vr0, const value_range *vr1)
VR1, store in VR0 a range that contains both VR0 and VR1. This
may not be the smallest possible such range. */
-static void
-vrp_meet_1 (value_range *vr0, const value_range *vr1)
+void
+value_range::union_helper (value_range *vr0, const value_range *vr1)
{
- value_range saved;
-
- if (vr0->type == VR_UNDEFINED)
+ if (vr1->undefined_p ())
{
- set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr1->equiv);
+ /* VR0 already has the resulting range. */
return;
}
- if (vr1->type == VR_UNDEFINED)
+ if (vr0->undefined_p ())
{
- /* VR0 already has the resulting range. */
+ vr0->deep_copy (vr1);
return;
}
- if (vr0->type == VR_VARYING)
+ if (vr0->varying_p ())
{
/* Nothing to do. VR0 already has the resulting range. */
return;
}
- if (vr1->type == VR_VARYING)
+ if (vr1->varying_p ())
{
set_value_range_to_varying (vr0);
return;
}
- saved = *vr0;
- union_ranges (&vr0->type, &vr0->min, &vr0->max,
- vr1->type, vr1->min, vr1->max);
- if (vr0->type == VR_VARYING)
+ value_range saved (*vr0);
+ value_range_kind vr0type = vr0->kind ();
+ tree vr0min = vr0->min ();
+ tree vr0max = vr0->max ();
+ union_ranges (&vr0type, &vr0min, &vr0max,
+ vr1->kind (), vr1->min (), vr1->max ());
+ *vr0 = value_range (vr0type, vr0min, vr0max);
+ if (vr0->varying_p ())
{
/* Failed to find an efficient meet. Before giving up and setting
the result to VARYING, see if we can at least derive a useful
@@ -5941,52 +6103,51 @@ vrp_meet_1 (value_range *vr0, const value_range *vr1)
if (range_includes_zero_p (&saved) == 0
&& range_includes_zero_p (vr1) == 0)
{
- set_value_range_to_nonnull (vr0, TREE_TYPE (saved.min));
+ set_value_range_to_nonnull (vr0, saved.type ());
/* Since this meet operation did not result from the meeting of
two equivalent names, VR0 cannot have any equivalences. */
- if (vr0->equiv)
- bitmap_clear (vr0->equiv);
+ if (vr0->m_equiv)
+ bitmap_clear (vr0->m_equiv);
return;
}
set_value_range_to_varying (vr0);
return;
}
- set_and_canonicalize_value_range (vr0, vr0->type, vr0->min, vr0->max,
- vr0->equiv);
- if (vr0->type == VR_VARYING)
+ vr0->set_and_canonicalize (vr0->kind (), vr0->min (), vr0->max (),
+ vr0->equiv ());
+ if (vr0->varying_p ())
return;
/* The resulting set of equivalences is always the intersection of
the two sets. */
- if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
- bitmap_and_into (vr0->equiv, vr1->equiv);
- else if (vr0->equiv && !vr1->equiv)
- bitmap_clear (vr0->equiv);
+ if (vr0->m_equiv && vr1->m_equiv && vr0->m_equiv != vr1->m_equiv)
+ bitmap_and_into (vr0->m_equiv, vr1->m_equiv);
+ else if (vr0->m_equiv && !vr1->m_equiv)
+ bitmap_clear (vr0->m_equiv);
}
void
-vrp_meet (value_range *vr0, const value_range *vr1)
+value_range::union_ (const value_range *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Meeting\n ");
- dump_value_range (dump_file, vr0);
+ dump_value_range (dump_file, this);
fprintf (dump_file, "\nand\n ");
- dump_value_range (dump_file, vr1);
+ dump_value_range (dump_file, other);
fprintf (dump_file, "\n");
}
- vrp_meet_1 (vr0, vr1);
+ union_helper (this, other);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");
- dump_value_range (dump_file, vr0);
+ dump_value_range (dump_file, this);
fprintf (dump_file, "\n");
}
}
-
/* Visit all arguments for PHI node PHI that flow through executable
edges. If a valid value range can be derived from all the incoming
value ranges, set a new range for the LHS of PHI. */
@@ -5995,7 +6156,7 @@ enum ssa_prop_result
vrp_prop::visit_phi (gphi *phi)
{
tree lhs = PHI_RESULT (phi);
- value_range vr_result = VR_INITIALIZER;
+ value_range vr_result;
extract_range_from_phi_node (phi, &vr_result);
if (update_value_range (lhs, &vr_result))
{
@@ -6008,7 +6169,7 @@ vrp_prop::visit_phi (gphi *phi)
fprintf (dump_file, "\n");
}
- if (vr_result.type == VR_VARYING)
+ if (vr_result.varying_p ())
return SSA_PROP_VARYING;
return SSA_PROP_INTERESTING;
@@ -6192,16 +6353,17 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
op = lhs_of_dominating_assert (op, bb, stmt);
const value_range *vr = vr_values->get_value_range (op);
- if ((vr->type != VR_RANGE && vr->type != VR_ANTI_RANGE)
- || symbolic_range_p (vr))
+ if (vr->undefined_p ()
+ || vr->varying_p ()
+ || vr->symbolic_p ())
return NULL_TREE;
- if (vr->type == VR_RANGE)
+ if (vr->kind () == VR_RANGE)
{
size_t i, j;
/* Get the range of labels that contain a part of the operand's
value range. */
- find_case_label_range (switch_stmt, vr->min, vr->max, &i, &j);
+ find_case_label_range (switch_stmt, vr->min (), vr->max (), &i, &j);
/* Is there only one such label? */
if (i == j)
@@ -6211,10 +6373,11 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
/* The i'th label will be taken only if the value range of the
operand is entirely within the bounds of this label. */
if (CASE_HIGH (label) != NULL_TREE
- ? (tree_int_cst_compare (CASE_LOW (label), vr->min) <= 0
- && tree_int_cst_compare (CASE_HIGH (label), vr->max) >= 0)
- : (tree_int_cst_equal (CASE_LOW (label), vr->min)
- && tree_int_cst_equal (vr->min, vr->max)))
+ ? (tree_int_cst_compare (CASE_LOW (label), vr->min ()) <= 0
+ && tree_int_cst_compare (CASE_HIGH (label),
+ vr->max ()) >= 0)
+ : (tree_int_cst_equal (CASE_LOW (label), vr->min ())
+ && tree_int_cst_equal (vr->min (), vr->max ())))
return label;
}
@@ -6224,7 +6387,7 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
return gimple_switch_label (switch_stmt, 0);
}
- if (vr->type == VR_ANTI_RANGE)
+ if (vr->kind () == VR_ANTI_RANGE)
{
unsigned n = gimple_switch_num_labels (switch_stmt);
tree min_label = gimple_switch_label (switch_stmt, 1);
@@ -6233,10 +6396,12 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
/* The default label will be taken only if the anti-range of the
operand is entirely outside the bounds of all the (non-default)
case labels. */
- if (tree_int_cst_compare (vr->min, CASE_LOW (min_label)) <= 0
+ if (tree_int_cst_compare (vr->min (), CASE_LOW (min_label)) <= 0
&& (CASE_HIGH (max_label) != NULL_TREE
- ? tree_int_cst_compare (vr->max, CASE_HIGH (max_label)) >= 0
- : tree_int_cst_compare (vr->max, CASE_LOW (max_label)) >= 0))
+ ? tree_int_cst_compare (vr->max (),
+ CASE_HIGH (max_label)) >= 0
+ : tree_int_cst_compare (vr->max (),
+ CASE_LOW (max_label)) >= 0))
return gimple_switch_label (switch_stmt, 0);
}
@@ -6253,11 +6418,12 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
{
edge dummy_e;
tree dummy_tree;
- value_range new_vr = VR_INITIALIZER;
+ value_range new_vr;
vr_values->extract_range_from_stmt (stmt, &dummy_e,
&dummy_tree, &new_vr);
- if (range_int_cst_singleton_p (&new_vr))
- return new_vr.min;
+ tree singleton;
+ if (new_vr.singleton_p (&singleton))
+ return singleton;
}
}
@@ -6429,20 +6595,16 @@ vrp_prop::vrp_finalize (bool warn_array_bounds_p)
continue;
const value_range *vr = get_value_range (name);
- if (!name
- || (vr->type == VR_VARYING)
- || (vr->type == VR_UNDEFINED)
- || (TREE_CODE (vr->min) != INTEGER_CST)
- || (TREE_CODE (vr->max) != INTEGER_CST))
+ if (!name || !vr->constant_p ())
continue;
if (POINTER_TYPE_P (TREE_TYPE (name))
&& range_includes_zero_p (vr) == 0)
set_ptr_nonnull (name);
else if (!POINTER_TYPE_P (TREE_TYPE (name)))
- set_range_info (name, vr->type,
- wi::to_wide (vr->min),
- wi::to_wide (vr->max));
+ set_range_info (name, vr->kind (),
+ wi::to_wide (vr->min ()),
+ wi::to_wide (vr->max ()));
}
/* If we're checking array refs, we want to merge information on
@@ -6634,7 +6796,7 @@ determine_value_range_1 (value_range *vr, tree expr)
{
if (BINARY_CLASS_P (expr))
{
- value_range vr0 = VR_INITIALIZER, vr1 = VR_INITIALIZER;
+ value_range vr0, vr1;
determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1));
extract_range_from_binary_expr_1 (vr, TREE_CODE (expr), TREE_TYPE (expr),
@@ -6642,7 +6804,7 @@ determine_value_range_1 (value_range *vr, tree expr)
}
else if (UNARY_CLASS_P (expr))
{
- value_range vr0 = VR_INITIALIZER;
+ value_range vr0;
determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
extract_range_from_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
&vr0, TREE_TYPE (TREE_OPERAND (expr, 0)));
@@ -6651,7 +6813,7 @@ determine_value_range_1 (value_range *vr, tree expr)
set_value_range_to_value (vr, expr, NULL);
else
{
- value_range_type kind;
+ value_range_kind kind;
wide_int min, max;
/* For SSA names try to extract range info computed by VRP. Otherwise
fall back to varying. */
@@ -6668,18 +6830,16 @@ determine_value_range_1 (value_range *vr, tree expr)
/* Compute a value-range for EXPR and set it in *MIN and *MAX. Return
the determined range type. */
-value_range_type
+value_range_kind
determine_value_range (tree expr, wide_int *min, wide_int *max)
{
- value_range vr = VR_INITIALIZER;
+ value_range vr;
determine_value_range_1 (&vr, expr);
- if ((vr.type == VR_RANGE
- || vr.type == VR_ANTI_RANGE)
- && !symbolic_range_p (&vr))
+ if (vr.constant_p ())
{
- *min = wi::to_wide (vr.min);
- *max = wi::to_wide (vr.max);
- return vr.type;
+ *min = wi::to_wide (vr.min ());
+ *max = wi::to_wide (vr.max ());
+ return vr.kind ();
}
return VR_VARYING;
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index 655cf05..c251329 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -20,42 +20,143 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_VRP_H
#define GCC_TREE_VRP_H
-/* Type of value ranges. See value_range below for a
- description of these types. */
-enum value_range_type { VR_UNDEFINED, VR_RANGE,
- VR_ANTI_RANGE, VR_VARYING, VR_LAST };
+/* Types of value ranges. */
+enum value_range_kind
+{
+ /* Empty range. */
+ VR_UNDEFINED,
+ /* Range spans the entire domain. */
+ VR_VARYING,
+ /* Range is [MIN, MAX]. */
+ VR_RANGE,
+ /* Range is ~[MIN, MAX]. */
+ VR_ANTI_RANGE,
+ /* Range is a nice guy. */
+ VR_LAST
+};
/* Range of values that can be associated with an SSA_NAME after VRP
has executed. */
-struct GTY((for_user)) value_range
+class GTY((for_user)) value_range
{
- /* Lattice value represented by this range. */
- enum value_range_type type;
+ public:
+ value_range ();
+ value_range (value_range_kind, tree, tree, bitmap = NULL);
+ void update (value_range_kind, tree, tree);
+ bool operator== (const value_range &) const;
+ bool operator!= (const value_range &) const;
+ void intersect (const value_range *);
+ void union_ (const value_range *);
+
+ /* Types of value ranges. */
+ bool undefined_p () const;
+ bool varying_p () const;
+ bool symbolic_p () const;
+ bool constant_p () const;
+ void set_undefined ();
+ void set_varying ();
+
+ /* Equivalence bitmap methods. */
+ bitmap equiv () const;
+ void equiv_clear ();
+ void equiv_add (const_tree, const value_range *, bitmap_obstack * = NULL);
+
+ /* Misc methods. */
+ tree type () const;
+ bool null_p () const;
+ bool may_contain_p (tree) const;
+ bool singleton_p (tree *result = NULL) const;
+ void deep_copy (const value_range *);
+ bool ignore_equivs_equal_p (const value_range &) const;
+ void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap);
+ void dump (FILE *) const;
+ void dump () const;
+
+ enum value_range_kind kind () const;
+ tree min () const;
+ tree max () const;
+
+ private:
+ void set (value_range_kind, tree, tree, bitmap);
+ void check ();
+ bool equal_p (const value_range &, bool ignore_equivs) const;
+ void intersect_helper (value_range *, const value_range *);
+ void union_helper (value_range *, const value_range *);
+
+ enum value_range_kind m_kind;
+ public:
+ /* These should be private, but GTY is a piece of crap. */
+ tree m_min;
+ tree m_max;
+ /* Set of SSA names whose value ranges are equivalent to this one.
+ This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */
+ bitmap m_equiv;
+};
- /* Minimum and maximum values represented by this range. These
- values should be interpreted as follows:
+inline
+value_range::value_range ()
+{
+ m_kind = VR_UNDEFINED;
+ m_min = m_max = NULL;
+ m_equiv = NULL;
+}
- - If TYPE is VR_UNDEFINED or VR_VARYING then MIN and MAX must
- be NULL.
+/* Return the kind of this range. */
- - If TYPE == VR_RANGE then MIN holds the minimum value and
- MAX holds the maximum value of the range [MIN, MAX].
+inline value_range_kind
+value_range::kind () const
+{
+ return m_kind;
+}
- - If TYPE == ANTI_RANGE the variable is known to NOT
- take any values in the range [MIN, MAX]. */
- tree min;
- tree max;
+inline bitmap
+value_range::equiv () const
+{
+ return m_equiv;
+}
- /* Set of SSA names whose value ranges are equivalent to this one.
- This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */
- bitmap equiv;
+/* Return the lower bound. */
- /* Dump value range to stderr. */
- void dump () const;
-};
+inline tree
+value_range::min () const
+{
+ return m_min;
+}
+
+/* Return the upper bound. */
+
+inline tree
+value_range::max () const
+{
+ return m_max;
+}
+
+/* Return TRUE if range spans the entire possible domain. */
+
+inline bool
+value_range::varying_p () const
+{
+ return m_kind == VR_VARYING;
+}
+
+/* Return TRUE if range is undefined (essentially the empty set). */
+
+inline bool
+value_range::undefined_p () const
+{
+ return m_kind == VR_UNDEFINED;
+}
+
+/* Return TRUE if range is the constant zero. */
+
+inline bool
+value_range::null_p () const
+{
+ return (m_kind == VR_RANGE
+ && integer_zerop (m_min)
+ && integer_zerop (m_max));
+}
-extern void vrp_intersect_ranges (value_range *vr0, const value_range *vr1);
-extern void vrp_meet (value_range *vr0, const value_range *vr1);
extern void dump_value_range (FILE *, const value_range *);
extern void extract_range_from_unary_expr (value_range *vr,
enum tree_code code,
@@ -64,8 +165,8 @@ extern void extract_range_from_unary_expr (value_range *vr,
tree op0_type);
extern bool vrp_operand_equal_p (const_tree, const_tree);
-extern enum value_range_type intersect_range_with_nonzero_bits
- (enum value_range_type, wide_int *, wide_int *, const wide_int &, signop);
+extern enum value_range_kind intersect_range_with_nonzero_bits
+ (enum value_range_kind, wide_int *, wide_int *, const wide_int &, signop);
struct assert_info
{
@@ -90,19 +191,14 @@ extern bool range_includes_zero_p (const value_range *);
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 (value_range *, enum value_range_type, tree,
+extern void set_value_range (value_range *, enum value_range_kind, tree,
tree, bitmap);
-extern void set_and_canonicalize_value_range (value_range *,
- enum value_range_type,
- tree, tree, bitmap);
extern bool vrp_bitmap_equal_p (const_bitmap, const_bitmap);
extern tree value_range_constant_singleton (const value_range *);
-extern bool symbolic_range_p (const value_range *);
extern int compare_values (tree, tree);
extern int compare_values_warnv (tree, tree, bool *);
extern bool vrp_val_is_min (const_tree);
extern bool vrp_val_is_max (const_tree);
-extern void copy_value_range (value_range *, const value_range *);
extern void set_value_range_to_value (value_range *, tree, bitmap);
extern void extract_range_from_binary_expr_1 (value_range *, enum tree_code,
tree, const value_range *,
@@ -121,5 +217,5 @@ extern bool range_int_cst_singleton_p (const value_range *);
extern int value_inside_range (tree, tree, tree);
extern tree get_single_symbol (tree, bool *, tree *);
extern void maybe_set_nonzero_bits (edge, tree);
-extern value_range_type determine_value_range (tree, wide_int *, wide_int *);
+extern value_range_kind determine_value_range (tree, wide_int *, wide_int *);
#endif /* GCC_TREE_VRP_H */
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 32392a1..8c9fd15 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -55,7 +55,7 @@ static inline void
set_value_range_to_nonnegative (value_range *vr, tree type)
{
tree zero = build_int_cst (type, 0);
- set_value_range (vr, VR_RANGE, zero, vrp_val_max (type), vr->equiv);
+ vr->update (VR_RANGE, zero, vrp_val_max (type));
}
/* Set value range VR to a range of a truthvalue of type TYPE. */
@@ -66,9 +66,7 @@ set_value_range_to_truthvalue (value_range *vr, tree type)
if (TYPE_PRECISION (type) == 1)
set_value_range_to_varying (vr);
else
- set_value_range (vr, VR_RANGE,
- build_int_cst (type, 0), build_int_cst (type, 1),
- vr->equiv);
+ vr->update (VR_RANGE, build_int_cst (type, 0), build_int_cst (type, 1));
}
@@ -80,8 +78,7 @@ set_value_range_to_truthvalue (value_range *vr, tree type)
value_range *
vr_values::get_value_range (const_tree var)
{
- static const value_range vr_const_varying
- = { VR_VARYING, NULL_TREE, NULL_TREE, NULL };
+ static const value_range vr_const_varying (VR_VARYING, NULL, NULL);
value_range *vr;
tree sym;
unsigned ver = SSA_NAME_VERSION (var);
@@ -106,10 +103,7 @@ vr_values::get_value_range (const_tree var)
/* Create a default value range. */
vr_value[ver] = vr = vrp_value_range_pool.allocate ();
- memset (vr, 0, sizeof (*vr));
-
- /* Defer allocating the equivalence set. */
- vr->equiv = NULL;
+ vr->set_undefined ();
/* If VAR is a default definition of a parameter, the variable can
take any value in VAR's type. */
@@ -128,7 +122,7 @@ vr_values::get_value_range (const_tree var)
else if (INTEGRAL_TYPE_P (TREE_TYPE (sym)))
{
wide_int min, max;
- value_range_type rtype = get_range_info (var, &min, &max);
+ value_range_kind rtype = get_range_info (var, &min, &max);
if (rtype == VR_RANGE || rtype == VR_ANTI_RANGE)
set_value_range (vr, rtype,
wide_int_to_tree (TREE_TYPE (var), min),
@@ -159,7 +153,7 @@ vr_values::set_defs_to_varying (gimple *stmt)
{
value_range *vr = get_value_range (def);
/* Avoid writing to vr_const_varying get_value_range may return. */
- if (vr->type != VR_VARYING)
+ if (!vr->varying_p ())
set_value_range_to_varying (vr);
}
}
@@ -185,24 +179,21 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
{
wide_int min, max;
- value_range_type rtype = get_range_info (var, &min, &max);
+ value_range_kind rtype = get_range_info (var, &min, &max);
if (rtype == VR_RANGE || rtype == VR_ANTI_RANGE)
{
tree nr_min, nr_max;
nr_min = wide_int_to_tree (TREE_TYPE (var), min);
nr_max = wide_int_to_tree (TREE_TYPE (var), max);
- value_range nr = VR_INITIALIZER;
- set_and_canonicalize_value_range (&nr, rtype, nr_min, nr_max, NULL);
- vrp_intersect_ranges (new_vr, &nr);
+ value_range nr;
+ nr.set_and_canonicalize (rtype, nr_min, nr_max, NULL);
+ new_vr->intersect (&nr);
}
}
/* Update the value range, if necessary. */
old_vr = get_value_range (var);
- is_new = old_vr->type != new_vr->type
- || !vrp_operand_equal_p (old_vr->min, new_vr->min)
- || !vrp_operand_equal_p (old_vr->max, new_vr->max)
- || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv);
+ is_new = *old_vr != *new_vr;
if (is_new)
{
@@ -212,40 +203,22 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
the same. We may not have is_new when transitioning to
UNDEFINED. If old_vr->type is VARYING, we shouldn't be
called. */
- if (new_vr->type == VR_UNDEFINED)
+ if (new_vr->undefined_p ())
{
- BITMAP_FREE (new_vr->equiv);
set_value_range_to_varying (old_vr);
set_value_range_to_varying (new_vr);
return true;
}
else
- set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
- new_vr->equiv);
+ set_value_range (old_vr, new_vr->kind (),
+ new_vr->min (), new_vr->max (), new_vr->equiv ());
}
- BITMAP_FREE (new_vr->equiv);
+ new_vr->equiv_clear ();
return is_new;
}
-
-/* Add VAR and VAR's equivalence set to EQUIV. This is the central
- point where equivalence processing can be turned on/off. */
-
-void
-vr_values::add_equivalence (bitmap *equiv, const_tree var)
-{
- unsigned ver = SSA_NAME_VERSION (var);
- value_range *vr = get_value_range (var);
-
- if (*equiv == NULL)
- *equiv = BITMAP_ALLOC (&vrp_equiv_obstack);
- bitmap_set_bit (*equiv, ver);
- if (vr && vr->equiv)
- bitmap_ior_into (*equiv, vr->equiv);
-}
-
/* Return true if value range VR involves exactly one symbol SYM. */
static bool
@@ -254,16 +227,16 @@ symbolic_range_based_on_p (value_range *vr, const_tree sym)
bool neg, min_has_symbol, max_has_symbol;
tree inv;
- if (is_gimple_min_invariant (vr->min))
+ if (is_gimple_min_invariant (vr->min ()))
min_has_symbol = false;
- else if (get_single_symbol (vr->min, &neg, &inv) == sym)
+ else if (get_single_symbol (vr->min (), &neg, &inv) == sym)
min_has_symbol = true;
else
return false;
- if (is_gimple_min_invariant (vr->max))
+ if (is_gimple_min_invariant (vr->max ()))
max_has_symbol = false;
- else if (get_single_symbol (vr->max, &neg, &inv) == sym)
+ else if (get_single_symbol (vr->max (), &neg, &inv) == sym)
max_has_symbol = true;
else
return false;
@@ -403,9 +376,9 @@ vr_values::op_with_boolean_value_range_p (tree op)
return false;
vr = get_value_range (op);
- return (vr->type == VR_RANGE
- && integer_zerop (vr->min)
- && integer_onep (vr->max));
+ return (vr->kind () == VR_RANGE
+ && integer_zerop (vr->min ())
+ && integer_onep (vr->max ()));
}
/* Extract value range information for VAR when (OP COND_CODE LIMIT) is
@@ -438,12 +411,13 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
/* LIMIT's range is only interesting if it has any useful information. */
if (! limit_vr
- || limit_vr->type == VR_UNDEFINED
- || limit_vr->type == VR_VARYING
- || (symbolic_range_p (limit_vr)
- && ! (limit_vr->type == VR_RANGE
- && (limit_vr->min == limit_vr->max
- || operand_equal_p (limit_vr->min, limit_vr->max, 0)))))
+ || limit_vr->undefined_p ()
+ || limit_vr->varying_p ()
+ || (limit_vr->symbolic_p ()
+ && ! (limit_vr->kind () == VR_RANGE
+ && (limit_vr->min () == limit_vr->max ()
+ || operand_equal_p (limit_vr->min (),
+ limit_vr->max (), 0)))))
limit_vr = NULL;
/* Initially, the new range has the same set of equivalences of
@@ -451,8 +425,8 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
value. Since assertions may be chained via mutually exclusive
predicates, we will need to trim the set of equivalences before
we are done. */
- gcc_assert (vr_p->equiv == NULL);
- add_equivalence (&vr_p->equiv, var);
+ gcc_assert (vr_p->equiv () == NULL);
+ vr_p->equiv_add (var, get_value_range (var), &vrp_equiv_obstack);
/* Extract a new range based on the asserted comparison for VAR and
LIMIT's value range. Notice that if LIMIT has an anti-range, we
@@ -488,26 +462,24 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
max = force_fit_type (TREE_TYPE (var), wi::to_widest (max), 0, false);
/* We can transform a max, min range to an anti-range or
- vice-versa. Use set_and_canonicalize_value_range which does
- this for us. */
+ vice-versa. Use set_and_canonicalize which does this for
+ us. */
if (cond_code == LE_EXPR)
- set_and_canonicalize_value_range (vr_p, VR_RANGE,
- min, max, vr_p->equiv);
+ vr_p->set_and_canonicalize (VR_RANGE, min, max, vr_p->equiv ());
else if (cond_code == GT_EXPR)
- set_and_canonicalize_value_range (vr_p, VR_ANTI_RANGE,
- min, max, vr_p->equiv);
+ vr_p->set_and_canonicalize (VR_ANTI_RANGE, min, max, vr_p->equiv ());
else
gcc_unreachable ();
}
else if (cond_code == EQ_EXPR)
{
- enum value_range_type range_type;
+ enum value_range_kind range_type;
if (limit_vr)
{
- range_type = limit_vr->type;
- min = limit_vr->min;
- max = limit_vr->max;
+ range_type = limit_vr->kind ();
+ min = limit_vr->min ();
+ max = limit_vr->max ();
}
else
{
@@ -516,13 +488,13 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
max = limit;
}
- set_value_range (vr_p, range_type, min, max, vr_p->equiv);
+ vr_p->update (range_type, min, max);
/* When asserting the equality VAR == LIMIT and LIMIT is another
SSA name, the new range will also inherit the equivalence set
from LIMIT. */
if (TREE_CODE (limit) == SSA_NAME)
- add_equivalence (&vr_p->equiv, limit);
+ vr_p->equiv_add (limit, get_value_range (limit), &vrp_equiv_obstack);
}
else if (cond_code == NE_EXPR)
{
@@ -547,11 +519,11 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
(i.e., LIMIT_VR->MIN == LIMIT_VR->MAX). In that case,
build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX]. */
if (limit_vr
- && limit_vr->type == VR_RANGE
- && compare_values (limit_vr->min, limit_vr->max) == 0)
+ && limit_vr->kind () == VR_RANGE
+ && compare_values (limit_vr->min (), limit_vr->max ()) == 0)
{
- min = limit_vr->min;
- max = limit_vr->max;
+ min = limit_vr->min ();
+ max = limit_vr->max ();
}
else
{
@@ -567,21 +539,20 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
&& vrp_val_is_max (max))
min = max = limit;
- set_and_canonicalize_value_range (vr_p, VR_ANTI_RANGE,
- min, max, vr_p->equiv);
+ vr_p->set_and_canonicalize (VR_ANTI_RANGE, min, max, vr_p->equiv ());
}
else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
{
min = TYPE_MIN_VALUE (type);
- if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
+ if (limit_vr == NULL || limit_vr->kind () == VR_ANTI_RANGE)
max = limit;
else
{
/* If LIMIT_VR is of the form [N1, N2], we need to build the
range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for
LT_EXPR. */
- max = limit_vr->max;
+ max = limit_vr->max ();
}
/* If the maximum value forces us to be out of bounds, simply punt.
@@ -607,21 +578,21 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
TREE_NO_WARNING (max) = 1;
}
- set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
+ vr_p->update (VR_RANGE, min, max);
}
}
else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
{
max = TYPE_MAX_VALUE (type);
- if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
+ if (limit_vr == NULL || limit_vr->kind () == VR_ANTI_RANGE)
min = limit;
else
{
/* If LIMIT_VR is of the form [N1, N2], we need to build the
range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for
GT_EXPR. */
- min = limit_vr->min;
+ min = limit_vr->min ();
}
/* If the minimum value forces us to be out of bounds, simply punt.
@@ -647,14 +618,14 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
TREE_NO_WARNING (min) = 1;
}
- set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
+ vr_p->update (VR_RANGE, min, max);
}
}
else
gcc_unreachable ();
/* Finally intersect the new range with what we already know about var. */
- vrp_intersect_ranges (vr_p, get_value_range (var));
+ vr_p->intersect (get_value_range (var));
}
/* Extract value range information from an ASSERT_EXPR EXPR and store
@@ -711,12 +682,12 @@ vr_values::extract_range_from_ssa_name (value_range *vr, tree var)
{
value_range *var_vr = get_value_range (var);
- if (var_vr->type != VR_VARYING)
- copy_value_range (vr, var_vr);
+ if (!var_vr->varying_p ())
+ vr->deep_copy (var_vr);
else
set_value_range (vr, VR_RANGE, var, var, NULL);
- add_equivalence (&vr->equiv, var);
+ vr->equiv_add (var, get_value_range (var), &vrp_equiv_obstack);
}
/* Extract range information from a binary expression OP0 CODE OP1 based on
@@ -728,11 +699,9 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
enum tree_code code,
tree expr_type, tree op0, tree op1)
{
- value_range vr0 = VR_INITIALIZER;
- value_range vr1 = VR_INITIALIZER;
-
/* Get value ranges for each operand. For constant operands, create
a new value range with the operand to simplify processing. */
+ value_range vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0))
@@ -752,18 +721,14 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
if (INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
{
- if (vr0.type == VR_VARYING && vr1.type != VR_VARYING)
- {
- vr0.type = VR_RANGE;
- vr0.min = vrp_val_min (expr_type);
- vr0.max = vrp_val_max (expr_type);
- }
- else if (vr1.type == VR_VARYING && vr0.type != VR_VARYING)
- {
- vr1.type = VR_RANGE;
- vr1.min = vrp_val_min (expr_type);
- vr1.max = vrp_val_max (expr_type);
- }
+ if (vr0.varying_p () && !vr1.varying_p ())
+ vr0 = value_range (VR_RANGE,
+ vrp_val_min (expr_type),
+ vrp_val_max (expr_type));
+ else if (vr1.varying_p () && !vr0.varying_p ())
+ vr1 = value_range (VR_RANGE,
+ vrp_val_min (expr_type),
+ vrp_val_max (expr_type));
}
extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1);
@@ -773,7 +738,7 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
n = def - arg
Here the range for n can be set to [0, PTRDIFF_MAX - 1]. */
- if (vr->type == VR_VARYING
+ if (vr->varying_p ()
&& code == POINTER_DIFF_EXPR
&& TREE_CODE (op0) == SSA_NAME
&& TREE_CODE (op1) == SSA_NAME)
@@ -806,21 +771,21 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
symbolic comparison. When a bound of the range of the first operand
is invariant, we set the corresponding bound of the new range to INF
in order to avoid recursing on the range of the second operand. */
- if (vr->type == VR_VARYING
+ if (vr->varying_p ()
&& (code == PLUS_EXPR || code == MINUS_EXPR)
&& TREE_CODE (op1) == SSA_NAME
- && vr0.type == VR_RANGE
+ && vr0.kind () == VR_RANGE
&& symbolic_range_based_on_p (&vr0, op1))
{
const bool minus_p = (code == MINUS_EXPR);
- value_range n_vr1 = VR_INITIALIZER;
+ value_range n_vr1;
/* 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);
/* 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);
/* Try with VR0 and [OP1, OP1]. */
@@ -830,21 +795,21 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &n_vr1);
}
- if (vr->type == VR_VARYING
+ if (vr->varying_p ()
&& (code == PLUS_EXPR || code == MINUS_EXPR)
&& TREE_CODE (op0) == SSA_NAME
- && vr1.type == VR_RANGE
+ && vr1.kind () == VR_RANGE
&& symbolic_range_based_on_p (&vr1, op0))
{
const bool minus_p = (code == MINUS_EXPR);
- value_range n_vr0 = VR_INITIALIZER;
+ value_range n_vr0;
/* 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);
/* 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);
/* Try with [OP0, OP0] and VR1. */
@@ -858,15 +823,15 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
op1's range is ~[op0,op0] or vice-versa, then we
can derive a non-null range. This happens often for
pointer subtraction. */
- if (vr->type == VR_VARYING
+ if (vr->varying_p ()
&& (code == MINUS_EXPR || code == POINTER_DIFF_EXPR)
&& TREE_CODE (op0) == SSA_NAME
- && ((vr0.type == VR_ANTI_RANGE
- && vr0.min == op1
- && vr0.min == vr0.max)
- || (vr1.type == VR_ANTI_RANGE
- && vr1.min == op0
- && vr1.min == vr1.max)))
+ && ((vr0.kind () == VR_ANTI_RANGE
+ && vr0.min () == op1
+ && vr0.min () == vr0.max ())
+ || (vr1.kind () == VR_ANTI_RANGE
+ && vr1.min () == op0
+ && vr1.min () == vr1.max ())))
set_value_range_to_nonnull (vr, expr_type);
}
@@ -878,7 +843,7 @@ void
vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
tree type, tree op0)
{
- value_range vr0 = VR_INITIALIZER;
+ value_range vr0;
/* Get value ranges for the operand. For constant operands, create
a new value range with the operand to simplify processing. */
@@ -899,13 +864,10 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
void
vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
{
- tree op0, op1;
- value_range vr0 = VR_INITIALIZER;
- value_range vr1 = VR_INITIALIZER;
-
/* Get value ranges for each operand. For constant operands, create
a new value range with the operand to simplify processing. */
- op0 = gimple_assign_rhs2 (stmt);
+ tree op0 = gimple_assign_rhs2 (stmt);
+ value_range vr0;
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
else if (is_gimple_min_invariant (op0))
@@ -913,7 +875,8 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
else
set_value_range_to_varying (&vr0);
- op1 = gimple_assign_rhs3 (stmt);
+ tree op1 = gimple_assign_rhs3 (stmt);
+ value_range vr1;
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1))
@@ -922,8 +885,8 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
set_value_range_to_varying (&vr1);
/* The resulting value range is the union of the operand ranges */
- copy_value_range (vr, &vr0);
- vrp_meet (vr, &vr1);
+ vr->deep_copy (&vr0);
+ vr->union_ (&vr1);
}
@@ -946,9 +909,9 @@ vr_values::extract_range_from_comparison (value_range *vr, enum tree_code code,
type. */
val = fold_convert (type, val);
if (is_gimple_min_invariant (val))
- set_value_range_to_value (vr, val, vr->equiv);
+ set_value_range_to_value (vr, val, vr->equiv ());
else
- set_value_range (vr, VR_RANGE, val, val, vr->equiv);
+ vr->update (VR_RANGE, val, val);
}
else
/* The result of a comparison is always true or false. */
@@ -965,8 +928,7 @@ bool
vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
tree op0, tree op1, bool *ovf)
{
- value_range vr0 = VR_INITIALIZER;
- value_range vr1 = VR_INITIALIZER;
+ value_range vr0, vr1;
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *get_value_range (op0);
else if (TREE_CODE (op0) == INTEGER_CST)
@@ -981,29 +943,31 @@ vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
else
set_value_range_to_varying (&vr1);
+ tree vr0min = vr0.min (), vr0max = vr0.max ();
+ tree vr1min = vr1.min (), vr1max = vr1.max ();
if (!range_int_cst_p (&vr0)
- || TREE_OVERFLOW (vr0.min)
- || TREE_OVERFLOW (vr0.max))
+ || TREE_OVERFLOW (vr0min)
+ || TREE_OVERFLOW (vr0max))
{
- vr0.min = vrp_val_min (TREE_TYPE (op0));
- vr0.max = vrp_val_max (TREE_TYPE (op0));
+ vr0min = vrp_val_min (TREE_TYPE (op0));
+ vr0max = vrp_val_max (TREE_TYPE (op0));
}
if (!range_int_cst_p (&vr1)
- || TREE_OVERFLOW (vr1.min)
- || TREE_OVERFLOW (vr1.max))
+ || TREE_OVERFLOW (vr1min)
+ || TREE_OVERFLOW (vr1max))
{
- vr1.min = vrp_val_min (TREE_TYPE (op1));
- vr1.max = vrp_val_max (TREE_TYPE (op1));
+ vr1min = vrp_val_min (TREE_TYPE (op1));
+ vr1max = vrp_val_max (TREE_TYPE (op1));
}
- *ovf = arith_overflowed_p (subcode, type, vr0.min,
- subcode == MINUS_EXPR ? vr1.max : vr1.min);
- if (arith_overflowed_p (subcode, type, vr0.max,
- subcode == MINUS_EXPR ? vr1.min : vr1.max) != *ovf)
+ *ovf = arith_overflowed_p (subcode, type, vr0min,
+ subcode == MINUS_EXPR ? vr1max : vr1min);
+ if (arith_overflowed_p (subcode, type, vr0max,
+ subcode == MINUS_EXPR ? vr1min : vr1max) != *ovf)
return false;
if (subcode == MULT_EXPR)
{
- if (arith_overflowed_p (subcode, type, vr0.min, vr1.max) != *ovf
- || arith_overflowed_p (subcode, type, vr0.max, vr1.min) != *ovf)
+ if (arith_overflowed_p (subcode, type, vr0min, vr1max) != *ovf
+ || arith_overflowed_p (subcode, type, vr0max, vr1min) != *ovf)
return false;
}
if (*ovf)
@@ -1016,10 +980,10 @@ vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
widest_int wmin, wmax;
widest_int w[4];
int i;
- w[0] = wi::to_widest (vr0.min);
- w[1] = wi::to_widest (vr0.max);
- w[2] = wi::to_widest (vr1.min);
- w[3] = wi::to_widest (vr1.max);
+ w[0] = wi::to_widest (vr0min);
+ w[1] = wi::to_widest (vr0max);
+ w[2] = wi::to_widest (vr1min);
+ w[3] = wi::to_widest (vr1max);
for (i = 0; i < 4; i++)
{
widest_int wt;
@@ -1113,11 +1077,11 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
mini = 1;
/* If some high bits are known to be zero,
we can decrease the maximum. */
- if (vr0->type == VR_RANGE
- && TREE_CODE (vr0->max) == INTEGER_CST
- && !operand_less_p (vr0->min,
- build_zero_cst (TREE_TYPE (vr0->min))))
- maxi = tree_floor_log2 (vr0->max) + 1;
+ if (vr0->kind () == VR_RANGE
+ && TREE_CODE (vr0->max ()) == INTEGER_CST
+ && !operand_less_p (vr0->min (),
+ build_zero_cst (TREE_TYPE (vr0->min ()))))
+ maxi = tree_floor_log2 (vr0->max ()) + 1;
}
goto bitop_builtin;
/* __builtin_parity* returns [0, 1]. */
@@ -1148,15 +1112,15 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
value_range *vr0 = get_value_range (arg);
/* From clz of VR_RANGE minimum we can compute
result maximum. */
- if (vr0->type == VR_RANGE
- && TREE_CODE (vr0->min) == INTEGER_CST)
+ if (vr0->kind () == VR_RANGE
+ && TREE_CODE (vr0->min ()) == INTEGER_CST)
{
- maxi = prec - 1 - tree_floor_log2 (vr0->min);
+ maxi = prec - 1 - tree_floor_log2 (vr0->min ());
if (maxi != prec)
mini = 0;
}
- else if (vr0->type == VR_ANTI_RANGE
- && integer_zerop (vr0->min))
+ else if (vr0->kind () == VR_ANTI_RANGE
+ && integer_zerop (vr0->min ()))
{
maxi = prec - 1;
mini = 0;
@@ -1165,10 +1129,10 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
break;
/* From clz of VR_RANGE maximum we can compute
result minimum. */
- if (vr0->type == VR_RANGE
- && TREE_CODE (vr0->max) == INTEGER_CST)
+ if (vr0->kind () == VR_RANGE
+ && TREE_CODE (vr0->max ()) == INTEGER_CST)
{
- mini = prec - 1 - tree_floor_log2 (vr0->max);
+ mini = prec - 1 - tree_floor_log2 (vr0->max ());
if (mini == prec)
break;
}
@@ -1204,20 +1168,20 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
{
value_range *vr0 = get_value_range (arg);
/* If arg is non-zero, then use [0, prec - 1]. */
- if ((vr0->type == VR_RANGE
- && integer_nonzerop (vr0->min))
- || (vr0->type == VR_ANTI_RANGE
- && integer_zerop (vr0->min)))
+ if ((vr0->kind () == VR_RANGE
+ && integer_nonzerop (vr0->min ()))
+ || (vr0->kind () == VR_ANTI_RANGE
+ && integer_zerop (vr0->min ())))
{
mini = 0;
maxi = prec - 1;
}
/* If some high bits are known to be zero,
we can decrease the result maximum. */
- if (vr0->type == VR_RANGE
- && TREE_CODE (vr0->max) == INTEGER_CST)
+ if (vr0->kind () == VR_RANGE
+ && TREE_CODE (vr0->max ()) == INTEGER_CST)
{
- maxi = tree_floor_log2 (vr0->max);
+ maxi = tree_floor_log2 (vr0->max ());
/* For vr0 [0, 0] give up. */
if (maxi == -1)
break;
@@ -1302,9 +1266,9 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
this should have been already folded and if not, it
wasn't folded because of overflow. Avoid removing the
UBSAN_CHECK_* calls in that case. */
- if (vr->type == VR_RANGE
- && (vr->min == vr->max
- || operand_equal_p (vr->min, vr->max, 0)))
+ if (vr->kind () == VR_RANGE
+ && (vr->min () == vr->max ()
+ || operand_equal_p (vr->min (), vr->max (), 0)))
set_value_range_to_varying (vr);
return;
}
@@ -1381,8 +1345,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
}
else
{
- value_range vr0 = VR_INITIALIZER;
- value_range vr1 = VR_INITIALIZER;
+ value_range vr0, vr1;
bool saved_flag_wrapv = flag_wrapv;
/* Pretend the arithmetics is wrapping. If there is
any overflow, IMAGPART_EXPR will be set. */
@@ -1444,7 +1407,7 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt)
else
set_value_range_to_varying (vr);
- if (vr->type == VR_VARYING)
+ if (vr->varying_p ())
extract_range_basic (vr, stmt);
}
@@ -1467,18 +1430,18 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
bool *strict_overflow_p)
{
/* VARYING or UNDEFINED ranges cannot be compared. */
- if (vr0->type == VR_VARYING
- || vr0->type == VR_UNDEFINED
- || vr1->type == VR_VARYING
- || vr1->type == VR_UNDEFINED)
+ if (vr0->varying_p ()
+ || vr0->undefined_p ()
+ || vr1->varying_p ()
+ || vr1->undefined_p ())
return NULL_TREE;
/* Anti-ranges need to be handled separately. */
- if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
+ if (vr0->kind () == VR_ANTI_RANGE || vr1->kind () == VR_ANTI_RANGE)
{
/* If both are anti-ranges, then we cannot compute any
comparison. */
- if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
+ if (vr0->kind () == VR_ANTI_RANGE && vr1->kind () == VR_ANTI_RANGE)
return NULL_TREE;
/* These comparisons are never statically computable. */
@@ -1490,7 +1453,7 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
/* Equality can be computed only between a range and an
anti-range. ~[VAL1, VAL2] == [VAL1, VAL2] is always false. */
- if (vr0->type == VR_RANGE)
+ if (vr0->kind () == VR_RANGE)
{
/* To simplify processing, make VR0 the anti-range. */
value_range *tmp = vr0;
@@ -1500,8 +1463,8 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);
- if (compare_values_warnv (vr0->min, vr1->min, strict_overflow_p) == 0
- && compare_values_warnv (vr0->max, vr1->max, strict_overflow_p) == 0)
+ if (compare_values_warnv (vr0->min (), vr1->min (), strict_overflow_p) == 0
+ && compare_values_warnv (vr0->max (), vr1->max (), strict_overflow_p) == 0)
return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
return NULL_TREE;
@@ -1519,12 +1482,12 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
{
/* Equality may only be computed if both ranges represent
exactly one value. */
- if (compare_values_warnv (vr0->min, vr0->max, strict_overflow_p) == 0
- && compare_values_warnv (vr1->min, vr1->max, strict_overflow_p) == 0)
+ if (compare_values_warnv (vr0->min (), vr0->max (), strict_overflow_p) == 0
+ && compare_values_warnv (vr1->min (), vr1->max (), strict_overflow_p) == 0)
{
- int cmp_min = compare_values_warnv (vr0->min, vr1->min,
+ int cmp_min = compare_values_warnv (vr0->min (), vr1->min (),
strict_overflow_p);
- int cmp_max = compare_values_warnv (vr0->max, vr1->max,
+ int cmp_max = compare_values_warnv (vr0->max (), vr1->max (),
strict_overflow_p);
if (cmp_min == 0 && cmp_max == 0)
return boolean_true_node;
@@ -1532,9 +1495,9 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
return boolean_false_node;
}
/* If [V0_MIN, V1_MAX] < [V1_MIN, V1_MAX] then V0 != V1. */
- else if (compare_values_warnv (vr0->min, vr1->max,
+ else if (compare_values_warnv (vr0->min (), vr1->max (),
strict_overflow_p) == 1
- || compare_values_warnv (vr1->min, vr0->max,
+ || compare_values_warnv (vr1->min (), vr0->max (),
strict_overflow_p) == 1)
return boolean_false_node;
@@ -1549,20 +1512,20 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
make sure that both comparisons yield similar results to
avoid comparing values that cannot be compared at
compile-time. */
- cmp1 = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
- cmp2 = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
+ cmp1 = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
+ cmp2 = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p);
if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1))
return boolean_true_node;
/* If VR0 and VR1 represent a single value and are identical,
return false. */
- else if (compare_values_warnv (vr0->min, vr0->max,
+ else if (compare_values_warnv (vr0->min (), vr0->max (),
strict_overflow_p) == 0
- && compare_values_warnv (vr1->min, vr1->max,
+ && compare_values_warnv (vr1->min (), vr1->max (),
strict_overflow_p) == 0
- && compare_values_warnv (vr0->min, vr1->min,
+ && compare_values_warnv (vr0->min (), vr1->min (),
strict_overflow_p) == 0
- && compare_values_warnv (vr0->max, vr1->max,
+ && compare_values_warnv (vr0->max (), vr1->max (),
strict_overflow_p) == 0)
return boolean_false_node;
@@ -1575,13 +1538,13 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
int tst;
/* If VR0 is to the left of VR1, return true. */
- tst = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
+ tst = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
if ((comp == LT_EXPR && tst == -1)
|| (comp == LE_EXPR && (tst == -1 || tst == 0)))
return boolean_true_node;
/* If VR0 is to the right of VR1, return false. */
- tst = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
+ tst = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p);
if ((comp == LT_EXPR && (tst == 0 || tst == 1))
|| (comp == LE_EXPR && tst == 1))
return boolean_false_node;
@@ -1605,11 +1568,11 @@ static tree
compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
bool *strict_overflow_p)
{
- if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
+ if (vr->varying_p () || vr->undefined_p ())
return NULL_TREE;
/* Anti-ranges need to be handled separately. */
- if (vr->type == VR_ANTI_RANGE)
+ if (vr->kind () == VR_ANTI_RANGE)
{
/* For anti-ranges, the only predicates that we can compute at
compile time are equality and inequality. */
@@ -1620,7 +1583,7 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
return NULL_TREE;
/* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2. */
- if (value_inside_range (val, vr->min, vr->max) == 1)
+ if (value_inside_range (val, vr->min (), vr->max ()) == 1)
return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
return NULL_TREE;
@@ -1630,16 +1593,16 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
{
/* EQ_EXPR may only be computed if VR represents exactly
one value. */
- if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0)
+ if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0)
{
- int cmp = compare_values_warnv (vr->min, val, strict_overflow_p);
+ int cmp = compare_values_warnv (vr->min (), val, strict_overflow_p);
if (cmp == 0)
return boolean_true_node;
else if (cmp == -1 || cmp == 1 || cmp == 2)
return boolean_false_node;
}
- else if (compare_values_warnv (val, vr->min, strict_overflow_p) == -1
- || compare_values_warnv (vr->max, val, strict_overflow_p) == -1)
+ else if (compare_values_warnv (val, vr->min (), strict_overflow_p) == -1
+ || compare_values_warnv (vr->max (), val, strict_overflow_p) == -1)
return boolean_false_node;
return NULL_TREE;
@@ -1647,14 +1610,14 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
else if (comp == NE_EXPR)
{
/* If VAL is not inside VR, then they are always different. */
- if (compare_values_warnv (vr->max, val, strict_overflow_p) == -1
- || compare_values_warnv (vr->min, val, strict_overflow_p) == 1)
+ if (compare_values_warnv (vr->max (), val, strict_overflow_p) == -1
+ || compare_values_warnv (vr->min (), val, strict_overflow_p) == 1)
return boolean_true_node;
/* If VR represents exactly one value equal to VAL, then return
false. */
- if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0
- && compare_values_warnv (vr->min, val, strict_overflow_p) == 0)
+ if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0
+ && compare_values_warnv (vr->min (), val, strict_overflow_p) == 0)
return boolean_false_node;
/* Otherwise, they may or may not be different. */
@@ -1665,13 +1628,13 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
int tst;
/* If VR is to the left of VAL, return true. */
- tst = compare_values_warnv (vr->max, val, strict_overflow_p);
+ tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
if ((comp == LT_EXPR && tst == -1)
|| (comp == LE_EXPR && (tst == -1 || tst == 0)))
return boolean_true_node;
/* If VR is to the right of VAL, return false. */
- tst = compare_values_warnv (vr->min, val, strict_overflow_p);
+ tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
if ((comp == LT_EXPR && (tst == 0 || tst == 1))
|| (comp == LE_EXPR && tst == 1))
return boolean_false_node;
@@ -1684,13 +1647,13 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
int tst;
/* If VR is to the right of VAL, return true. */
- tst = compare_values_warnv (vr->min, val, strict_overflow_p);
+ tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
if ((comp == GT_EXPR && tst == 1)
|| (comp == GE_EXPR && (tst == 0 || tst == 1)))
return boolean_true_node;
/* If VR is to the left of VAL, return false. */
- tst = compare_values_warnv (vr->max, val, strict_overflow_p);
+ tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
if ((comp == GT_EXPR && (tst == -1 || tst == 0))
|| (comp == GE_EXPR && tst == -1))
return boolean_false_node;
@@ -1714,7 +1677,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
/* TODO. Don't adjust anti-ranges. An anti-range may provide
better opportunities than a regular range, but I'm not sure. */
- if (vr->type == VR_ANTI_RANGE)
+ if (vr->kind () == VR_ANTI_RANGE)
return;
chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
@@ -1722,7 +1685,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
/* Like in PR19590, scev can return a constant function. */
if (is_gimple_min_invariant (chrec))
{
- set_value_range_to_value (vr, chrec, vr->equiv);
+ set_value_range_to_value (vr, chrec, vr->equiv ());
return;
}
@@ -1771,7 +1734,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
if (TREE_CODE (step) == INTEGER_CST
&& is_gimple_val (init)
&& (TREE_CODE (init) != SSA_NAME
- || get_value_range (init)->type == VR_RANGE))
+ || get_value_range (init)->kind () == VR_RANGE))
{
widest_int nit;
@@ -1779,7 +1742,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
the number of latch executions is the correct thing to use. */
if (max_loop_iterations (loop, &nit))
{
- value_range maxvr = VR_INITIALIZER;
+ value_range maxvr;
signop sgn = TYPE_SIGN (TREE_TYPE (step));
wi::overflow_type overflow;
@@ -1799,9 +1762,9 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
TREE_TYPE (init), init, tem);
/* Likewise if the addition did. */
- if (maxvr.type == VR_RANGE)
+ if (maxvr.kind () == VR_RANGE)
{
- value_range initvr = VR_INITIALIZER;
+ value_range initvr;
if (TREE_CODE (init) == SSA_NAME)
initvr = *(get_value_range (init));
@@ -1815,19 +1778,19 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
because the loop may exit immediately. Overflow could
happen in the plus expression in this case. */
if ((dir == EV_DIR_DECREASES
- && compare_values (maxvr.min, initvr.min) != -1)
+ && compare_values (maxvr.min (), initvr.min ()) != -1)
|| (dir == EV_DIR_GROWS
- && compare_values (maxvr.max, initvr.max) != 1))
+ && compare_values (maxvr.max (), initvr.max ()) != 1))
return;
- tmin = maxvr.min;
- tmax = maxvr.max;
+ tmin = maxvr.min ();
+ tmax = maxvr.max ();
}
}
}
}
- if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
+ if (vr->varying_p () || vr->undefined_p ())
{
min = tmin;
max = tmax;
@@ -1840,15 +1803,15 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
else
min = init;
}
- else if (vr->type == VR_RANGE)
+ else if (vr->kind () == VR_RANGE)
{
- min = vr->min;
- max = vr->max;
+ min = vr->min ();
+ max = vr->max ();
if (dir == EV_DIR_DECREASES)
{
- /* INIT is the maximum value. If INIT is lower than VR->MAX
- but no smaller than VR->MIN, set VR->MAX to INIT. */
+ /* INIT is the maximum value. If INIT is lower than VR->MAX ()
+ but no smaller than VR->MIN (), set VR->MAX () to INIT. */
if (compare_values (init, max) == -1)
max = init;
@@ -1860,7 +1823,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
}
else
{
- /* If INIT is bigger than VR->MIN, set VR->MIN to INIT. */
+ /* If INIT is bigger than VR->MIN (), set VR->MIN () to INIT. */
if (compare_values (init, min) == 1)
min = init;
@@ -1886,7 +1849,7 @@ vr_values::adjust_range_with_scev (value_range *vr, struct loop *loop,
if (TREE_OVERFLOW_P (max))
max = drop_tree_overflow (max);
- set_value_range (vr, VR_RANGE, min, max, vr->equiv);
+ vr->update (VR_RANGE, min, max);
}
/* Dump value ranges of all SSA_NAMEs to FILE. */
@@ -1957,11 +1920,11 @@ vrp_valueize (tree name)
if (TREE_CODE (name) == SSA_NAME)
{
value_range *vr = x_vr_values->get_value_range (name);
- if (vr->type == VR_RANGE
- && (TREE_CODE (vr->min) == SSA_NAME
- || is_gimple_min_invariant (vr->min))
- && vrp_operand_equal_p (vr->min, vr->max))
- return vr->min;
+ if (vr->kind () == VR_RANGE
+ && (TREE_CODE (vr->min ()) == SSA_NAME
+ || is_gimple_min_invariant (vr->min ()))
+ && vrp_operand_equal_p (vr->min (), vr->max ()))
+ return vr->min ();
}
return name;
}
@@ -1982,8 +1945,9 @@ vrp_valueize_1 (tree name)
&& prop_simulate_again_p (def_stmt))
return NULL_TREE;
value_range *vr = x_vr_values->get_value_range (name);
- if (range_int_cst_singleton_p (vr))
- return vr->min;
+ tree singleton;
+ if (vr->singleton_p (&singleton))
+ return singleton;
}
return name;
}
@@ -2066,12 +2030,8 @@ vr_values::get_vr_for_comparison (int i)
/* 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
have N_i in their ranges. */
- if (vr.type == VR_VARYING || vr.type == VR_UNDEFINED)
- {
- vr.type = VR_RANGE;
- vr.min = ssa_name (i);
- vr.max = ssa_name (i);
- }
+ if (vr.varying_p () || vr.undefined_p ())
+ vr = value_range (VR_RANGE, ssa_name (i), ssa_name (i), NULL);
return vr;
}
@@ -2094,7 +2054,7 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
value_range equiv_vr;
/* Get the set of equivalences for VAR. */
- e = get_value_range (var)->equiv;
+ e = get_value_range (var)->equiv ();
/* Start at -1. Set it to 0 if we do a comparison without relying
on overflow, or 1 if all comparisons rely on overflow. */
@@ -2180,8 +2140,8 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
/* Compare the ranges of every name equivalent to N1 against the
ranges of every name equivalent to N2. */
- e1 = get_value_range (n1)->equiv;
- e2 = get_value_range (n2)->equiv;
+ e1 = get_value_range (n1)->equiv ();
+ e2 = get_value_range (n2)->equiv ();
/* Use the fake bitmaps if e1 or e2 are not available. */
if (s_obstack == NULL)
@@ -2440,10 +2400,10 @@ vr_values::vrp_evaluate_conditional (tree_code code, tree op0,
tree type = TREE_TYPE (op0);
value_range *vr0 = get_value_range (op0);
- if (vr0->type == VR_RANGE
+ if (vr0->kind () == VR_RANGE
&& INTEGRAL_TYPE_P (type)
- && vrp_val_is_min (vr0->min)
- && vrp_val_is_max (vr0->max)
+ && vrp_val_is_min (vr0->min ())
+ && vrp_val_is_max (vr0->max ())
&& is_gimple_min_invariant (op1))
{
location_t location;
@@ -2572,9 +2532,9 @@ find_case_label_ranges (gswitch *stmt, value_range *vr, size_t *min_idx1,
unsigned int n = gimple_switch_num_labels (stmt);
bool take_default;
tree case_low, case_high;
- tree min = vr->min, max = vr->max;
+ tree min = vr->min (), max = vr->max ();
- gcc_checking_assert (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE);
+ gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ());
take_default = !find_case_label_range (stmt, min, max, &i, &j);
@@ -2582,7 +2542,7 @@ find_case_label_ranges (gswitch *stmt, value_range *vr, size_t *min_idx1,
*min_idx2 = 1;
*max_idx2 = 0;
- if (vr->type == VR_RANGE)
+ if (vr->kind () == VR_RANGE)
{
*min_idx1 = i;
*max_idx1 = j;
@@ -2663,9 +2623,9 @@ vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
fprintf (dump_file, "\n");
}
- if ((vr->type != VR_RANGE
- && vr->type != VR_ANTI_RANGE)
- || symbolic_range_p (vr))
+ if (vr->undefined_p ()
+ || vr->varying_p ()
+ || vr->symbolic_p ())
return;
/* Find the single edge that is taken from the switch expression. */
@@ -2809,40 +2769,24 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
See PR53465 and PR54767. */
if (e->flags & EDGE_DFS_BACK)
{
- if (vr_arg.type == VR_RANGE
- || vr_arg.type == VR_ANTI_RANGE)
+ if (!vr_arg.varying_p () && !vr_arg.undefined_p ())
{
- vr_arg.equiv = NULL;
- if (symbolic_range_p (&vr_arg))
- {
- vr_arg.type = VR_VARYING;
- vr_arg.min = NULL_TREE;
- vr_arg.max = NULL_TREE;
- }
- }
- }
- else
- {
- /* If the non-backedge arguments range is VR_VARYING then
- we can still try recording a simple equivalence. */
- if (vr_arg.type == VR_VARYING)
- {
- vr_arg.type = VR_RANGE;
- vr_arg.min = arg;
- vr_arg.max = arg;
- vr_arg.equiv = NULL;
+ vr_arg.equiv_clear ();
+ if (vr_arg.symbolic_p ())
+ vr_arg.set_varying ();
}
}
+ /* If the non-backedge arguments range is VR_VARYING then
+ we can still try recording a simple equivalence. */
+ else if (vr_arg.varying_p ())
+ vr_arg = value_range (VR_RANGE, arg, arg, NULL);
}
else
{
if (TREE_OVERFLOW_P (arg))
arg = drop_tree_overflow (arg);
- vr_arg.type = VR_RANGE;
- vr_arg.min = arg;
- vr_arg.max = arg;
- vr_arg.equiv = NULL;
+ vr_arg = value_range (VR_RANGE, arg, arg);
}
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2855,19 +2799,19 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
}
if (first)
- copy_value_range (vr_result, &vr_arg);
+ vr_result->deep_copy (&vr_arg);
else
- vrp_meet (vr_result, &vr_arg);
+ vr_result->union_ (&vr_arg);
first = false;
- if (vr_result->type == VR_VARYING)
+ if (vr_result->varying_p ())
break;
}
}
- if (vr_result->type == VR_VARYING)
+ if (vr_result->varying_p ())
goto varying;
- else if (vr_result->type == VR_UNDEFINED)
+ else if (vr_result->undefined_p ())
goto update_range;
old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
@@ -2883,21 +2827,21 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
if (edges > 0
&& gimple_phi_num_args (phi) > 1
&& edges == old_edges
- && lhs_vr->type != VR_UNDEFINED
+ && !lhs_vr->undefined_p ()
&& may_simulate_backedge_again)
{
/* Compare old and new ranges, fall back to varying if the
values are not comparable. */
- int cmp_min = compare_values (lhs_vr->min, vr_result->min);
+ int cmp_min = compare_values (lhs_vr->min (), vr_result->min ());
if (cmp_min == -2)
goto varying;
- int cmp_max = compare_values (lhs_vr->max, vr_result->max);
+ int cmp_max = compare_values (lhs_vr->max (), vr_result->max ());
if (cmp_max == -2)
goto varying;
/* For non VR_RANGE or for pointers fall back to varying if
the range changed. */
- if ((lhs_vr->type != VR_RANGE || vr_result->type != VR_RANGE
+ if ((lhs_vr->kind () != VR_RANGE || vr_result->kind () != VR_RANGE
|| POINTER_TYPE_P (TREE_TYPE (lhs)))
&& (cmp_min != 0 || cmp_max != 0))
goto varying;
@@ -2910,24 +2854,27 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
times to reach -INF. Going to -INF + 1 also lets the following
iteration compute whether there will be any overflow, at the
expense of one additional iteration. */
+ tree new_min = vr_result->min ();
+ tree new_max = vr_result->max ();
if (cmp_min < 0)
- vr_result->min = lhs_vr->min;
+ new_min = lhs_vr->min ();
else if (cmp_min > 0
- && !vrp_val_is_min (vr_result->min))
- vr_result->min
- = int_const_binop (PLUS_EXPR,
- vrp_val_min (TREE_TYPE (vr_result->min)),
- build_int_cst (TREE_TYPE (vr_result->min), 1));
+ && !vrp_val_is_min (vr_result->min ()))
+ new_min = int_const_binop (PLUS_EXPR,
+ vrp_val_min (vr_result->type ()),
+ build_int_cst (vr_result->type (), 1));
/* Similarly for the maximum value. */
if (cmp_max > 0)
- vr_result->max = lhs_vr->max;
+ new_max = lhs_vr->max ();
else if (cmp_max < 0
- && !vrp_val_is_max (vr_result->max))
- vr_result->max
- = int_const_binop (MINUS_EXPR,
- vrp_val_max (TREE_TYPE (vr_result->min)),
- build_int_cst (TREE_TYPE (vr_result->min), 1));
+ && !vrp_val_is_max (vr_result->max ()))
+ new_max = int_const_binop (MINUS_EXPR,
+ vrp_val_max (vr_result->type ()),
+ build_int_cst (vr_result->type (), 1));
+
+ *vr_result = value_range (vr_result->kind (), new_min, new_max,
+ vr_result->equiv ());
/* If we dropped either bound to +-INF then if this is a loop
PHI node SCEV may known more about its value-range. */
@@ -2957,9 +2904,9 @@ infinite_check:
/* If we will end up with a (-INF, +INF) range, set it to
VARYING. Same if the previous max value was invalid for
the type and we end up with vr_result.min > vr_result.max. */
- if ((vr_result->type == VR_RANGE || vr_result->type == VR_ANTI_RANGE)
- && !((vrp_val_is_max (vr_result->max) && vrp_val_is_min (vr_result->min))
- || compare_values (vr_result->min, vr_result->max) > 0))
+ if ((!vr_result->varying_p () && !vr_result->undefined_p ())
+ && !((vrp_val_is_max (vr_result->max ()) && vrp_val_is_min (vr_result->min ()))
+ || compare_values (vr_result->min (), vr_result->max ()) > 0))
;
else
set_value_range_to_varying (vr_result);
@@ -3071,8 +3018,8 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
vr = get_value_range (op0);
if (range_int_cst_p (vr))
{
- op0min = vr->min;
- op0max = vr->max;
+ op0min = vr->min ();
+ op0max = vr->max ();
}
}
@@ -3081,7 +3028,7 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
{
value_range *vr1 = get_value_range (op1);
if (range_int_cst_p (vr1))
- op1min = vr1->min;
+ op1min = vr1->min ();
}
if (rhs_code == TRUNC_MOD_EXPR
&& TREE_CODE (op1min) == INTEGER_CST
@@ -3285,8 +3232,7 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi,
tree op0 = gimple_assign_rhs1 (stmt);
tree op1 = gimple_assign_rhs2 (stmt);
tree op = NULL_TREE;
- value_range vr0 = VR_INITIALIZER;
- value_range vr1 = VR_INITIALIZER;
+ value_range vr0, vr1;
wide_int may_be_nonzero0, may_be_nonzero1;
wide_int must_be_nonzero0, must_be_nonzero1;
wide_int mask;
@@ -3405,10 +3351,10 @@ test_for_singularity (enum tree_code cond_code, tree op0,
value range information we have for op0. */
if (min && max)
{
- if (compare_values (vr->min, min) == 1)
- min = vr->min;
- if (compare_values (vr->max, max) == -1)
- max = vr->max;
+ if (compare_values (vr->min (), min) == 1)
+ min = vr->min ();
+ if (compare_values (vr->max (), max) == -1)
+ max = vr->max ();
/* If the new min/max values have converged to a single value,
then there is only one value which can satisfy the condition,
@@ -3431,14 +3377,14 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn)
signop src_sgn;
/* We can only handle integral and pointer types. */
- src_type = TREE_TYPE (vr->min);
+ src_type = vr->type ();
if (!INTEGRAL_TYPE_P (src_type)
&& !POINTER_TYPE_P (src_type))
return false;
/* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED,
and so is an identity transform. */
- src_precision = TYPE_PRECISION (TREE_TYPE (vr->min));
+ src_precision = TYPE_PRECISION (vr->type ());
src_sgn = TYPE_SIGN (src_type);
if ((src_precision < dest_precision
&& !(dest_sgn == UNSIGNED && src_sgn == SIGNED))
@@ -3446,9 +3392,7 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn)
return true;
/* Now we can only handle ranges with constant bounds. */
- if (vr->type != VR_RANGE
- || TREE_CODE (vr->min) != INTEGER_CST
- || TREE_CODE (vr->max) != INTEGER_CST)
+ if (!range_int_cst_p (vr))
return false;
/* For sign changes, the MSB of the wide_int has to be clear.
@@ -3456,17 +3400,17 @@ range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn)
a signed wide_int, while a negative value cannot be represented
by an unsigned wide_int. */
if (src_sgn != dest_sgn
- && (wi::lts_p (wi::to_wide (vr->min), 0)
- || wi::lts_p (wi::to_wide (vr->max), 0)))
+ && (wi::lts_p (wi::to_wide (vr->min ()), 0)
+ || wi::lts_p (wi::to_wide (vr->max ()), 0)))
return false;
/* Then we can perform the conversion on both ends and compare
the result for equality. */
- tem = wi::ext (wi::to_widest (vr->min), dest_precision, dest_sgn);
- if (tem != wi::to_widest (vr->min))
+ tem = wi::ext (wi::to_widest (vr->min ()), dest_precision, dest_sgn);
+ if (tem != wi::to_widest (vr->min ()))
return false;
- tem = wi::ext (wi::to_widest (vr->max), dest_precision, dest_sgn);
- if (tem != wi::to_widest (vr->max))
+ tem = wi::ext (wi::to_widest (vr->max ()), dest_precision, dest_sgn);
+ if (tem != wi::to_widest (vr->max ()))
return false;
return true;
@@ -3493,7 +3437,7 @@ vr_values::simplify_cond_using_ranges_1 (gcond *stmt)
/* If we have range information for OP0, then we might be
able to simplify this conditional. */
- if (vr->type == VR_RANGE)
+ if (vr->kind () == VR_RANGE)
{
tree new_tree = test_for_singularity (cond_code, op0, op1, vr);
if (new_tree)
@@ -3636,9 +3580,9 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
vr = get_value_range (op);
/* We can only handle integer ranges. */
- if ((vr->type != VR_RANGE
- && vr->type != VR_ANTI_RANGE)
- || symbolic_range_p (vr))
+ if (vr->varying_p ()
+ || vr->undefined_p ()
+ || vr->symbolic_p ())
return false;
/* Find case label for min/max of the value range. */
@@ -3666,7 +3610,7 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
value range. */
size_t min_idx = 1, max_idx = 0;
if (vr != NULL)
- find_case_label_range (stmt, vr->min, vr->max, &min_idx, &max_idx);
+ find_case_label_range (stmt, vr->min (), vr->max (), &min_idx, &max_idx);
if (min_idx <= max_idx)
{
tree min_label = gimple_switch_label (stmt, min_idx);
@@ -3674,10 +3618,10 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
/* Avoid changing the type of the case labels when truncating. */
tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
- tree vr_min = fold_convert (case_label_type, vr->min);
- tree vr_max = fold_convert (case_label_type, vr->max);
+ tree vr_min = fold_convert (case_label_type, vr->min ());
+ tree vr_max = fold_convert (case_label_type, vr->max ());
- if (vr->type == VR_RANGE)
+ if (vr->kind () == VR_RANGE)
{
/* If OP's value range is [2,8] and the low label range is
0 ... 3, truncate the label's range to 2 .. 3. */
@@ -3693,7 +3637,7 @@ vr_values::simplify_switch_using_ranges (gswitch *stmt)
&& tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
CASE_HIGH (max_label) = vr_max;
}
- else if (vr->type == VR_ANTI_RANGE)
+ else if (vr->kind () == VR_ANTI_RANGE)
{
tree one_cst = build_one_cst (case_label_type);
@@ -3930,9 +3874,7 @@ vr_values::simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi,
gassign *conv;
/* We can only handle constant ranges. */
- if (vr->type != VR_RANGE
- || TREE_CODE (vr->min) != INTEGER_CST
- || TREE_CODE (vr->max) != INTEGER_CST)
+ if (!range_int_cst_p (vr))
return false;
/* First check if we can use a signed type in place of an unsigned. */
@@ -4088,26 +4030,26 @@ bool
vr_values::two_valued_val_range_p (tree var, tree *a, tree *b)
{
value_range *vr = get_value_range (var);
- if ((vr->type != VR_RANGE
- && vr->type != VR_ANTI_RANGE)
- || TREE_CODE (vr->min) != INTEGER_CST
- || TREE_CODE (vr->max) != INTEGER_CST)
+ if (vr->varying_p ()
+ || vr->undefined_p ()
+ || TREE_CODE (vr->min ()) != INTEGER_CST
+ || TREE_CODE (vr->max ()) != INTEGER_CST)
return false;
- if (vr->type == VR_RANGE
- && wi::to_wide (vr->max) - wi::to_wide (vr->min) == 1)
+ if (vr->kind () == VR_RANGE
+ && wi::to_wide (vr->max ()) - wi::to_wide (vr->min ()) == 1)
{
- *a = vr->min;
- *b = vr->max;
+ *a = vr->min ();
+ *b = vr->max ();
return true;
}
/* ~[TYPE_MIN + 1, TYPE_MAX - 1] */
- if (vr->type == VR_ANTI_RANGE
- && (wi::to_wide (vr->min)
+ if (vr->kind () == VR_ANTI_RANGE
+ && (wi::to_wide (vr->min ())
- wi::to_wide (vrp_val_min (TREE_TYPE (var)))) == 1
&& (wi::to_wide (vrp_val_max (TREE_TYPE (var)))
- - wi::to_wide (vr->max)) == 1)
+ - wi::to_wide (vr->max ())) == 1)
{
*a = vrp_val_min (TREE_TYPE (var));
*b = vrp_val_max (TREE_TYPE (var));
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 487a800c..6ff461b 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -72,7 +72,6 @@ class vr_values
void cleanup_edges_and_switches (void);
private:
- void add_equivalence (bitmap *, const_tree);
bool vrp_stmt_computes_nonzero (gimple *);
bool op_with_boolean_value_range_p (tree);
bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *);
@@ -142,7 +141,5 @@ class vr_values
vec<switch_update> to_update_switch_stmts;
};
-#define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }
-
extern tree get_output_for_vrp (gimple *);
#endif /* GCC_VR_VALUES_H */