Commit 9384a5af by Richard Biener Committed by Richard Biener

tree-ssanames.h (set_range_info): Use value_range_base.

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

	* tree-ssanames.h (set_range_info): Use value_range_base.
	(get_range_info): Likewise.
	* tree-ssanames.c (set_range_info): Likewise.
	(get_range_info): Likewise.
	* tree-vrp.c (value_range_base::union_helper): Split
	out common parts of value_range[_base]::union_.
	(value_range_base::union_): Update.
	(value_range::union_): Likewise.
	(determine_value_range_1): Use value_range_base.
	(determine_value_range): Likewise.
	* tree-vrp.h (value_range_base::union_helper): Move ...
	(value_range::union_helper): ... from here.

From-SVN: r266061
parent b2a71af6
2018-11-13 Richard Biener <rguenther@suse.de>
* tree-ssanames.h (set_range_info): Use value_range_base.
(get_range_info): Likewise.
* tree-ssanames.c (set_range_info): Likewise.
(get_range_info): Likewise.
* tree-vrp.c (value_range_base::union_helper): Split
out common parts of value_range[_base]::union_.
(value_range_base::union_): Update.
(value_range::union_): Likewise.
(determine_value_range_1): Use value_range_base.
(determine_value_range): Likewise.
* tree-vrp.h (value_range_base::union_helper): Move ...
(value_range::union_helper): ... from here.
2018-11-13 Alan Modra <amodra@gmail.com> 2018-11-13 Alan Modra <amodra@gmail.com>
* config/rs6000/rs6000.c (rs6000_secondary_reload_inner): Negate * config/rs6000/rs6000.c (rs6000_secondary_reload_inner): Negate
...@@ -401,7 +401,7 @@ set_range_info (tree name, enum value_range_kind range_type, ...@@ -401,7 +401,7 @@ set_range_info (tree name, enum value_range_kind range_type,
/* Store range information for NAME from a value_range. */ /* Store range information for NAME from a value_range. */
void void
set_range_info (tree name, const value_range &vr) set_range_info (tree name, const value_range_base &vr)
{ {
wide_int min = wi::to_wide (vr.min ()); wide_int min = wi::to_wide (vr.min ());
wide_int max = wi::to_wide (vr.max ()); wide_int max = wi::to_wide (vr.max ());
...@@ -434,7 +434,7 @@ get_range_info (const_tree name, wide_int *min, wide_int *max) ...@@ -434,7 +434,7 @@ get_range_info (const_tree name, wide_int *min, wide_int *max)
in a value_range VR. Returns the value_range_kind. */ in a value_range VR. Returns the value_range_kind. */
enum value_range_kind enum value_range_kind
get_range_info (const_tree name, value_range &vr) get_range_info (const_tree name, value_range_base &vr)
{ {
tree min, max; tree min, max;
wide_int wmin, wmax; wide_int wmin, wmax;
......
...@@ -69,11 +69,11 @@ struct GTY ((variable_size)) range_info_def { ...@@ -69,11 +69,11 @@ struct GTY ((variable_size)) range_info_def {
/* Sets the value range to SSA. */ /* Sets the value range to SSA. */
extern void set_range_info (tree, enum value_range_kind, const wide_int_ref &, extern void set_range_info (tree, enum value_range_kind, const wide_int_ref &,
const wide_int_ref &); const wide_int_ref &);
extern void set_range_info (tree, const value_range &); extern void set_range_info (tree, const value_range_base &);
/* Gets the value range from SSA. */ /* Gets the value range from SSA. */
extern enum value_range_kind get_range_info (const_tree, wide_int *, extern enum value_range_kind get_range_info (const_tree, wide_int *,
wide_int *); wide_int *);
extern enum value_range_kind get_range_info (const_tree, value_range &); extern enum value_range_kind get_range_info (const_tree, value_range_base &);
extern void set_nonzero_bits (tree, const wide_int_ref &); extern void set_nonzero_bits (tree, const wide_int_ref &);
extern wide_int get_nonzero_bits (const_tree); extern wide_int get_nonzero_bits (const_tree);
extern bool ssa_name_has_boolean_range (tree); extern bool ssa_name_has_boolean_range (tree);
......
...@@ -6084,125 +6084,73 @@ value_range::intersect (const value_range *other) ...@@ -6084,125 +6084,73 @@ value_range::intersect (const value_range *other)
} }
} }
/* Meet operation for value ranges. Given two value ranges VR0 and /* Helper for meet operation for value ranges. Given two value ranges VR0 and
VR1, store in VR0 a range that contains both VR0 and VR1. This VR1, return a range that contains both VR0 and VR1. This may not be the
may not be the smallest possible such range. */ smallest possible such range. */
void value_range_base
value_range_base::union_ (const value_range_base *other) value_range_base::union_helper (const value_range_base *vr0,
const value_range_base *vr1)
{ {
if (other->undefined_p ()) /* VR0 has the resulting range if VR1 is undefined or VR0 is varying. */
{ if (vr1->undefined_p ()
/* this already has the resulting range. */ || vr0->varying_p ())
return; return *vr0;
}
if (this->undefined_p ()) /* VR1 has the resulting range if VR0 is undefined or VR1 is varying. */
{ if (vr0->undefined_p ()
*this = *other; || vr1->varying_p ())
return; return *vr1;
}
if (this->varying_p ()) value_range_kind vr0type = vr0->kind ();
{ tree vr0min = vr0->min ();
/* Nothing to do. VR0 already has the resulting range. */ tree vr0max = vr0->max ();
return; union_ranges (&vr0type, &vr0min, &vr0max,
} vr1->kind (), vr1->min (), vr1->max ());
/* Work on a temporary so we can still use vr0 when union returns varying. */
value_range tem;
tem.set_and_canonicalize (vr0type, vr0min, vr0max);
if (other->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
anti-range. */
if (tem.varying_p ()
&& range_includes_zero_p (vr0) == 0
&& range_includes_zero_p (vr1) == 0)
{ {
this->set_varying (); tem.set_nonnull (vr0->type ());
return; return tem;
} }
value_range saved (*this); return tem;
value_range_kind vr0type = this->kind ();
tree vr0min = this->min ();
tree vr0max = this->max ();
union_ranges (&vr0type, &vr0min, &vr0max,
other->kind (), other->min (), other->max ());
*this = value_range_base (vr0type, vr0min, vr0max);
if (this->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
anti-range. */
if (range_includes_zero_p (&saved) == 0
&& range_includes_zero_p (other) == 0)
{
tree zero = build_int_cst (saved.type (), 0);
*this = value_range_base (VR_ANTI_RANGE, zero, zero);
return;
}
this->set_varying ();
return;
}
this->set_and_canonicalize (this->kind (), this->min (), this->max ());
} }
/* Meet operation for value ranges. Given two value ranges VR0 and /* Meet operation for value ranges. Given two value ranges VR0 and
VR1, store in VR0 a range that contains both VR0 and VR1. This VR1, store in VR0 a range that contains both VR0 and VR1. This
may not be the smallest possible such range. */ may not be the smallest possible such range. */
void void
value_range::union_helper (value_range *vr0, const value_range *vr1) value_range_base::union_ (const value_range_base *other)
{ {
if (vr1->undefined_p ()) if (dump_file && (dump_flags & TDF_DETAILS))
{
/* VR0 already has the resulting range. */
return;
}
if (vr0->undefined_p ())
{
vr0->deep_copy (vr1);
return;
}
if (vr0->varying_p ())
{ {
/* Nothing to do. VR0 already has the resulting range. */ fprintf (dump_file, "Meeting\n ");
return; dump_value_range (dump_file, this);
fprintf (dump_file, "\nand\n ");
dump_value_range (dump_file, other);
fprintf (dump_file, "\n");
} }
if (vr1->varying_p ()) *this = union_helper (this, other);
{
vr0->set_varying ();
return;
}
value_range_kind vr0type = vr0->kind (); if (dump_file && (dump_flags & TDF_DETAILS))
tree vr0min = vr0->min ();
tree vr0max = vr0->max ();
union_ranges (&vr0type, &vr0min, &vr0max,
vr1->kind (), vr1->min (), vr1->max ());
/* Work on a temporary so we can still use vr0 when union returns varying. */
value_range tem;
tem.set_and_canonicalize (vr0type, vr0min, vr0max);
if (tem.varying_p ())
{ {
/* Failed to find an efficient meet. Before giving up and setting fprintf (dump_file, "to\n ");
the result to VARYING, see if we can at least derive a useful dump_value_range (dump_file, this);
anti-range. */ fprintf (dump_file, "\n");
if (range_includes_zero_p (vr0) == 0
&& range_includes_zero_p (vr1) == 0)
{
vr0->set_nonnull (vr0->type ());
return;
}
vr0->set_varying ();
return;
} }
vr0->update (tem.kind (), tem.min (), tem.max ());
/* The resulting set of equivalences is always the intersection of
the two sets. */
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 void
...@@ -6216,7 +6164,24 @@ value_range::union_ (const value_range *other) ...@@ -6216,7 +6164,24 @@ value_range::union_ (const value_range *other)
dump_value_range (dump_file, other); dump_value_range (dump_file, other);
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
union_helper (this, other);
/* If THIS is undefined we want to pick up equivalences from OTHER.
Just special-case this here rather than trying to fixup after the fact. */
if (this->undefined_p ())
this->deep_copy (other);
else
{
value_range_base tem = union_helper (this, other);
this->update (tem.kind (), tem.min (), tem.max ());
/* The resulting set of equivalences is always the intersection of
the two sets. */
if (this->m_equiv && other->m_equiv && this->m_equiv != other->m_equiv)
bitmap_and_into (this->m_equiv, other->m_equiv);
else if (this->m_equiv && !other->m_equiv)
bitmap_clear (this->m_equiv);
}
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
fprintf (dump_file, "to\n "); fprintf (dump_file, "to\n ");
...@@ -6867,11 +6832,11 @@ make_pass_vrp (gcc::context *ctxt) ...@@ -6867,11 +6832,11 @@ make_pass_vrp (gcc::context *ctxt)
/* Worker for determine_value_range. */ /* Worker for determine_value_range. */
static void static void
determine_value_range_1 (value_range *vr, tree expr) determine_value_range_1 (value_range_base *vr, tree expr)
{ {
if (BINARY_CLASS_P (expr)) if (BINARY_CLASS_P (expr))
{ {
value_range vr0, vr1; value_range_base vr0, vr1;
determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0)); determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1)); determine_value_range_1 (&vr1, TREE_OPERAND (expr, 1));
extract_range_from_binary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr), extract_range_from_binary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
...@@ -6879,7 +6844,7 @@ determine_value_range_1 (value_range *vr, tree expr) ...@@ -6879,7 +6844,7 @@ determine_value_range_1 (value_range *vr, tree expr)
} }
else if (UNARY_CLASS_P (expr)) else if (UNARY_CLASS_P (expr))
{ {
value_range vr0; value_range_base vr0;
determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0)); determine_value_range_1 (&vr0, TREE_OPERAND (expr, 0));
extract_range_from_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr), extract_range_from_unary_expr (vr, TREE_CODE (expr), TREE_TYPE (expr),
&vr0, TREE_TYPE (TREE_OPERAND (expr, 0))); &vr0, TREE_TYPE (TREE_OPERAND (expr, 0)));
...@@ -6908,7 +6873,7 @@ determine_value_range_1 (value_range *vr, tree expr) ...@@ -6908,7 +6873,7 @@ determine_value_range_1 (value_range *vr, tree expr)
value_range_kind value_range_kind
determine_value_range (tree expr, wide_int *min, wide_int *max) determine_value_range (tree expr, wide_int *min, wide_int *max)
{ {
value_range vr; value_range_base vr;
determine_value_range_1 (&vr, expr); determine_value_range_1 (&vr, expr);
if (vr.constant_p ()) if (vr.constant_p ())
{ {
......
...@@ -77,6 +77,8 @@ public: ...@@ -77,6 +77,8 @@ public:
protected: protected:
void check (); void check ();
static value_range_base union_helper (const value_range_base *,
const value_range_base *);
enum value_range_kind m_kind; enum value_range_kind m_kind;
...@@ -145,7 +147,6 @@ class GTY((user)) value_range : public value_range_base ...@@ -145,7 +147,6 @@ class GTY((user)) value_range : public value_range_base
void check (); void check ();
bool equal_p (const value_range &, bool ignore_equivs) const; bool equal_p (const value_range &, bool ignore_equivs) const;
void intersect_helper (value_range *, const value_range *); void intersect_helper (value_range *, const value_range *);
void union_helper (value_range *, const value_range *);
/* Set of SSA names whose value ranges are equivalent to this one. /* 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. */ This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment