* [COMMITTED] Implement vrange::supports_type_p.
@ 2022-06-03 7:30 Aldy Hernandez
2022-06-13 9:43 ` Richard Biener
0 siblings, 1 reply; 6+ messages in thread
From: Aldy Hernandez @ 2022-06-03 7:30 UTC (permalink / raw)
To: GCC patches, Richard Biener, Martin Liska
[I have conservatively assumed that both the loop-ch and loop-unswitch
passes, which also use the ranger, only support integers and pointers.
If the goal is to handle other types as well, irange::supports_p()
should be Value_Range::supports_type_p(), and any uses of
int_range_max should be converted to Value_Range. I can help in the
conversion if you'd like.]
As discussed, this patch disambiguates the use of supports_type_p
throughout, as what ranger supports is a totally different question
than what a given range variant (irange, frange, etc) supports.
Unfortunately we need both a static method and a virtual method, and
they can't be named the same. The uses are documented in the vrange
class:
+// To query what types ranger and the entire ecosystem can support,
+// use Value_Range::supports_type_p(tree type). This is a static
+// method available independently of any vrange object.
+//
+// To query what a given vrange variant can support, use:
+// irange::supports_p ()
+// frange::supports_p ()
+// etc
+//
+// To query what a range object can support, use:
+// void foo (vrange &v, irange &i, frange &f)
+// {
+// if (v.supports_type_p (type)) ...
+// if (i.supports_type_p (type)) ...
+// if (f.supports_type_p (type)) ...
+// }
The value_range_equiv::supports_p() method can be use to determine
what legacy VRP supports, as irange::supports_p() will no longer be
applicable in the evrp analyzer code base once irange and prange are
split.
Tested on x86-64 Linux.
gcc/ChangeLog:
* gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Adjust for
an object level supports_type_p for irange and a static
Value_Range::supports_type_p.
* gimple-range-fold.cc (fold_using_range::range_of_range_op): Same.
(fold_using_range::range_of_address): Same.
(fold_using_range::range_of_builtin_call): Same.
* gimple-range-fold.h (gimple_range_type): Same.
(gimple_range_ssa_p): Same.
* gimple-range-path.cc (path_range_query::internal_range_of_expr):
Same.
(path_range_query::range_of_stmt): Same.
(path_range_query::add_to_imports): Same.
* gimple-range.cc (gimple_ranger::range_on_edge): Same.
(gimple_ranger::export_global_ranges): Same.
* gimple-ssa-evrp-analyze.cc
(evrp_range_analyzer::record_ranges_from_phis): Same.
* range-op.cc (range_operator::wi_fold): Same.
(range_operator::fold_range): Same.
* tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Same.
* tree-ssa-loop-unswitch.cc (struct unswitch_predicate): Same.
(evaluate_control_stmt_using_entry_checks): Same.
* tree-ssa-threadedge.cc
(hybrid_jt_simplifier::compute_ranges_from_state): Same.
* tree-vrp.cc (supported_types_p): Same.
* value-query.cc (range_query::value_of_expr): Same.
(range_query::value_on_edge): Same.
(range_query::value_of_stmt): Same.
(range_query::get_tree_range): Same.
(get_range_global): Same.
(global_range_query::range_of_expr): Same.
* value-range-equiv.h (class value_range_equiv): Same.
* value-range.cc (irange::supports_type_p): Same.
(unsupported_range::supports_type_p): Same.
* value-range.h (enum value_range_discriminator): Same.
(Value_Range::init): Same.
(Value_Range::supports_type_p): Same.
(irange::supports_type_p): Same.
(irange::supports_p): Same.
(vrange::supports_type_p): Same.
(vrange_allocator::alloc_vrange): Same.
---
gcc/gimple-range-edge.cc | 3 +--
gcc/gimple-range-fold.cc | 5 ++--
gcc/gimple-range-fold.h | 4 +--
gcc/gimple-range-path.cc | 6 ++---
gcc/gimple-range.cc | 4 +--
gcc/gimple-ssa-evrp-analyze.cc | 2 +-
gcc/range-op.cc | 4 +--
gcc/tree-ssa-loop-ch.cc | 2 +-
gcc/tree-ssa-loop-unswitch.cc | 6 ++---
gcc/tree-ssa-threadedge.cc | 2 +-
gcc/tree-vrp.cc | 4 +--
gcc/value-query.cc | 16 ++++++------
gcc/value-range-equiv.h | 4 +++
gcc/value-range.cc | 12 +++++++++
gcc/value-range.h | 45 +++++++++++++++++++++++++---------
15 files changed, 76 insertions(+), 43 deletions(-)
diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
index 6fe33408f7e..03a804ac2be 100644
--- a/gcc/gimple-range-edge.cc
+++ b/gcc/gimple-range-edge.cc
@@ -44,8 +44,7 @@ gimple_outgoing_range_stmt_p (basic_block bb)
gimple *s = gsi_stmt (gsi);
if (is_a<gcond *> (s) && range_op_handler (s))
return gsi_stmt (gsi);
- gswitch *sw = dyn_cast<gswitch *> (s);
- if (sw && irange::supports_type_p (TREE_TYPE (gimple_switch_index (sw))))
+ if (is_a <gswitch *> (s))
return gsi_stmt (gsi);
}
return NULL;
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
index c1a801668c4..2a8c66e0c05 100644
--- a/gcc/gimple-range-fold.cc
+++ b/gcc/gimple-range-fold.cc
@@ -632,7 +632,7 @@ fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
}
// Fold range, and register any dependency if available.
handler.fold_range (r, type, range1, range2, rel);
- if (irange::supports_type_p (type))
+ if (irange::supports_p (type))
relation_fold_and_or (as_a <irange> (r), s, src);
if (lhs)
{
@@ -709,7 +709,6 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
tree lhs = gimple_get_lhs (stmt);
if (lhs && gimple_range_ssa_p (ssa) && src.gori ())
src.gori ()->register_dependency (lhs, ssa);
- gcc_checking_assert (irange::supports_type_p (TREE_TYPE (ssa)));
src.get_operand (r, ssa);
range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt)));
@@ -985,7 +984,7 @@ fold_using_range::range_of_builtin_call (vrange &r, gcall *call,
tree type = gimple_range_type (call);
gcc_checking_assert (type);
- if (irange::supports_type_p (type))
+ if (irange::supports_p (type))
return range_of_builtin_int_call (as_a <irange> (r), call, src);
return false;
diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
index df24280ee40..fbf66275f74 100644
--- a/gcc/gimple-range-fold.h
+++ b/gcc/gimple-range-fold.h
@@ -66,7 +66,7 @@ gimple_range_type (const gimple *s)
type = TREE_TYPE (type);
}
}
- if (type && vrange::supports_type_p (type))
+ if (type && Value_Range::supports_type_p (type))
return type;
return NULL_TREE;
}
@@ -79,7 +79,7 @@ gimple_range_ssa_p (tree exp)
if (exp && TREE_CODE (exp) == SSA_NAME &&
!SSA_NAME_IS_VIRTUAL_OPERAND (exp) &&
!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp) &&
- vrange::supports_type_p (TREE_TYPE (exp)))
+ Value_Range::supports_type_p (TREE_TYPE (exp)))
return exp;
return NULL_TREE;
}
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
index f8ae6fb9ffb..e1b9683c1e4 100644
--- a/gcc/gimple-range-path.cc
+++ b/gcc/gimple-range-path.cc
@@ -192,7 +192,7 @@ path_range_query::range_on_path_entry (vrange &r, tree name)
bool
path_range_query::internal_range_of_expr (vrange &r, tree name, gimple *stmt)
{
- if (!vrange::supports_type_p (TREE_TYPE (name)))
+ if (!r.supports_type_p (TREE_TYPE (name)))
return false;
if (get_cache (r, name))
@@ -548,7 +548,7 @@ bool
path_range_query::add_to_imports (tree name, bitmap imports)
{
if (TREE_CODE (name) == SSA_NAME
- && vrange::supports_type_p (TREE_TYPE (name)))
+ && Value_Range::supports_type_p (TREE_TYPE (name)))
return bitmap_set_bit (imports, SSA_NAME_VERSION (name));
return false;
}
@@ -764,7 +764,7 @@ path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree)
{
tree type = gimple_range_type (stmt);
- if (!type || !vrange::supports_type_p (type))
+ if (!type || !r.supports_type_p (type))
return false;
// If resolving unknowns, fold the statement making use of any
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 12da16841c2..67dafb2a2c0 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -201,7 +201,7 @@ bool
gimple_ranger::range_on_edge (vrange &r, edge e, tree name)
{
Value_Range edge_range (TREE_TYPE (name));
- gcc_checking_assert (vrange::supports_type_p (TREE_TYPE (name)));
+ gcc_checking_assert (r.supports_type_p (TREE_TYPE (name)));
// Do not process values along abnormal edges.
if (e->flags & EDGE_ABNORMAL)
@@ -514,7 +514,7 @@ gimple_ranger::export_global_ranges ()
print_header = false;
}
- if (!irange::supports_type_p (TREE_TYPE (name)))
+ if (!irange::supports_p (TREE_TYPE (name)))
continue;
vrange &v = r;
diff --git a/gcc/gimple-ssa-evrp-analyze.cc b/gcc/gimple-ssa-evrp-analyze.cc
index 16e5a75b1db..82142db7976 100644
--- a/gcc/gimple-ssa-evrp-analyze.cc
+++ b/gcc/gimple-ssa-evrp-analyze.cc
@@ -255,7 +255,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
/* Skips floats and other things we can't represent in a
range. */
- if (!value_range::supports_type_p (TREE_TYPE (lhs)))
+ if (!value_range_equiv::supports_p (TREE_TYPE (lhs)))
continue;
value_range_equiv vr_result;
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 028b4b7237c..5150c6021b8 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -111,7 +111,7 @@ range_operator::wi_fold (irange &r, tree type,
const wide_int &rh_lb ATTRIBUTE_UNUSED,
const wide_int &rh_ub ATTRIBUTE_UNUSED) const
{
- gcc_checking_assert (irange::supports_type_p (type));
+ gcc_checking_assert (r.supports_type_p (type));
r.set_varying (type);
}
@@ -181,7 +181,7 @@ range_operator::fold_range (irange &r, tree type,
const irange &rh,
relation_kind rel) const
{
- gcc_checking_assert (irange::supports_type_p (type));
+ gcc_checking_assert (r.supports_type_p (type));
if (empty_range_varying (r, type, lh, rh))
return true;
diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 2f5a390404c..26d96c0c21a 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -55,7 +55,7 @@ entry_loop_condition_is_static (class loop *l, path_range_query *query)
gcond *last = safe_dyn_cast <gcond *> (last_stmt (e->dest));
if (!last
- || !irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (last))))
+ || !irange::supports_p (TREE_TYPE (gimple_cond_lhs (last))))
return false;
edge true_e, false_e;
diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
index ad1d05ccdff..95ccc0b7b47 100644
--- a/gcc/tree-ssa-loop-unswitch.cc
+++ b/gcc/tree-ssa-loop-unswitch.cc
@@ -113,7 +113,7 @@ struct unswitch_predicate
true_range (edge_range), edge_index (edge_index_), switch_p (true)
{
gcc_assert (!(e->flags & (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE))
- && irange::supports_type_p (TREE_TYPE (lhs)));
+ && irange::supports_p (TREE_TYPE (lhs)));
false_range = true_range;
if (!false_range.varying_p ()
&& !false_range.undefined_p ())
@@ -134,7 +134,7 @@ struct unswitch_predicate
tree rhs = gimple_cond_rhs (stmt);
enum tree_code code = gimple_cond_code (stmt);
condition = build2 (code, boolean_type_node, lhs, rhs);
- if (irange::supports_type_p (TREE_TYPE (lhs)))
+ if (irange::supports_p (TREE_TYPE (lhs)))
{
auto range_op = range_op_handler (code, TREE_TYPE (lhs));
int_range<2> rhs_range (TREE_TYPE (rhs));
@@ -646,7 +646,7 @@ evaluate_control_stmt_using_entry_checks (gimple *stmt,
TREE_OPERAND (last_predicate->condition, 1)))
return true_edge ? boolean_true_node : boolean_false_node;
/* Else try ranger if it supports LHS. */
- else if (irange::supports_type_p (TREE_TYPE (lhs)))
+ else if (irange::supports_p (TREE_TYPE (lhs)))
{
int_range<2> r;
int_range_max path_range;
diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc
index 931aa7479bb..a70aebd10a7 100644
--- a/gcc/tree-ssa-threadedge.cc
+++ b/gcc/tree-ssa-threadedge.cc
@@ -1452,7 +1452,7 @@ hybrid_jt_simplifier::compute_ranges_from_state (gimple *stmt, jt_state *state)
tree op = gimple_op (stmt, i);
if (op
&& TREE_CODE (op) == SSA_NAME
- && irange::supports_type_p (TREE_TYPE (op)))
+ && Value_Range::supports_type_p (TREE_TYPE (op)))
bitmap_set_bit (imports, SSA_NAME_VERSION (op));
}
}
diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
index 74277617b66..30022dac108 100644
--- a/gcc/tree-vrp.cc
+++ b/gcc/tree-vrp.cc
@@ -932,8 +932,8 @@ supported_types_p (value_range *vr,
tree type0,
tree type1 = NULL)
{
- if (!value_range::supports_type_p (type0)
- || (type1 && !value_range::supports_type_p (type1)))
+ if (!value_range_equiv::supports_p (type0)
+ || (type1 && !value_range_equiv::supports_p (type1)))
{
vr->set_varying (type0);
return false;
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index e40e358ebd4..1d7541ce34f 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -80,7 +80,7 @@ range_query::value_of_expr (tree expr, gimple *stmt)
{
tree t;
- if (!vrange::supports_type_p (TREE_TYPE (expr)))
+ if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
return NULL_TREE;
Value_Range r (TREE_TYPE (expr));
@@ -102,7 +102,7 @@ range_query::value_on_edge (edge e, tree expr)
{
tree t;
- if (!vrange::supports_type_p (TREE_TYPE (expr)))
+ if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
return NULL_TREE;
Value_Range r (TREE_TYPE (expr));
if (range_on_edge (r, e, expr))
@@ -128,7 +128,7 @@ range_query::value_of_stmt (gimple *stmt, tree name)
gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
- if (!name || !vrange::supports_type_p (TREE_TYPE (name)))
+ if (!name || !Value_Range::supports_type_p (TREE_TYPE (name)))
return NULL_TREE;
Value_Range r (TREE_TYPE (name));
if (range_of_stmt (r, stmt, name) && r.singleton_p (&t))
@@ -196,7 +196,7 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
else
type = TREE_TYPE (expr);
- if (!vrange::supports_type_p (type))
+ if (!Value_Range::supports_type_p (type))
{
r.set_undefined ();
return false;
@@ -252,7 +252,7 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
{
range_op_handler op (TREE_CODE (expr), type);
tree op0_type = TREE_TYPE (TREE_OPERAND (expr, 0));
- if (op && vrange::supports_type_p (op0_type))
+ if (op && Value_Range::supports_type_p (op0_type))
{
Value_Range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
Value_Range r1 (type);
@@ -387,7 +387,7 @@ get_range_global (vrange &r, tree name)
}
else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
{
- gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
+ gcc_checking_assert (irange::supports_p (TREE_TYPE (name)));
get_ssa_name_range_info (as_a <irange> (r), name);
if (r.undefined_p ())
r.set_varying (type);
@@ -441,9 +441,7 @@ global_range_query global_ranges;
bool
global_range_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
{
- tree type = TREE_TYPE (expr);
-
- if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr))
+ if (!gimple_range_ssa_p (expr))
return get_tree_range (r, expr, stmt);
get_range_global (r, expr);
diff --git a/gcc/value-range-equiv.h b/gcc/value-range-equiv.h
index 743ceb2b227..0a52d1372a1 100644
--- a/gcc/value-range-equiv.h
+++ b/gcc/value-range-equiv.h
@@ -67,6 +67,10 @@ class GTY((user)) value_range_equiv : public value_range
void deep_copy (const value_range_equiv *);
void dump (FILE *) const;
void dump () const;
+ static bool supports_p (tree type)
+ {
+ return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
+ }
private:
/* Deep-copies bitmap argument. */
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 429672737a8..c4bcb970094 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -107,6 +107,12 @@ vrange::operator== (const vrange &src) const
gcc_unreachable ();
}
+bool
+irange::supports_type_p (tree type) const
+{
+ return supports_p (type);
+}
+
// Return TRUE if R fits in THIS.
bool
@@ -140,6 +146,12 @@ unsupported_range::type () const
return nullptr;
}
+bool
+unsupported_range::supports_type_p (tree) const
+{
+ return false;
+}
+
void
unsupported_range::set_undefined ()
{
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 5cd0e0ef76a..69cf6c304d6 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -50,6 +50,23 @@ enum value_range_discriminator
};
// Abstract class for ranges of any of the supported types.
+//
+// To query what types ranger and the entire ecosystem can support,
+// use Value_Range::supports_type_p(tree type). This is a static
+// method available independently of any vrange object.
+//
+// To query what a given vrange variant can support, use:
+// irange::supports_p ()
+// frange::supports_p ()
+// etc
+//
+// To query what a range object can support, use:
+// void foo (vrange &v, irange &i, frange &f)
+// {
+// if (v.supports_type_p (type)) ...
+// if (i.supports_type_p (type)) ...
+// if (f.supports_type_p (type)) ...
+// }
class vrange
{
@@ -58,6 +75,7 @@ class vrange
public:
virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
virtual tree type () const = 0;
+ virtual bool supports_type_p (tree type) const = 0;
virtual void set_varying (tree type) = 0;
virtual void set_undefined () = 0;
virtual void dump (FILE * = stderr) const = 0;
@@ -72,8 +90,6 @@ public:
virtual void set_nonnegative (tree type) = 0;
virtual bool fits_p (const vrange &r) const = 0;
- static bool supports_type_p (tree);
-
bool varying_p () const;
bool undefined_p () const;
vrange& operator= (const vrange &);
@@ -103,7 +119,8 @@ public:
virtual void set_undefined () override;
// Range types.
- static bool supports_type_p (tree);
+ static bool supports_p (tree type);
+ virtual bool supports_type_p (tree type) const override;
virtual tree type () const override;
// Iteration over sub-ranges.
@@ -228,6 +245,7 @@ public:
unsupported_range ();
virtual void set (tree, tree, value_range_kind) override;
virtual tree type () const override;
+ virtual bool supports_type_p (tree type) const override;
virtual void set_varying (tree type) override;
virtual void set_undefined () override;
virtual void dump (FILE *) const override;
@@ -331,6 +349,7 @@ public:
operator vrange &();
operator const vrange &() const;
void dump (FILE *out = stderr) const;
+ static bool supports_type_p (tree type);
// Convenience methods for vrange compatability.
void set (tree min, tree max, value_range_kind kind = VR_RANGE)
@@ -387,7 +406,7 @@ Value_Range::init (tree type)
{
gcc_checking_assert (TYPE_P (type));
- if (irange::supports_type_p (type))
+ if (irange::supports_p (type))
m_vrange = &m_irange;
else
m_vrange = &m_unsupported;
@@ -444,6 +463,14 @@ Value_Range::operator const vrange &() const
return *m_vrange;
}
+// Return TRUE if TYPE is supported by the vrange infrastructure.
+
+inline bool
+Value_Range::supports_type_p (tree type)
+{
+ return irange::supports_p (type);
+}
+
// Returns true for an old-school value_range as described above.
inline bool
irange::legacy_mode_p () const
@@ -580,7 +607,7 @@ irange::nonzero_p () const
}
inline bool
-irange::supports_type_p (tree type)
+irange::supports_p (tree type)
{
return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
}
@@ -864,12 +891,6 @@ irange::normalize_kind ()
}
}
-inline bool
-vrange::supports_type_p (tree type)
-{
- return irange::supports_type_p (type);
-}
-
// Return the maximum value for TYPE.
inline tree
@@ -944,7 +965,7 @@ vrange_allocator::alloc (unsigned bytes)
inline vrange *
vrange_allocator::alloc_vrange (tree type)
{
- if (irange::supports_type_p (type))
+ if (irange::supports_p (type))
return alloc_irange (2);
gcc_unreachable ();
--
2.36.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [COMMITTED] Implement vrange::supports_type_p.
2022-06-03 7:30 [COMMITTED] Implement vrange::supports_type_p Aldy Hernandez
@ 2022-06-13 9:43 ` Richard Biener
2022-06-27 19:00 ` Aldy Hernandez
0 siblings, 1 reply; 6+ messages in thread
From: Richard Biener @ 2022-06-13 9:43 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: GCC patches, Martin Liska, Andrew MacLeod
On Fri, Jun 3, 2022 at 9:31 AM Aldy Hernandez <aldyh@redhat.com> wrote:
>
> [I have conservatively assumed that both the loop-ch and loop-unswitch
> passes, which also use the ranger, only support integers and pointers.
> If the goal is to handle other types as well, irange::supports_p()
> should be Value_Range::supports_type_p(), and any uses of
> int_range_max should be converted to Value_Range. I can help in the
> conversion if you'd like.]
Both should also support float ranges, so yes - if you can send simple
patches I'll review them.
> As discussed, this patch disambiguates the use of supports_type_p
> throughout, as what ranger supports is a totally different question
> than what a given range variant (irange, frange, etc) supports.
>
> Unfortunately we need both a static method and a virtual method, and
> they can't be named the same. The uses are documented in the vrange
> class:
>
> +// To query what types ranger and the entire ecosystem can support,
> +// use Value_Range::supports_type_p(tree type). This is a static
> +// method available independently of any vrange object.
> +//
> +// To query what a given vrange variant can support, use:
> +// irange::supports_p ()
> +// frange::supports_p ()
> +// etc
> +//
> +// To query what a range object can support, use:
> +// void foo (vrange &v, irange &i, frange &f)
> +// {
> +// if (v.supports_type_p (type)) ...
> +// if (i.supports_type_p (type)) ...
> +// if (f.supports_type_p (type)) ...
> +// }
>
> The value_range_equiv::supports_p() method can be use to determine
> what legacy VRP supports, as irange::supports_p() will no longer be
> applicable in the evrp analyzer code base once irange and prange are
> split.
>
> Tested on x86-64 Linux.
>
> gcc/ChangeLog:
>
> * gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Adjust for
> an object level supports_type_p for irange and a static
> Value_Range::supports_type_p.
> * gimple-range-fold.cc (fold_using_range::range_of_range_op): Same.
> (fold_using_range::range_of_address): Same.
> (fold_using_range::range_of_builtin_call): Same.
> * gimple-range-fold.h (gimple_range_type): Same.
> (gimple_range_ssa_p): Same.
> * gimple-range-path.cc (path_range_query::internal_range_of_expr):
> Same.
> (path_range_query::range_of_stmt): Same.
> (path_range_query::add_to_imports): Same.
> * gimple-range.cc (gimple_ranger::range_on_edge): Same.
> (gimple_ranger::export_global_ranges): Same.
> * gimple-ssa-evrp-analyze.cc
> (evrp_range_analyzer::record_ranges_from_phis): Same.
> * range-op.cc (range_operator::wi_fold): Same.
> (range_operator::fold_range): Same.
> * tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Same.
> * tree-ssa-loop-unswitch.cc (struct unswitch_predicate): Same.
> (evaluate_control_stmt_using_entry_checks): Same.
> * tree-ssa-threadedge.cc
> (hybrid_jt_simplifier::compute_ranges_from_state): Same.
> * tree-vrp.cc (supported_types_p): Same.
> * value-query.cc (range_query::value_of_expr): Same.
> (range_query::value_on_edge): Same.
> (range_query::value_of_stmt): Same.
> (range_query::get_tree_range): Same.
> (get_range_global): Same.
> (global_range_query::range_of_expr): Same.
> * value-range-equiv.h (class value_range_equiv): Same.
> * value-range.cc (irange::supports_type_p): Same.
> (unsupported_range::supports_type_p): Same.
> * value-range.h (enum value_range_discriminator): Same.
> (Value_Range::init): Same.
> (Value_Range::supports_type_p): Same.
> (irange::supports_type_p): Same.
> (irange::supports_p): Same.
> (vrange::supports_type_p): Same.
> (vrange_allocator::alloc_vrange): Same.
> ---
> gcc/gimple-range-edge.cc | 3 +--
> gcc/gimple-range-fold.cc | 5 ++--
> gcc/gimple-range-fold.h | 4 +--
> gcc/gimple-range-path.cc | 6 ++---
> gcc/gimple-range.cc | 4 +--
> gcc/gimple-ssa-evrp-analyze.cc | 2 +-
> gcc/range-op.cc | 4 +--
> gcc/tree-ssa-loop-ch.cc | 2 +-
> gcc/tree-ssa-loop-unswitch.cc | 6 ++---
> gcc/tree-ssa-threadedge.cc | 2 +-
> gcc/tree-vrp.cc | 4 +--
> gcc/value-query.cc | 16 ++++++------
> gcc/value-range-equiv.h | 4 +++
> gcc/value-range.cc | 12 +++++++++
> gcc/value-range.h | 45 +++++++++++++++++++++++++---------
> 15 files changed, 76 insertions(+), 43 deletions(-)
>
> diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
> index 6fe33408f7e..03a804ac2be 100644
> --- a/gcc/gimple-range-edge.cc
> +++ b/gcc/gimple-range-edge.cc
> @@ -44,8 +44,7 @@ gimple_outgoing_range_stmt_p (basic_block bb)
> gimple *s = gsi_stmt (gsi);
> if (is_a<gcond *> (s) && range_op_handler (s))
> return gsi_stmt (gsi);
> - gswitch *sw = dyn_cast<gswitch *> (s);
> - if (sw && irange::supports_type_p (TREE_TYPE (gimple_switch_index (sw))))
> + if (is_a <gswitch *> (s))
> return gsi_stmt (gsi);
> }
> return NULL;
> diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
> index c1a801668c4..2a8c66e0c05 100644
> --- a/gcc/gimple-range-fold.cc
> +++ b/gcc/gimple-range-fold.cc
> @@ -632,7 +632,7 @@ fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
> }
> // Fold range, and register any dependency if available.
> handler.fold_range (r, type, range1, range2, rel);
> - if (irange::supports_type_p (type))
> + if (irange::supports_p (type))
> relation_fold_and_or (as_a <irange> (r), s, src);
> if (lhs)
> {
> @@ -709,7 +709,6 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
> tree lhs = gimple_get_lhs (stmt);
> if (lhs && gimple_range_ssa_p (ssa) && src.gori ())
> src.gori ()->register_dependency (lhs, ssa);
> - gcc_checking_assert (irange::supports_type_p (TREE_TYPE (ssa)));
> src.get_operand (r, ssa);
> range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt)));
>
> @@ -985,7 +984,7 @@ fold_using_range::range_of_builtin_call (vrange &r, gcall *call,
> tree type = gimple_range_type (call);
> gcc_checking_assert (type);
>
> - if (irange::supports_type_p (type))
> + if (irange::supports_p (type))
> return range_of_builtin_int_call (as_a <irange> (r), call, src);
>
> return false;
> diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
> index df24280ee40..fbf66275f74 100644
> --- a/gcc/gimple-range-fold.h
> +++ b/gcc/gimple-range-fold.h
> @@ -66,7 +66,7 @@ gimple_range_type (const gimple *s)
> type = TREE_TYPE (type);
> }
> }
> - if (type && vrange::supports_type_p (type))
> + if (type && Value_Range::supports_type_p (type))
> return type;
> return NULL_TREE;
> }
> @@ -79,7 +79,7 @@ gimple_range_ssa_p (tree exp)
> if (exp && TREE_CODE (exp) == SSA_NAME &&
> !SSA_NAME_IS_VIRTUAL_OPERAND (exp) &&
> !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp) &&
> - vrange::supports_type_p (TREE_TYPE (exp)))
> + Value_Range::supports_type_p (TREE_TYPE (exp)))
> return exp;
> return NULL_TREE;
> }
> diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
> index f8ae6fb9ffb..e1b9683c1e4 100644
> --- a/gcc/gimple-range-path.cc
> +++ b/gcc/gimple-range-path.cc
> @@ -192,7 +192,7 @@ path_range_query::range_on_path_entry (vrange &r, tree name)
> bool
> path_range_query::internal_range_of_expr (vrange &r, tree name, gimple *stmt)
> {
> - if (!vrange::supports_type_p (TREE_TYPE (name)))
> + if (!r.supports_type_p (TREE_TYPE (name)))
> return false;
>
> if (get_cache (r, name))
> @@ -548,7 +548,7 @@ bool
> path_range_query::add_to_imports (tree name, bitmap imports)
> {
> if (TREE_CODE (name) == SSA_NAME
> - && vrange::supports_type_p (TREE_TYPE (name)))
> + && Value_Range::supports_type_p (TREE_TYPE (name)))
> return bitmap_set_bit (imports, SSA_NAME_VERSION (name));
> return false;
> }
> @@ -764,7 +764,7 @@ path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree)
> {
> tree type = gimple_range_type (stmt);
>
> - if (!type || !vrange::supports_type_p (type))
> + if (!type || !r.supports_type_p (type))
> return false;
>
> // If resolving unknowns, fold the statement making use of any
> diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
> index 12da16841c2..67dafb2a2c0 100644
> --- a/gcc/gimple-range.cc
> +++ b/gcc/gimple-range.cc
> @@ -201,7 +201,7 @@ bool
> gimple_ranger::range_on_edge (vrange &r, edge e, tree name)
> {
> Value_Range edge_range (TREE_TYPE (name));
> - gcc_checking_assert (vrange::supports_type_p (TREE_TYPE (name)));
> + gcc_checking_assert (r.supports_type_p (TREE_TYPE (name)));
>
> // Do not process values along abnormal edges.
> if (e->flags & EDGE_ABNORMAL)
> @@ -514,7 +514,7 @@ gimple_ranger::export_global_ranges ()
> print_header = false;
> }
>
> - if (!irange::supports_type_p (TREE_TYPE (name)))
> + if (!irange::supports_p (TREE_TYPE (name)))
> continue;
>
> vrange &v = r;
> diff --git a/gcc/gimple-ssa-evrp-analyze.cc b/gcc/gimple-ssa-evrp-analyze.cc
> index 16e5a75b1db..82142db7976 100644
> --- a/gcc/gimple-ssa-evrp-analyze.cc
> +++ b/gcc/gimple-ssa-evrp-analyze.cc
> @@ -255,7 +255,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
>
> /* Skips floats and other things we can't represent in a
> range. */
> - if (!value_range::supports_type_p (TREE_TYPE (lhs)))
> + if (!value_range_equiv::supports_p (TREE_TYPE (lhs)))
> continue;
>
> value_range_equiv vr_result;
> diff --git a/gcc/range-op.cc b/gcc/range-op.cc
> index 028b4b7237c..5150c6021b8 100644
> --- a/gcc/range-op.cc
> +++ b/gcc/range-op.cc
> @@ -111,7 +111,7 @@ range_operator::wi_fold (irange &r, tree type,
> const wide_int &rh_lb ATTRIBUTE_UNUSED,
> const wide_int &rh_ub ATTRIBUTE_UNUSED) const
> {
> - gcc_checking_assert (irange::supports_type_p (type));
> + gcc_checking_assert (r.supports_type_p (type));
> r.set_varying (type);
> }
>
> @@ -181,7 +181,7 @@ range_operator::fold_range (irange &r, tree type,
> const irange &rh,
> relation_kind rel) const
> {
> - gcc_checking_assert (irange::supports_type_p (type));
> + gcc_checking_assert (r.supports_type_p (type));
> if (empty_range_varying (r, type, lh, rh))
> return true;
>
> diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
> index 2f5a390404c..26d96c0c21a 100644
> --- a/gcc/tree-ssa-loop-ch.cc
> +++ b/gcc/tree-ssa-loop-ch.cc
> @@ -55,7 +55,7 @@ entry_loop_condition_is_static (class loop *l, path_range_query *query)
> gcond *last = safe_dyn_cast <gcond *> (last_stmt (e->dest));
>
> if (!last
> - || !irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (last))))
> + || !irange::supports_p (TREE_TYPE (gimple_cond_lhs (last))))
> return false;
>
> edge true_e, false_e;
> diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
> index ad1d05ccdff..95ccc0b7b47 100644
> --- a/gcc/tree-ssa-loop-unswitch.cc
> +++ b/gcc/tree-ssa-loop-unswitch.cc
> @@ -113,7 +113,7 @@ struct unswitch_predicate
> true_range (edge_range), edge_index (edge_index_), switch_p (true)
> {
> gcc_assert (!(e->flags & (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE))
> - && irange::supports_type_p (TREE_TYPE (lhs)));
> + && irange::supports_p (TREE_TYPE (lhs)));
> false_range = true_range;
> if (!false_range.varying_p ()
> && !false_range.undefined_p ())
> @@ -134,7 +134,7 @@ struct unswitch_predicate
> tree rhs = gimple_cond_rhs (stmt);
> enum tree_code code = gimple_cond_code (stmt);
> condition = build2 (code, boolean_type_node, lhs, rhs);
> - if (irange::supports_type_p (TREE_TYPE (lhs)))
> + if (irange::supports_p (TREE_TYPE (lhs)))
> {
> auto range_op = range_op_handler (code, TREE_TYPE (lhs));
> int_range<2> rhs_range (TREE_TYPE (rhs));
> @@ -646,7 +646,7 @@ evaluate_control_stmt_using_entry_checks (gimple *stmt,
> TREE_OPERAND (last_predicate->condition, 1)))
> return true_edge ? boolean_true_node : boolean_false_node;
> /* Else try ranger if it supports LHS. */
> - else if (irange::supports_type_p (TREE_TYPE (lhs)))
> + else if (irange::supports_p (TREE_TYPE (lhs)))
> {
> int_range<2> r;
> int_range_max path_range;
> diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc
> index 931aa7479bb..a70aebd10a7 100644
> --- a/gcc/tree-ssa-threadedge.cc
> +++ b/gcc/tree-ssa-threadedge.cc
> @@ -1452,7 +1452,7 @@ hybrid_jt_simplifier::compute_ranges_from_state (gimple *stmt, jt_state *state)
> tree op = gimple_op (stmt, i);
> if (op
> && TREE_CODE (op) == SSA_NAME
> - && irange::supports_type_p (TREE_TYPE (op)))
> + && Value_Range::supports_type_p (TREE_TYPE (op)))
> bitmap_set_bit (imports, SSA_NAME_VERSION (op));
> }
> }
> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
> index 74277617b66..30022dac108 100644
> --- a/gcc/tree-vrp.cc
> +++ b/gcc/tree-vrp.cc
> @@ -932,8 +932,8 @@ supported_types_p (value_range *vr,
> tree type0,
> tree type1 = NULL)
> {
> - if (!value_range::supports_type_p (type0)
> - || (type1 && !value_range::supports_type_p (type1)))
> + if (!value_range_equiv::supports_p (type0)
> + || (type1 && !value_range_equiv::supports_p (type1)))
> {
> vr->set_varying (type0);
> return false;
> diff --git a/gcc/value-query.cc b/gcc/value-query.cc
> index e40e358ebd4..1d7541ce34f 100644
> --- a/gcc/value-query.cc
> +++ b/gcc/value-query.cc
> @@ -80,7 +80,7 @@ range_query::value_of_expr (tree expr, gimple *stmt)
> {
> tree t;
>
> - if (!vrange::supports_type_p (TREE_TYPE (expr)))
> + if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
> return NULL_TREE;
>
> Value_Range r (TREE_TYPE (expr));
> @@ -102,7 +102,7 @@ range_query::value_on_edge (edge e, tree expr)
> {
> tree t;
>
> - if (!vrange::supports_type_p (TREE_TYPE (expr)))
> + if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
> return NULL_TREE;
> Value_Range r (TREE_TYPE (expr));
> if (range_on_edge (r, e, expr))
> @@ -128,7 +128,7 @@ range_query::value_of_stmt (gimple *stmt, tree name)
>
> gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
>
> - if (!name || !vrange::supports_type_p (TREE_TYPE (name)))
> + if (!name || !Value_Range::supports_type_p (TREE_TYPE (name)))
> return NULL_TREE;
> Value_Range r (TREE_TYPE (name));
> if (range_of_stmt (r, stmt, name) && r.singleton_p (&t))
> @@ -196,7 +196,7 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
> else
> type = TREE_TYPE (expr);
>
> - if (!vrange::supports_type_p (type))
> + if (!Value_Range::supports_type_p (type))
> {
> r.set_undefined ();
> return false;
> @@ -252,7 +252,7 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
> {
> range_op_handler op (TREE_CODE (expr), type);
> tree op0_type = TREE_TYPE (TREE_OPERAND (expr, 0));
> - if (op && vrange::supports_type_p (op0_type))
> + if (op && Value_Range::supports_type_p (op0_type))
> {
> Value_Range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
> Value_Range r1 (type);
> @@ -387,7 +387,7 @@ get_range_global (vrange &r, tree name)
> }
> else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
> {
> - gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
> + gcc_checking_assert (irange::supports_p (TREE_TYPE (name)));
> get_ssa_name_range_info (as_a <irange> (r), name);
> if (r.undefined_p ())
> r.set_varying (type);
> @@ -441,9 +441,7 @@ global_range_query global_ranges;
> bool
> global_range_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
> {
> - tree type = TREE_TYPE (expr);
> -
> - if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr))
> + if (!gimple_range_ssa_p (expr))
> return get_tree_range (r, expr, stmt);
>
> get_range_global (r, expr);
> diff --git a/gcc/value-range-equiv.h b/gcc/value-range-equiv.h
> index 743ceb2b227..0a52d1372a1 100644
> --- a/gcc/value-range-equiv.h
> +++ b/gcc/value-range-equiv.h
> @@ -67,6 +67,10 @@ class GTY((user)) value_range_equiv : public value_range
> void deep_copy (const value_range_equiv *);
> void dump (FILE *) const;
> void dump () const;
> + static bool supports_p (tree type)
> + {
> + return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
> + }
>
> private:
> /* Deep-copies bitmap argument. */
> diff --git a/gcc/value-range.cc b/gcc/value-range.cc
> index 429672737a8..c4bcb970094 100644
> --- a/gcc/value-range.cc
> +++ b/gcc/value-range.cc
> @@ -107,6 +107,12 @@ vrange::operator== (const vrange &src) const
> gcc_unreachable ();
> }
>
> +bool
> +irange::supports_type_p (tree type) const
> +{
> + return supports_p (type);
> +}
> +
> // Return TRUE if R fits in THIS.
>
> bool
> @@ -140,6 +146,12 @@ unsupported_range::type () const
> return nullptr;
> }
>
> +bool
> +unsupported_range::supports_type_p (tree) const
> +{
> + return false;
> +}
> +
> void
> unsupported_range::set_undefined ()
> {
> diff --git a/gcc/value-range.h b/gcc/value-range.h
> index 5cd0e0ef76a..69cf6c304d6 100644
> --- a/gcc/value-range.h
> +++ b/gcc/value-range.h
> @@ -50,6 +50,23 @@ enum value_range_discriminator
> };
>
> // Abstract class for ranges of any of the supported types.
> +//
> +// To query what types ranger and the entire ecosystem can support,
> +// use Value_Range::supports_type_p(tree type). This is a static
> +// method available independently of any vrange object.
> +//
> +// To query what a given vrange variant can support, use:
> +// irange::supports_p ()
> +// frange::supports_p ()
> +// etc
> +//
> +// To query what a range object can support, use:
> +// void foo (vrange &v, irange &i, frange &f)
> +// {
> +// if (v.supports_type_p (type)) ...
> +// if (i.supports_type_p (type)) ...
> +// if (f.supports_type_p (type)) ...
> +// }
>
> class vrange
> {
> @@ -58,6 +75,7 @@ class vrange
> public:
> virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
> virtual tree type () const = 0;
> + virtual bool supports_type_p (tree type) const = 0;
> virtual void set_varying (tree type) = 0;
> virtual void set_undefined () = 0;
> virtual void dump (FILE * = stderr) const = 0;
> @@ -72,8 +90,6 @@ public:
> virtual void set_nonnegative (tree type) = 0;
> virtual bool fits_p (const vrange &r) const = 0;
>
> - static bool supports_type_p (tree);
> -
> bool varying_p () const;
> bool undefined_p () const;
> vrange& operator= (const vrange &);
> @@ -103,7 +119,8 @@ public:
> virtual void set_undefined () override;
>
> // Range types.
> - static bool supports_type_p (tree);
> + static bool supports_p (tree type);
> + virtual bool supports_type_p (tree type) const override;
> virtual tree type () const override;
>
> // Iteration over sub-ranges.
> @@ -228,6 +245,7 @@ public:
> unsupported_range ();
> virtual void set (tree, tree, value_range_kind) override;
> virtual tree type () const override;
> + virtual bool supports_type_p (tree type) const override;
> virtual void set_varying (tree type) override;
> virtual void set_undefined () override;
> virtual void dump (FILE *) const override;
> @@ -331,6 +349,7 @@ public:
> operator vrange &();
> operator const vrange &() const;
> void dump (FILE *out = stderr) const;
> + static bool supports_type_p (tree type);
>
> // Convenience methods for vrange compatability.
> void set (tree min, tree max, value_range_kind kind = VR_RANGE)
> @@ -387,7 +406,7 @@ Value_Range::init (tree type)
> {
> gcc_checking_assert (TYPE_P (type));
>
> - if (irange::supports_type_p (type))
> + if (irange::supports_p (type))
> m_vrange = &m_irange;
> else
> m_vrange = &m_unsupported;
> @@ -444,6 +463,14 @@ Value_Range::operator const vrange &() const
> return *m_vrange;
> }
>
> +// Return TRUE if TYPE is supported by the vrange infrastructure.
> +
> +inline bool
> +Value_Range::supports_type_p (tree type)
> +{
> + return irange::supports_p (type);
> +}
> +
> // Returns true for an old-school value_range as described above.
> inline bool
> irange::legacy_mode_p () const
> @@ -580,7 +607,7 @@ irange::nonzero_p () const
> }
>
> inline bool
> -irange::supports_type_p (tree type)
> +irange::supports_p (tree type)
> {
> return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
> }
> @@ -864,12 +891,6 @@ irange::normalize_kind ()
> }
> }
>
> -inline bool
> -vrange::supports_type_p (tree type)
> -{
> - return irange::supports_type_p (type);
> -}
> -
> // Return the maximum value for TYPE.
>
> inline tree
> @@ -944,7 +965,7 @@ vrange_allocator::alloc (unsigned bytes)
> inline vrange *
> vrange_allocator::alloc_vrange (tree type)
> {
> - if (irange::supports_type_p (type))
> + if (irange::supports_p (type))
> return alloc_irange (2);
>
> gcc_unreachable ();
> --
> 2.36.1
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [COMMITTED] Implement vrange::supports_type_p.
2022-06-13 9:43 ` Richard Biener
@ 2022-06-27 19:00 ` Aldy Hernandez
2022-06-28 7:36 ` Richard Biener
0 siblings, 1 reply; 6+ messages in thread
From: Aldy Hernandez @ 2022-06-27 19:00 UTC (permalink / raw)
To: Richard Biener; +Cc: GCC patches, Martin Liska, Andrew MacLeod
[-- Attachment #1: Type: text/plain, Size: 23267 bytes --]
The conversion for loop-ch is trivial, since the range of a
GIMPLE_COND is always an integer.
OK for trunk?
p.s. The loop unswitch code requires a bit more thought, since there
are numerous range temporaries in the code that are not necessarily
integers.
On Mon, Jun 13, 2022 at 11:44 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Fri, Jun 3, 2022 at 9:31 AM Aldy Hernandez <aldyh@redhat.com> wrote:
> >
> > [I have conservatively assumed that both the loop-ch and loop-unswitch
> > passes, which also use the ranger, only support integers and pointers.
> > If the goal is to handle other types as well, irange::supports_p()
> > should be Value_Range::supports_type_p(), and any uses of
> > int_range_max should be converted to Value_Range. I can help in the
> > conversion if you'd like.]
>
> Both should also support float ranges, so yes - if you can send simple
> patches I'll review them.
>
> > As discussed, this patch disambiguates the use of supports_type_p
> > throughout, as what ranger supports is a totally different question
> > than what a given range variant (irange, frange, etc) supports.
> >
> > Unfortunately we need both a static method and a virtual method, and
> > they can't be named the same. The uses are documented in the vrange
> > class:
> >
> > +// To query what types ranger and the entire ecosystem can support,
> > +// use Value_Range::supports_type_p(tree type). This is a static
> > +// method available independently of any vrange object.
> > +//
> > +// To query what a given vrange variant can support, use:
> > +// irange::supports_p ()
> > +// frange::supports_p ()
> > +// etc
> > +//
> > +// To query what a range object can support, use:
> > +// void foo (vrange &v, irange &i, frange &f)
> > +// {
> > +// if (v.supports_type_p (type)) ...
> > +// if (i.supports_type_p (type)) ...
> > +// if (f.supports_type_p (type)) ...
> > +// }
> >
> > The value_range_equiv::supports_p() method can be use to determine
> > what legacy VRP supports, as irange::supports_p() will no longer be
> > applicable in the evrp analyzer code base once irange and prange are
> > split.
> >
> > Tested on x86-64 Linux.
> >
> > gcc/ChangeLog:
> >
> > * gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Adjust for
> > an object level supports_type_p for irange and a static
> > Value_Range::supports_type_p.
> > * gimple-range-fold.cc (fold_using_range::range_of_range_op): Same.
> > (fold_using_range::range_of_address): Same.
> > (fold_using_range::range_of_builtin_call): Same.
> > * gimple-range-fold.h (gimple_range_type): Same.
> > (gimple_range_ssa_p): Same.
> > * gimple-range-path.cc (path_range_query::internal_range_of_expr):
> > Same.
> > (path_range_query::range_of_stmt): Same.
> > (path_range_query::add_to_imports): Same.
> > * gimple-range.cc (gimple_ranger::range_on_edge): Same.
> > (gimple_ranger::export_global_ranges): Same.
> > * gimple-ssa-evrp-analyze.cc
> > (evrp_range_analyzer::record_ranges_from_phis): Same.
> > * range-op.cc (range_operator::wi_fold): Same.
> > (range_operator::fold_range): Same.
> > * tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Same.
> > * tree-ssa-loop-unswitch.cc (struct unswitch_predicate): Same.
> > (evaluate_control_stmt_using_entry_checks): Same.
> > * tree-ssa-threadedge.cc
> > (hybrid_jt_simplifier::compute_ranges_from_state): Same.
> > * tree-vrp.cc (supported_types_p): Same.
> > * value-query.cc (range_query::value_of_expr): Same.
> > (range_query::value_on_edge): Same.
> > (range_query::value_of_stmt): Same.
> > (range_query::get_tree_range): Same.
> > (get_range_global): Same.
> > (global_range_query::range_of_expr): Same.
> > * value-range-equiv.h (class value_range_equiv): Same.
> > * value-range.cc (irange::supports_type_p): Same.
> > (unsupported_range::supports_type_p): Same.
> > * value-range.h (enum value_range_discriminator): Same.
> > (Value_Range::init): Same.
> > (Value_Range::supports_type_p): Same.
> > (irange::supports_type_p): Same.
> > (irange::supports_p): Same.
> > (vrange::supports_type_p): Same.
> > (vrange_allocator::alloc_vrange): Same.
> > ---
> > gcc/gimple-range-edge.cc | 3 +--
> > gcc/gimple-range-fold.cc | 5 ++--
> > gcc/gimple-range-fold.h | 4 +--
> > gcc/gimple-range-path.cc | 6 ++---
> > gcc/gimple-range.cc | 4 +--
> > gcc/gimple-ssa-evrp-analyze.cc | 2 +-
> > gcc/range-op.cc | 4 +--
> > gcc/tree-ssa-loop-ch.cc | 2 +-
> > gcc/tree-ssa-loop-unswitch.cc | 6 ++---
> > gcc/tree-ssa-threadedge.cc | 2 +-
> > gcc/tree-vrp.cc | 4 +--
> > gcc/value-query.cc | 16 ++++++------
> > gcc/value-range-equiv.h | 4 +++
> > gcc/value-range.cc | 12 +++++++++
> > gcc/value-range.h | 45 +++++++++++++++++++++++++---------
> > 15 files changed, 76 insertions(+), 43 deletions(-)
> >
> > diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
> > index 6fe33408f7e..03a804ac2be 100644
> > --- a/gcc/gimple-range-edge.cc
> > +++ b/gcc/gimple-range-edge.cc
> > @@ -44,8 +44,7 @@ gimple_outgoing_range_stmt_p (basic_block bb)
> > gimple *s = gsi_stmt (gsi);
> > if (is_a<gcond *> (s) && range_op_handler (s))
> > return gsi_stmt (gsi);
> > - gswitch *sw = dyn_cast<gswitch *> (s);
> > - if (sw && irange::supports_type_p (TREE_TYPE (gimple_switch_index (sw))))
> > + if (is_a <gswitch *> (s))
> > return gsi_stmt (gsi);
> > }
> > return NULL;
> > diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
> > index c1a801668c4..2a8c66e0c05 100644
> > --- a/gcc/gimple-range-fold.cc
> > +++ b/gcc/gimple-range-fold.cc
> > @@ -632,7 +632,7 @@ fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
> > }
> > // Fold range, and register any dependency if available.
> > handler.fold_range (r, type, range1, range2, rel);
> > - if (irange::supports_type_p (type))
> > + if (irange::supports_p (type))
> > relation_fold_and_or (as_a <irange> (r), s, src);
> > if (lhs)
> > {
> > @@ -709,7 +709,6 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
> > tree lhs = gimple_get_lhs (stmt);
> > if (lhs && gimple_range_ssa_p (ssa) && src.gori ())
> > src.gori ()->register_dependency (lhs, ssa);
> > - gcc_checking_assert (irange::supports_type_p (TREE_TYPE (ssa)));
> > src.get_operand (r, ssa);
> > range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt)));
> >
> > @@ -985,7 +984,7 @@ fold_using_range::range_of_builtin_call (vrange &r, gcall *call,
> > tree type = gimple_range_type (call);
> > gcc_checking_assert (type);
> >
> > - if (irange::supports_type_p (type))
> > + if (irange::supports_p (type))
> > return range_of_builtin_int_call (as_a <irange> (r), call, src);
> >
> > return false;
> > diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
> > index df24280ee40..fbf66275f74 100644
> > --- a/gcc/gimple-range-fold.h
> > +++ b/gcc/gimple-range-fold.h
> > @@ -66,7 +66,7 @@ gimple_range_type (const gimple *s)
> > type = TREE_TYPE (type);
> > }
> > }
> > - if (type && vrange::supports_type_p (type))
> > + if (type && Value_Range::supports_type_p (type))
> > return type;
> > return NULL_TREE;
> > }
> > @@ -79,7 +79,7 @@ gimple_range_ssa_p (tree exp)
> > if (exp && TREE_CODE (exp) == SSA_NAME &&
> > !SSA_NAME_IS_VIRTUAL_OPERAND (exp) &&
> > !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp) &&
> > - vrange::supports_type_p (TREE_TYPE (exp)))
> > + Value_Range::supports_type_p (TREE_TYPE (exp)))
> > return exp;
> > return NULL_TREE;
> > }
> > diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
> > index f8ae6fb9ffb..e1b9683c1e4 100644
> > --- a/gcc/gimple-range-path.cc
> > +++ b/gcc/gimple-range-path.cc
> > @@ -192,7 +192,7 @@ path_range_query::range_on_path_entry (vrange &r, tree name)
> > bool
> > path_range_query::internal_range_of_expr (vrange &r, tree name, gimple *stmt)
> > {
> > - if (!vrange::supports_type_p (TREE_TYPE (name)))
> > + if (!r.supports_type_p (TREE_TYPE (name)))
> > return false;
> >
> > if (get_cache (r, name))
> > @@ -548,7 +548,7 @@ bool
> > path_range_query::add_to_imports (tree name, bitmap imports)
> > {
> > if (TREE_CODE (name) == SSA_NAME
> > - && vrange::supports_type_p (TREE_TYPE (name)))
> > + && Value_Range::supports_type_p (TREE_TYPE (name)))
> > return bitmap_set_bit (imports, SSA_NAME_VERSION (name));
> > return false;
> > }
> > @@ -764,7 +764,7 @@ path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree)
> > {
> > tree type = gimple_range_type (stmt);
> >
> > - if (!type || !vrange::supports_type_p (type))
> > + if (!type || !r.supports_type_p (type))
> > return false;
> >
> > // If resolving unknowns, fold the statement making use of any
> > diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
> > index 12da16841c2..67dafb2a2c0 100644
> > --- a/gcc/gimple-range.cc
> > +++ b/gcc/gimple-range.cc
> > @@ -201,7 +201,7 @@ bool
> > gimple_ranger::range_on_edge (vrange &r, edge e, tree name)
> > {
> > Value_Range edge_range (TREE_TYPE (name));
> > - gcc_checking_assert (vrange::supports_type_p (TREE_TYPE (name)));
> > + gcc_checking_assert (r.supports_type_p (TREE_TYPE (name)));
> >
> > // Do not process values along abnormal edges.
> > if (e->flags & EDGE_ABNORMAL)
> > @@ -514,7 +514,7 @@ gimple_ranger::export_global_ranges ()
> > print_header = false;
> > }
> >
> > - if (!irange::supports_type_p (TREE_TYPE (name)))
> > + if (!irange::supports_p (TREE_TYPE (name)))
> > continue;
> >
> > vrange &v = r;
> > diff --git a/gcc/gimple-ssa-evrp-analyze.cc b/gcc/gimple-ssa-evrp-analyze.cc
> > index 16e5a75b1db..82142db7976 100644
> > --- a/gcc/gimple-ssa-evrp-analyze.cc
> > +++ b/gcc/gimple-ssa-evrp-analyze.cc
> > @@ -255,7 +255,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
> >
> > /* Skips floats and other things we can't represent in a
> > range. */
> > - if (!value_range::supports_type_p (TREE_TYPE (lhs)))
> > + if (!value_range_equiv::supports_p (TREE_TYPE (lhs)))
> > continue;
> >
> > value_range_equiv vr_result;
> > diff --git a/gcc/range-op.cc b/gcc/range-op.cc
> > index 028b4b7237c..5150c6021b8 100644
> > --- a/gcc/range-op.cc
> > +++ b/gcc/range-op.cc
> > @@ -111,7 +111,7 @@ range_operator::wi_fold (irange &r, tree type,
> > const wide_int &rh_lb ATTRIBUTE_UNUSED,
> > const wide_int &rh_ub ATTRIBUTE_UNUSED) const
> > {
> > - gcc_checking_assert (irange::supports_type_p (type));
> > + gcc_checking_assert (r.supports_type_p (type));
> > r.set_varying (type);
> > }
> >
> > @@ -181,7 +181,7 @@ range_operator::fold_range (irange &r, tree type,
> > const irange &rh,
> > relation_kind rel) const
> > {
> > - gcc_checking_assert (irange::supports_type_p (type));
> > + gcc_checking_assert (r.supports_type_p (type));
> > if (empty_range_varying (r, type, lh, rh))
> > return true;
> >
> > diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
> > index 2f5a390404c..26d96c0c21a 100644
> > --- a/gcc/tree-ssa-loop-ch.cc
> > +++ b/gcc/tree-ssa-loop-ch.cc
> > @@ -55,7 +55,7 @@ entry_loop_condition_is_static (class loop *l, path_range_query *query)
> > gcond *last = safe_dyn_cast <gcond *> (last_stmt (e->dest));
> >
> > if (!last
> > - || !irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (last))))
> > + || !irange::supports_p (TREE_TYPE (gimple_cond_lhs (last))))
> > return false;
> >
> > edge true_e, false_e;
> > diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
> > index ad1d05ccdff..95ccc0b7b47 100644
> > --- a/gcc/tree-ssa-loop-unswitch.cc
> > +++ b/gcc/tree-ssa-loop-unswitch.cc
> > @@ -113,7 +113,7 @@ struct unswitch_predicate
> > true_range (edge_range), edge_index (edge_index_), switch_p (true)
> > {
> > gcc_assert (!(e->flags & (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE))
> > - && irange::supports_type_p (TREE_TYPE (lhs)));
> > + && irange::supports_p (TREE_TYPE (lhs)));
> > false_range = true_range;
> > if (!false_range.varying_p ()
> > && !false_range.undefined_p ())
> > @@ -134,7 +134,7 @@ struct unswitch_predicate
> > tree rhs = gimple_cond_rhs (stmt);
> > enum tree_code code = gimple_cond_code (stmt);
> > condition = build2 (code, boolean_type_node, lhs, rhs);
> > - if (irange::supports_type_p (TREE_TYPE (lhs)))
> > + if (irange::supports_p (TREE_TYPE (lhs)))
> > {
> > auto range_op = range_op_handler (code, TREE_TYPE (lhs));
> > int_range<2> rhs_range (TREE_TYPE (rhs));
> > @@ -646,7 +646,7 @@ evaluate_control_stmt_using_entry_checks (gimple *stmt,
> > TREE_OPERAND (last_predicate->condition, 1)))
> > return true_edge ? boolean_true_node : boolean_false_node;
> > /* Else try ranger if it supports LHS. */
> > - else if (irange::supports_type_p (TREE_TYPE (lhs)))
> > + else if (irange::supports_p (TREE_TYPE (lhs)))
> > {
> > int_range<2> r;
> > int_range_max path_range;
> > diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc
> > index 931aa7479bb..a70aebd10a7 100644
> > --- a/gcc/tree-ssa-threadedge.cc
> > +++ b/gcc/tree-ssa-threadedge.cc
> > @@ -1452,7 +1452,7 @@ hybrid_jt_simplifier::compute_ranges_from_state (gimple *stmt, jt_state *state)
> > tree op = gimple_op (stmt, i);
> > if (op
> > && TREE_CODE (op) == SSA_NAME
> > - && irange::supports_type_p (TREE_TYPE (op)))
> > + && Value_Range::supports_type_p (TREE_TYPE (op)))
> > bitmap_set_bit (imports, SSA_NAME_VERSION (op));
> > }
> > }
> > diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
> > index 74277617b66..30022dac108 100644
> > --- a/gcc/tree-vrp.cc
> > +++ b/gcc/tree-vrp.cc
> > @@ -932,8 +932,8 @@ supported_types_p (value_range *vr,
> > tree type0,
> > tree type1 = NULL)
> > {
> > - if (!value_range::supports_type_p (type0)
> > - || (type1 && !value_range::supports_type_p (type1)))
> > + if (!value_range_equiv::supports_p (type0)
> > + || (type1 && !value_range_equiv::supports_p (type1)))
> > {
> > vr->set_varying (type0);
> > return false;
> > diff --git a/gcc/value-query.cc b/gcc/value-query.cc
> > index e40e358ebd4..1d7541ce34f 100644
> > --- a/gcc/value-query.cc
> > +++ b/gcc/value-query.cc
> > @@ -80,7 +80,7 @@ range_query::value_of_expr (tree expr, gimple *stmt)
> > {
> > tree t;
> >
> > - if (!vrange::supports_type_p (TREE_TYPE (expr)))
> > + if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
> > return NULL_TREE;
> >
> > Value_Range r (TREE_TYPE (expr));
> > @@ -102,7 +102,7 @@ range_query::value_on_edge (edge e, tree expr)
> > {
> > tree t;
> >
> > - if (!vrange::supports_type_p (TREE_TYPE (expr)))
> > + if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
> > return NULL_TREE;
> > Value_Range r (TREE_TYPE (expr));
> > if (range_on_edge (r, e, expr))
> > @@ -128,7 +128,7 @@ range_query::value_of_stmt (gimple *stmt, tree name)
> >
> > gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
> >
> > - if (!name || !vrange::supports_type_p (TREE_TYPE (name)))
> > + if (!name || !Value_Range::supports_type_p (TREE_TYPE (name)))
> > return NULL_TREE;
> > Value_Range r (TREE_TYPE (name));
> > if (range_of_stmt (r, stmt, name) && r.singleton_p (&t))
> > @@ -196,7 +196,7 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
> > else
> > type = TREE_TYPE (expr);
> >
> > - if (!vrange::supports_type_p (type))
> > + if (!Value_Range::supports_type_p (type))
> > {
> > r.set_undefined ();
> > return false;
> > @@ -252,7 +252,7 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
> > {
> > range_op_handler op (TREE_CODE (expr), type);
> > tree op0_type = TREE_TYPE (TREE_OPERAND (expr, 0));
> > - if (op && vrange::supports_type_p (op0_type))
> > + if (op && Value_Range::supports_type_p (op0_type))
> > {
> > Value_Range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
> > Value_Range r1 (type);
> > @@ -387,7 +387,7 @@ get_range_global (vrange &r, tree name)
> > }
> > else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
> > {
> > - gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
> > + gcc_checking_assert (irange::supports_p (TREE_TYPE (name)));
> > get_ssa_name_range_info (as_a <irange> (r), name);
> > if (r.undefined_p ())
> > r.set_varying (type);
> > @@ -441,9 +441,7 @@ global_range_query global_ranges;
> > bool
> > global_range_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
> > {
> > - tree type = TREE_TYPE (expr);
> > -
> > - if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr))
> > + if (!gimple_range_ssa_p (expr))
> > return get_tree_range (r, expr, stmt);
> >
> > get_range_global (r, expr);
> > diff --git a/gcc/value-range-equiv.h b/gcc/value-range-equiv.h
> > index 743ceb2b227..0a52d1372a1 100644
> > --- a/gcc/value-range-equiv.h
> > +++ b/gcc/value-range-equiv.h
> > @@ -67,6 +67,10 @@ class GTY((user)) value_range_equiv : public value_range
> > void deep_copy (const value_range_equiv *);
> > void dump (FILE *) const;
> > void dump () const;
> > + static bool supports_p (tree type)
> > + {
> > + return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
> > + }
> >
> > private:
> > /* Deep-copies bitmap argument. */
> > diff --git a/gcc/value-range.cc b/gcc/value-range.cc
> > index 429672737a8..c4bcb970094 100644
> > --- a/gcc/value-range.cc
> > +++ b/gcc/value-range.cc
> > @@ -107,6 +107,12 @@ vrange::operator== (const vrange &src) const
> > gcc_unreachable ();
> > }
> >
> > +bool
> > +irange::supports_type_p (tree type) const
> > +{
> > + return supports_p (type);
> > +}
> > +
> > // Return TRUE if R fits in THIS.
> >
> > bool
> > @@ -140,6 +146,12 @@ unsupported_range::type () const
> > return nullptr;
> > }
> >
> > +bool
> > +unsupported_range::supports_type_p (tree) const
> > +{
> > + return false;
> > +}
> > +
> > void
> > unsupported_range::set_undefined ()
> > {
> > diff --git a/gcc/value-range.h b/gcc/value-range.h
> > index 5cd0e0ef76a..69cf6c304d6 100644
> > --- a/gcc/value-range.h
> > +++ b/gcc/value-range.h
> > @@ -50,6 +50,23 @@ enum value_range_discriminator
> > };
> >
> > // Abstract class for ranges of any of the supported types.
> > +//
> > +// To query what types ranger and the entire ecosystem can support,
> > +// use Value_Range::supports_type_p(tree type). This is a static
> > +// method available independently of any vrange object.
> > +//
> > +// To query what a given vrange variant can support, use:
> > +// irange::supports_p ()
> > +// frange::supports_p ()
> > +// etc
> > +//
> > +// To query what a range object can support, use:
> > +// void foo (vrange &v, irange &i, frange &f)
> > +// {
> > +// if (v.supports_type_p (type)) ...
> > +// if (i.supports_type_p (type)) ...
> > +// if (f.supports_type_p (type)) ...
> > +// }
> >
> > class vrange
> > {
> > @@ -58,6 +75,7 @@ class vrange
> > public:
> > virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
> > virtual tree type () const = 0;
> > + virtual bool supports_type_p (tree type) const = 0;
> > virtual void set_varying (tree type) = 0;
> > virtual void set_undefined () = 0;
> > virtual void dump (FILE * = stderr) const = 0;
> > @@ -72,8 +90,6 @@ public:
> > virtual void set_nonnegative (tree type) = 0;
> > virtual bool fits_p (const vrange &r) const = 0;
> >
> > - static bool supports_type_p (tree);
> > -
> > bool varying_p () const;
> > bool undefined_p () const;
> > vrange& operator= (const vrange &);
> > @@ -103,7 +119,8 @@ public:
> > virtual void set_undefined () override;
> >
> > // Range types.
> > - static bool supports_type_p (tree);
> > + static bool supports_p (tree type);
> > + virtual bool supports_type_p (tree type) const override;
> > virtual tree type () const override;
> >
> > // Iteration over sub-ranges.
> > @@ -228,6 +245,7 @@ public:
> > unsupported_range ();
> > virtual void set (tree, tree, value_range_kind) override;
> > virtual tree type () const override;
> > + virtual bool supports_type_p (tree type) const override;
> > virtual void set_varying (tree type) override;
> > virtual void set_undefined () override;
> > virtual void dump (FILE *) const override;
> > @@ -331,6 +349,7 @@ public:
> > operator vrange &();
> > operator const vrange &() const;
> > void dump (FILE *out = stderr) const;
> > + static bool supports_type_p (tree type);
> >
> > // Convenience methods for vrange compatability.
> > void set (tree min, tree max, value_range_kind kind = VR_RANGE)
> > @@ -387,7 +406,7 @@ Value_Range::init (tree type)
> > {
> > gcc_checking_assert (TYPE_P (type));
> >
> > - if (irange::supports_type_p (type))
> > + if (irange::supports_p (type))
> > m_vrange = &m_irange;
> > else
> > m_vrange = &m_unsupported;
> > @@ -444,6 +463,14 @@ Value_Range::operator const vrange &() const
> > return *m_vrange;
> > }
> >
> > +// Return TRUE if TYPE is supported by the vrange infrastructure.
> > +
> > +inline bool
> > +Value_Range::supports_type_p (tree type)
> > +{
> > + return irange::supports_p (type);
> > +}
> > +
> > // Returns true for an old-school value_range as described above.
> > inline bool
> > irange::legacy_mode_p () const
> > @@ -580,7 +607,7 @@ irange::nonzero_p () const
> > }
> >
> > inline bool
> > -irange::supports_type_p (tree type)
> > +irange::supports_p (tree type)
> > {
> > return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
> > }
> > @@ -864,12 +891,6 @@ irange::normalize_kind ()
> > }
> > }
> >
> > -inline bool
> > -vrange::supports_type_p (tree type)
> > -{
> > - return irange::supports_type_p (type);
> > -}
> > -
> > // Return the maximum value for TYPE.
> >
> > inline tree
> > @@ -944,7 +965,7 @@ vrange_allocator::alloc (unsigned bytes)
> > inline vrange *
> > vrange_allocator::alloc_vrange (tree type)
> > {
> > - if (irange::supports_type_p (type))
> > + if (irange::supports_p (type))
> > return alloc_irange (2);
> >
> > gcc_unreachable ();
> > --
> > 2.36.1
> >
>
[-- Attachment #2: 0002-Allow-all-types-supported-by-ranger-in-loop-ch.patch --]
[-- Type: text/x-patch, Size: 1395 bytes --]
From fc0af537a184ec4ffc26c5516f7a978c38c4b0ab Mon Sep 17 00:00:00 2001
From: Aldy Hernandez <aldyh@redhat.com>
Date: Mon, 27 Jun 2022 20:50:03 +0200
Subject: [PATCH] Allow all types supported by ranger in loop-ch.
This converts the ranger use in loop-ch to allow any types allowed by
the ranger infrastructure. As per the documentation for class vrange,
the way to query this is with Value_Range::supports_type_p().
Since the range of a GIMPLE_COND is always an integer, no further
changes to loop-ch are necessary because its only temporary is already
an int_range (otherwise, we'd need to use Value_Range with the
appropriate type).
gcc/ChangeLog:
* tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Use
Value_Range::supports_type_p instead of irange::supports_p.
---
gcc/tree-ssa-loop-ch.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 26d96c0c21a..1cc38f3b889 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -55,7 +55,7 @@ entry_loop_condition_is_static (class loop *l, path_range_query *query)
gcond *last = safe_dyn_cast <gcond *> (last_stmt (e->dest));
if (!last
- || !irange::supports_p (TREE_TYPE (gimple_cond_lhs (last))))
+ || !Value_Range::supports_type_p (TREE_TYPE (gimple_cond_lhs (last))))
return false;
edge true_e, false_e;
--
2.36.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [COMMITTED] Implement vrange::supports_type_p.
2022-06-27 19:00 ` Aldy Hernandez
@ 2022-06-28 7:36 ` Richard Biener
2022-06-28 9:33 ` Aldy Hernandez
0 siblings, 1 reply; 6+ messages in thread
From: Richard Biener @ 2022-06-28 7:36 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: GCC patches, Martin Liska, Andrew MacLeod
On Mon, Jun 27, 2022 at 9:00 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>
> The conversion for loop-ch is trivial, since the range of a
> GIMPLE_COND is always an integer.
Yes - but doesn't this hint at the fact that the irange::supports_p is
useless because it checks on the type of the comparison operand
rather than the type of the comparison (boolean_type_node)?
So .. instead of replacing it, remove it?
Richard.
> OK for trunk?
>
> p.s. The loop unswitch code requires a bit more thought, since there
> are numerous range temporaries in the code that are not necessarily
> integers.
>
> On Mon, Jun 13, 2022 at 11:44 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Fri, Jun 3, 2022 at 9:31 AM Aldy Hernandez <aldyh@redhat.com> wrote:
> > >
> > > [I have conservatively assumed that both the loop-ch and loop-unswitch
> > > passes, which also use the ranger, only support integers and pointers.
> > > If the goal is to handle other types as well, irange::supports_p()
> > > should be Value_Range::supports_type_p(), and any uses of
> > > int_range_max should be converted to Value_Range. I can help in the
> > > conversion if you'd like.]
> >
> > Both should also support float ranges, so yes - if you can send simple
> > patches I'll review them.
> >
> > > As discussed, this patch disambiguates the use of supports_type_p
> > > throughout, as what ranger supports is a totally different question
> > > than what a given range variant (irange, frange, etc) supports.
> > >
> > > Unfortunately we need both a static method and a virtual method, and
> > > they can't be named the same. The uses are documented in the vrange
> > > class:
> > >
> > > +// To query what types ranger and the entire ecosystem can support,
> > > +// use Value_Range::supports_type_p(tree type). This is a static
> > > +// method available independently of any vrange object.
> > > +//
> > > +// To query what a given vrange variant can support, use:
> > > +// irange::supports_p ()
> > > +// frange::supports_p ()
> > > +// etc
> > > +//
> > > +// To query what a range object can support, use:
> > > +// void foo (vrange &v, irange &i, frange &f)
> > > +// {
> > > +// if (v.supports_type_p (type)) ...
> > > +// if (i.supports_type_p (type)) ...
> > > +// if (f.supports_type_p (type)) ...
> > > +// }
> > >
> > > The value_range_equiv::supports_p() method can be use to determine
> > > what legacy VRP supports, as irange::supports_p() will no longer be
> > > applicable in the evrp analyzer code base once irange and prange are
> > > split.
> > >
> > > Tested on x86-64 Linux.
> > >
> > > gcc/ChangeLog:
> > >
> > > * gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Adjust for
> > > an object level supports_type_p for irange and a static
> > > Value_Range::supports_type_p.
> > > * gimple-range-fold.cc (fold_using_range::range_of_range_op): Same.
> > > (fold_using_range::range_of_address): Same.
> > > (fold_using_range::range_of_builtin_call): Same.
> > > * gimple-range-fold.h (gimple_range_type): Same.
> > > (gimple_range_ssa_p): Same.
> > > * gimple-range-path.cc (path_range_query::internal_range_of_expr):
> > > Same.
> > > (path_range_query::range_of_stmt): Same.
> > > (path_range_query::add_to_imports): Same.
> > > * gimple-range.cc (gimple_ranger::range_on_edge): Same.
> > > (gimple_ranger::export_global_ranges): Same.
> > > * gimple-ssa-evrp-analyze.cc
> > > (evrp_range_analyzer::record_ranges_from_phis): Same.
> > > * range-op.cc (range_operator::wi_fold): Same.
> > > (range_operator::fold_range): Same.
> > > * tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Same.
> > > * tree-ssa-loop-unswitch.cc (struct unswitch_predicate): Same.
> > > (evaluate_control_stmt_using_entry_checks): Same.
> > > * tree-ssa-threadedge.cc
> > > (hybrid_jt_simplifier::compute_ranges_from_state): Same.
> > > * tree-vrp.cc (supported_types_p): Same.
> > > * value-query.cc (range_query::value_of_expr): Same.
> > > (range_query::value_on_edge): Same.
> > > (range_query::value_of_stmt): Same.
> > > (range_query::get_tree_range): Same.
> > > (get_range_global): Same.
> > > (global_range_query::range_of_expr): Same.
> > > * value-range-equiv.h (class value_range_equiv): Same.
> > > * value-range.cc (irange::supports_type_p): Same.
> > > (unsupported_range::supports_type_p): Same.
> > > * value-range.h (enum value_range_discriminator): Same.
> > > (Value_Range::init): Same.
> > > (Value_Range::supports_type_p): Same.
> > > (irange::supports_type_p): Same.
> > > (irange::supports_p): Same.
> > > (vrange::supports_type_p): Same.
> > > (vrange_allocator::alloc_vrange): Same.
> > > ---
> > > gcc/gimple-range-edge.cc | 3 +--
> > > gcc/gimple-range-fold.cc | 5 ++--
> > > gcc/gimple-range-fold.h | 4 +--
> > > gcc/gimple-range-path.cc | 6 ++---
> > > gcc/gimple-range.cc | 4 +--
> > > gcc/gimple-ssa-evrp-analyze.cc | 2 +-
> > > gcc/range-op.cc | 4 +--
> > > gcc/tree-ssa-loop-ch.cc | 2 +-
> > > gcc/tree-ssa-loop-unswitch.cc | 6 ++---
> > > gcc/tree-ssa-threadedge.cc | 2 +-
> > > gcc/tree-vrp.cc | 4 +--
> > > gcc/value-query.cc | 16 ++++++------
> > > gcc/value-range-equiv.h | 4 +++
> > > gcc/value-range.cc | 12 +++++++++
> > > gcc/value-range.h | 45 +++++++++++++++++++++++++---------
> > > 15 files changed, 76 insertions(+), 43 deletions(-)
> > >
> > > diff --git a/gcc/gimple-range-edge.cc b/gcc/gimple-range-edge.cc
> > > index 6fe33408f7e..03a804ac2be 100644
> > > --- a/gcc/gimple-range-edge.cc
> > > +++ b/gcc/gimple-range-edge.cc
> > > @@ -44,8 +44,7 @@ gimple_outgoing_range_stmt_p (basic_block bb)
> > > gimple *s = gsi_stmt (gsi);
> > > if (is_a<gcond *> (s) && range_op_handler (s))
> > > return gsi_stmt (gsi);
> > > - gswitch *sw = dyn_cast<gswitch *> (s);
> > > - if (sw && irange::supports_type_p (TREE_TYPE (gimple_switch_index (sw))))
> > > + if (is_a <gswitch *> (s))
> > > return gsi_stmt (gsi);
> > > }
> > > return NULL;
> > > diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
> > > index c1a801668c4..2a8c66e0c05 100644
> > > --- a/gcc/gimple-range-fold.cc
> > > +++ b/gcc/gimple-range-fold.cc
> > > @@ -632,7 +632,7 @@ fold_using_range::range_of_range_op (vrange &r, gimple *s, fur_source &src)
> > > }
> > > // Fold range, and register any dependency if available.
> > > handler.fold_range (r, type, range1, range2, rel);
> > > - if (irange::supports_type_p (type))
> > > + if (irange::supports_p (type))
> > > relation_fold_and_or (as_a <irange> (r), s, src);
> > > if (lhs)
> > > {
> > > @@ -709,7 +709,6 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src)
> > > tree lhs = gimple_get_lhs (stmt);
> > > if (lhs && gimple_range_ssa_p (ssa) && src.gori ())
> > > src.gori ()->register_dependency (lhs, ssa);
> > > - gcc_checking_assert (irange::supports_type_p (TREE_TYPE (ssa)));
> > > src.get_operand (r, ssa);
> > > range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt)));
> > >
> > > @@ -985,7 +984,7 @@ fold_using_range::range_of_builtin_call (vrange &r, gcall *call,
> > > tree type = gimple_range_type (call);
> > > gcc_checking_assert (type);
> > >
> > > - if (irange::supports_type_p (type))
> > > + if (irange::supports_p (type))
> > > return range_of_builtin_int_call (as_a <irange> (r), call, src);
> > >
> > > return false;
> > > diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h
> > > index df24280ee40..fbf66275f74 100644
> > > --- a/gcc/gimple-range-fold.h
> > > +++ b/gcc/gimple-range-fold.h
> > > @@ -66,7 +66,7 @@ gimple_range_type (const gimple *s)
> > > type = TREE_TYPE (type);
> > > }
> > > }
> > > - if (type && vrange::supports_type_p (type))
> > > + if (type && Value_Range::supports_type_p (type))
> > > return type;
> > > return NULL_TREE;
> > > }
> > > @@ -79,7 +79,7 @@ gimple_range_ssa_p (tree exp)
> > > if (exp && TREE_CODE (exp) == SSA_NAME &&
> > > !SSA_NAME_IS_VIRTUAL_OPERAND (exp) &&
> > > !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp) &&
> > > - vrange::supports_type_p (TREE_TYPE (exp)))
> > > + Value_Range::supports_type_p (TREE_TYPE (exp)))
> > > return exp;
> > > return NULL_TREE;
> > > }
> > > diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc
> > > index f8ae6fb9ffb..e1b9683c1e4 100644
> > > --- a/gcc/gimple-range-path.cc
> > > +++ b/gcc/gimple-range-path.cc
> > > @@ -192,7 +192,7 @@ path_range_query::range_on_path_entry (vrange &r, tree name)
> > > bool
> > > path_range_query::internal_range_of_expr (vrange &r, tree name, gimple *stmt)
> > > {
> > > - if (!vrange::supports_type_p (TREE_TYPE (name)))
> > > + if (!r.supports_type_p (TREE_TYPE (name)))
> > > return false;
> > >
> > > if (get_cache (r, name))
> > > @@ -548,7 +548,7 @@ bool
> > > path_range_query::add_to_imports (tree name, bitmap imports)
> > > {
> > > if (TREE_CODE (name) == SSA_NAME
> > > - && vrange::supports_type_p (TREE_TYPE (name)))
> > > + && Value_Range::supports_type_p (TREE_TYPE (name)))
> > > return bitmap_set_bit (imports, SSA_NAME_VERSION (name));
> > > return false;
> > > }
> > > @@ -764,7 +764,7 @@ path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree)
> > > {
> > > tree type = gimple_range_type (stmt);
> > >
> > > - if (!type || !vrange::supports_type_p (type))
> > > + if (!type || !r.supports_type_p (type))
> > > return false;
> > >
> > > // If resolving unknowns, fold the statement making use of any
> > > diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
> > > index 12da16841c2..67dafb2a2c0 100644
> > > --- a/gcc/gimple-range.cc
> > > +++ b/gcc/gimple-range.cc
> > > @@ -201,7 +201,7 @@ bool
> > > gimple_ranger::range_on_edge (vrange &r, edge e, tree name)
> > > {
> > > Value_Range edge_range (TREE_TYPE (name));
> > > - gcc_checking_assert (vrange::supports_type_p (TREE_TYPE (name)));
> > > + gcc_checking_assert (r.supports_type_p (TREE_TYPE (name)));
> > >
> > > // Do not process values along abnormal edges.
> > > if (e->flags & EDGE_ABNORMAL)
> > > @@ -514,7 +514,7 @@ gimple_ranger::export_global_ranges ()
> > > print_header = false;
> > > }
> > >
> > > - if (!irange::supports_type_p (TREE_TYPE (name)))
> > > + if (!irange::supports_p (TREE_TYPE (name)))
> > > continue;
> > >
> > > vrange &v = r;
> > > diff --git a/gcc/gimple-ssa-evrp-analyze.cc b/gcc/gimple-ssa-evrp-analyze.cc
> > > index 16e5a75b1db..82142db7976 100644
> > > --- a/gcc/gimple-ssa-evrp-analyze.cc
> > > +++ b/gcc/gimple-ssa-evrp-analyze.cc
> > > @@ -255,7 +255,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
> > >
> > > /* Skips floats and other things we can't represent in a
> > > range. */
> > > - if (!value_range::supports_type_p (TREE_TYPE (lhs)))
> > > + if (!value_range_equiv::supports_p (TREE_TYPE (lhs)))
> > > continue;
> > >
> > > value_range_equiv vr_result;
> > > diff --git a/gcc/range-op.cc b/gcc/range-op.cc
> > > index 028b4b7237c..5150c6021b8 100644
> > > --- a/gcc/range-op.cc
> > > +++ b/gcc/range-op.cc
> > > @@ -111,7 +111,7 @@ range_operator::wi_fold (irange &r, tree type,
> > > const wide_int &rh_lb ATTRIBUTE_UNUSED,
> > > const wide_int &rh_ub ATTRIBUTE_UNUSED) const
> > > {
> > > - gcc_checking_assert (irange::supports_type_p (type));
> > > + gcc_checking_assert (r.supports_type_p (type));
> > > r.set_varying (type);
> > > }
> > >
> > > @@ -181,7 +181,7 @@ range_operator::fold_range (irange &r, tree type,
> > > const irange &rh,
> > > relation_kind rel) const
> > > {
> > > - gcc_checking_assert (irange::supports_type_p (type));
> > > + gcc_checking_assert (r.supports_type_p (type));
> > > if (empty_range_varying (r, type, lh, rh))
> > > return true;
> > >
> > > diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
> > > index 2f5a390404c..26d96c0c21a 100644
> > > --- a/gcc/tree-ssa-loop-ch.cc
> > > +++ b/gcc/tree-ssa-loop-ch.cc
> > > @@ -55,7 +55,7 @@ entry_loop_condition_is_static (class loop *l, path_range_query *query)
> > > gcond *last = safe_dyn_cast <gcond *> (last_stmt (e->dest));
> > >
> > > if (!last
> > > - || !irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (last))))
> > > + || !irange::supports_p (TREE_TYPE (gimple_cond_lhs (last))))
> > > return false;
> > >
> > > edge true_e, false_e;
> > > diff --git a/gcc/tree-ssa-loop-unswitch.cc b/gcc/tree-ssa-loop-unswitch.cc
> > > index ad1d05ccdff..95ccc0b7b47 100644
> > > --- a/gcc/tree-ssa-loop-unswitch.cc
> > > +++ b/gcc/tree-ssa-loop-unswitch.cc
> > > @@ -113,7 +113,7 @@ struct unswitch_predicate
> > > true_range (edge_range), edge_index (edge_index_), switch_p (true)
> > > {
> > > gcc_assert (!(e->flags & (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE))
> > > - && irange::supports_type_p (TREE_TYPE (lhs)));
> > > + && irange::supports_p (TREE_TYPE (lhs)));
> > > false_range = true_range;
> > > if (!false_range.varying_p ()
> > > && !false_range.undefined_p ())
> > > @@ -134,7 +134,7 @@ struct unswitch_predicate
> > > tree rhs = gimple_cond_rhs (stmt);
> > > enum tree_code code = gimple_cond_code (stmt);
> > > condition = build2 (code, boolean_type_node, lhs, rhs);
> > > - if (irange::supports_type_p (TREE_TYPE (lhs)))
> > > + if (irange::supports_p (TREE_TYPE (lhs)))
> > > {
> > > auto range_op = range_op_handler (code, TREE_TYPE (lhs));
> > > int_range<2> rhs_range (TREE_TYPE (rhs));
> > > @@ -646,7 +646,7 @@ evaluate_control_stmt_using_entry_checks (gimple *stmt,
> > > TREE_OPERAND (last_predicate->condition, 1)))
> > > return true_edge ? boolean_true_node : boolean_false_node;
> > > /* Else try ranger if it supports LHS. */
> > > - else if (irange::supports_type_p (TREE_TYPE (lhs)))
> > > + else if (irange::supports_p (TREE_TYPE (lhs)))
> > > {
> > > int_range<2> r;
> > > int_range_max path_range;
> > > diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc
> > > index 931aa7479bb..a70aebd10a7 100644
> > > --- a/gcc/tree-ssa-threadedge.cc
> > > +++ b/gcc/tree-ssa-threadedge.cc
> > > @@ -1452,7 +1452,7 @@ hybrid_jt_simplifier::compute_ranges_from_state (gimple *stmt, jt_state *state)
> > > tree op = gimple_op (stmt, i);
> > > if (op
> > > && TREE_CODE (op) == SSA_NAME
> > > - && irange::supports_type_p (TREE_TYPE (op)))
> > > + && Value_Range::supports_type_p (TREE_TYPE (op)))
> > > bitmap_set_bit (imports, SSA_NAME_VERSION (op));
> > > }
> > > }
> > > diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
> > > index 74277617b66..30022dac108 100644
> > > --- a/gcc/tree-vrp.cc
> > > +++ b/gcc/tree-vrp.cc
> > > @@ -932,8 +932,8 @@ supported_types_p (value_range *vr,
> > > tree type0,
> > > tree type1 = NULL)
> > > {
> > > - if (!value_range::supports_type_p (type0)
> > > - || (type1 && !value_range::supports_type_p (type1)))
> > > + if (!value_range_equiv::supports_p (type0)
> > > + || (type1 && !value_range_equiv::supports_p (type1)))
> > > {
> > > vr->set_varying (type0);
> > > return false;
> > > diff --git a/gcc/value-query.cc b/gcc/value-query.cc
> > > index e40e358ebd4..1d7541ce34f 100644
> > > --- a/gcc/value-query.cc
> > > +++ b/gcc/value-query.cc
> > > @@ -80,7 +80,7 @@ range_query::value_of_expr (tree expr, gimple *stmt)
> > > {
> > > tree t;
> > >
> > > - if (!vrange::supports_type_p (TREE_TYPE (expr)))
> > > + if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
> > > return NULL_TREE;
> > >
> > > Value_Range r (TREE_TYPE (expr));
> > > @@ -102,7 +102,7 @@ range_query::value_on_edge (edge e, tree expr)
> > > {
> > > tree t;
> > >
> > > - if (!vrange::supports_type_p (TREE_TYPE (expr)))
> > > + if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
> > > return NULL_TREE;
> > > Value_Range r (TREE_TYPE (expr));
> > > if (range_on_edge (r, e, expr))
> > > @@ -128,7 +128,7 @@ range_query::value_of_stmt (gimple *stmt, tree name)
> > >
> > > gcc_checking_assert (!name || name == gimple_get_lhs (stmt));
> > >
> > > - if (!name || !vrange::supports_type_p (TREE_TYPE (name)))
> > > + if (!name || !Value_Range::supports_type_p (TREE_TYPE (name)))
> > > return NULL_TREE;
> > > Value_Range r (TREE_TYPE (name));
> > > if (range_of_stmt (r, stmt, name) && r.singleton_p (&t))
> > > @@ -196,7 +196,7 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
> > > else
> > > type = TREE_TYPE (expr);
> > >
> > > - if (!vrange::supports_type_p (type))
> > > + if (!Value_Range::supports_type_p (type))
> > > {
> > > r.set_undefined ();
> > > return false;
> > > @@ -252,7 +252,7 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
> > > {
> > > range_op_handler op (TREE_CODE (expr), type);
> > > tree op0_type = TREE_TYPE (TREE_OPERAND (expr, 0));
> > > - if (op && vrange::supports_type_p (op0_type))
> > > + if (op && Value_Range::supports_type_p (op0_type))
> > > {
> > > Value_Range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
> > > Value_Range r1 (type);
> > > @@ -387,7 +387,7 @@ get_range_global (vrange &r, tree name)
> > > }
> > > else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
> > > {
> > > - gcc_checking_assert (irange::supports_type_p (TREE_TYPE (name)));
> > > + gcc_checking_assert (irange::supports_p (TREE_TYPE (name)));
> > > get_ssa_name_range_info (as_a <irange> (r), name);
> > > if (r.undefined_p ())
> > > r.set_varying (type);
> > > @@ -441,9 +441,7 @@ global_range_query global_ranges;
> > > bool
> > > global_range_query::range_of_expr (vrange &r, tree expr, gimple *stmt)
> > > {
> > > - tree type = TREE_TYPE (expr);
> > > -
> > > - if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr))
> > > + if (!gimple_range_ssa_p (expr))
> > > return get_tree_range (r, expr, stmt);
> > >
> > > get_range_global (r, expr);
> > > diff --git a/gcc/value-range-equiv.h b/gcc/value-range-equiv.h
> > > index 743ceb2b227..0a52d1372a1 100644
> > > --- a/gcc/value-range-equiv.h
> > > +++ b/gcc/value-range-equiv.h
> > > @@ -67,6 +67,10 @@ class GTY((user)) value_range_equiv : public value_range
> > > void deep_copy (const value_range_equiv *);
> > > void dump (FILE *) const;
> > > void dump () const;
> > > + static bool supports_p (tree type)
> > > + {
> > > + return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
> > > + }
> > >
> > > private:
> > > /* Deep-copies bitmap argument. */
> > > diff --git a/gcc/value-range.cc b/gcc/value-range.cc
> > > index 429672737a8..c4bcb970094 100644
> > > --- a/gcc/value-range.cc
> > > +++ b/gcc/value-range.cc
> > > @@ -107,6 +107,12 @@ vrange::operator== (const vrange &src) const
> > > gcc_unreachable ();
> > > }
> > >
> > > +bool
> > > +irange::supports_type_p (tree type) const
> > > +{
> > > + return supports_p (type);
> > > +}
> > > +
> > > // Return TRUE if R fits in THIS.
> > >
> > > bool
> > > @@ -140,6 +146,12 @@ unsupported_range::type () const
> > > return nullptr;
> > > }
> > >
> > > +bool
> > > +unsupported_range::supports_type_p (tree) const
> > > +{
> > > + return false;
> > > +}
> > > +
> > > void
> > > unsupported_range::set_undefined ()
> > > {
> > > diff --git a/gcc/value-range.h b/gcc/value-range.h
> > > index 5cd0e0ef76a..69cf6c304d6 100644
> > > --- a/gcc/value-range.h
> > > +++ b/gcc/value-range.h
> > > @@ -50,6 +50,23 @@ enum value_range_discriminator
> > > };
> > >
> > > // Abstract class for ranges of any of the supported types.
> > > +//
> > > +// To query what types ranger and the entire ecosystem can support,
> > > +// use Value_Range::supports_type_p(tree type). This is a static
> > > +// method available independently of any vrange object.
> > > +//
> > > +// To query what a given vrange variant can support, use:
> > > +// irange::supports_p ()
> > > +// frange::supports_p ()
> > > +// etc
> > > +//
> > > +// To query what a range object can support, use:
> > > +// void foo (vrange &v, irange &i, frange &f)
> > > +// {
> > > +// if (v.supports_type_p (type)) ...
> > > +// if (i.supports_type_p (type)) ...
> > > +// if (f.supports_type_p (type)) ...
> > > +// }
> > >
> > > class vrange
> > > {
> > > @@ -58,6 +75,7 @@ class vrange
> > > public:
> > > virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
> > > virtual tree type () const = 0;
> > > + virtual bool supports_type_p (tree type) const = 0;
> > > virtual void set_varying (tree type) = 0;
> > > virtual void set_undefined () = 0;
> > > virtual void dump (FILE * = stderr) const = 0;
> > > @@ -72,8 +90,6 @@ public:
> > > virtual void set_nonnegative (tree type) = 0;
> > > virtual bool fits_p (const vrange &r) const = 0;
> > >
> > > - static bool supports_type_p (tree);
> > > -
> > > bool varying_p () const;
> > > bool undefined_p () const;
> > > vrange& operator= (const vrange &);
> > > @@ -103,7 +119,8 @@ public:
> > > virtual void set_undefined () override;
> > >
> > > // Range types.
> > > - static bool supports_type_p (tree);
> > > + static bool supports_p (tree type);
> > > + virtual bool supports_type_p (tree type) const override;
> > > virtual tree type () const override;
> > >
> > > // Iteration over sub-ranges.
> > > @@ -228,6 +245,7 @@ public:
> > > unsupported_range ();
> > > virtual void set (tree, tree, value_range_kind) override;
> > > virtual tree type () const override;
> > > + virtual bool supports_type_p (tree type) const override;
> > > virtual void set_varying (tree type) override;
> > > virtual void set_undefined () override;
> > > virtual void dump (FILE *) const override;
> > > @@ -331,6 +349,7 @@ public:
> > > operator vrange &();
> > > operator const vrange &() const;
> > > void dump (FILE *out = stderr) const;
> > > + static bool supports_type_p (tree type);
> > >
> > > // Convenience methods for vrange compatability.
> > > void set (tree min, tree max, value_range_kind kind = VR_RANGE)
> > > @@ -387,7 +406,7 @@ Value_Range::init (tree type)
> > > {
> > > gcc_checking_assert (TYPE_P (type));
> > >
> > > - if (irange::supports_type_p (type))
> > > + if (irange::supports_p (type))
> > > m_vrange = &m_irange;
> > > else
> > > m_vrange = &m_unsupported;
> > > @@ -444,6 +463,14 @@ Value_Range::operator const vrange &() const
> > > return *m_vrange;
> > > }
> > >
> > > +// Return TRUE if TYPE is supported by the vrange infrastructure.
> > > +
> > > +inline bool
> > > +Value_Range::supports_type_p (tree type)
> > > +{
> > > + return irange::supports_p (type);
> > > +}
> > > +
> > > // Returns true for an old-school value_range as described above.
> > > inline bool
> > > irange::legacy_mode_p () const
> > > @@ -580,7 +607,7 @@ irange::nonzero_p () const
> > > }
> > >
> > > inline bool
> > > -irange::supports_type_p (tree type)
> > > +irange::supports_p (tree type)
> > > {
> > > return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
> > > }
> > > @@ -864,12 +891,6 @@ irange::normalize_kind ()
> > > }
> > > }
> > >
> > > -inline bool
> > > -vrange::supports_type_p (tree type)
> > > -{
> > > - return irange::supports_type_p (type);
> > > -}
> > > -
> > > // Return the maximum value for TYPE.
> > >
> > > inline tree
> > > @@ -944,7 +965,7 @@ vrange_allocator::alloc (unsigned bytes)
> > > inline vrange *
> > > vrange_allocator::alloc_vrange (tree type)
> > > {
> > > - if (irange::supports_type_p (type))
> > > + if (irange::supports_p (type))
> > > return alloc_irange (2);
> > >
> > > gcc_unreachable ();
> > > --
> > > 2.36.1
> > >
> >
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [COMMITTED] Implement vrange::supports_type_p.
2022-06-28 7:36 ` Richard Biener
@ 2022-06-28 9:33 ` Aldy Hernandez
2022-06-28 10:15 ` Richard Biener
0 siblings, 1 reply; 6+ messages in thread
From: Aldy Hernandez @ 2022-06-28 9:33 UTC (permalink / raw)
To: Richard Biener; +Cc: GCC patches, Martin Liska, Andrew MacLeod
[-- Attachment #1: Type: text/plain, Size: 566 bytes --]
On Tue, Jun 28, 2022 at 9:36 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Mon, Jun 27, 2022 at 9:00 PM Aldy Hernandez <aldyh@redhat.com> wrote:
> >
> > The conversion for loop-ch is trivial, since the range of a
> > GIMPLE_COND is always an integer.
>
> Yes - but doesn't this hint at the fact that the irange::supports_p is
> useless because it checks on the type of the comparison operand
> rather than the type of the comparison (boolean_type_node)?
>
> So .. instead of replacing it, remove it?
You're absolutely right.
OK pending tests?
Aldy
[-- Attachment #2: 0001-Allow-all-types-supported-by-ranger-in-loop-ch.patch --]
[-- Type: text/x-patch, Size: 1138 bytes --]
From 6a37eec1ccc4f9d648156bc1eaf99ba73a6ccce2 Mon Sep 17 00:00:00 2001
From: Aldy Hernandez <aldyh@redhat.com>
Date: Mon, 27 Jun 2022 20:50:03 +0200
Subject: [PATCH] Allow all types supported by ranger in loop-ch.
This converts the ranger use in loop-ch to allow any types allowed by
the ranger infrastructure. Since the range of a GIMPLE_COND is always an
integer we can remove the check because the only temporary is already
an int_range.
gcc/ChangeLog:
* tree-ssa-loop-ch.cc (entry_loop_condition_is_static): Remove
irange::supports_p.
---
gcc/tree-ssa-loop-ch.cc | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/gcc/tree-ssa-loop-ch.cc b/gcc/tree-ssa-loop-ch.cc
index 26d96c0c21a..b74f1d7b612 100644
--- a/gcc/tree-ssa-loop-ch.cc
+++ b/gcc/tree-ssa-loop-ch.cc
@@ -54,8 +54,7 @@ entry_loop_condition_is_static (class loop *l, path_range_query *query)
edge e = loop_preheader_edge (l);
gcond *last = safe_dyn_cast <gcond *> (last_stmt (e->dest));
- if (!last
- || !irange::supports_p (TREE_TYPE (gimple_cond_lhs (last))))
+ if (!last)
return false;
edge true_e, false_e;
--
2.36.1
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [COMMITTED] Implement vrange::supports_type_p.
2022-06-28 9:33 ` Aldy Hernandez
@ 2022-06-28 10:15 ` Richard Biener
0 siblings, 0 replies; 6+ messages in thread
From: Richard Biener @ 2022-06-28 10:15 UTC (permalink / raw)
To: Aldy Hernandez; +Cc: GCC patches, Martin Liska, Andrew MacLeod
On Tue, Jun 28, 2022 at 11:33 AM Aldy Hernandez <aldyh@redhat.com> wrote:
>
> On Tue, Jun 28, 2022 at 9:36 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Mon, Jun 27, 2022 at 9:00 PM Aldy Hernandez <aldyh@redhat.com> wrote:
> > >
> > > The conversion for loop-ch is trivial, since the range of a
> > > GIMPLE_COND is always an integer.
> >
> > Yes - but doesn't this hint at the fact that the irange::supports_p is
> > useless because it checks on the type of the comparison operand
> > rather than the type of the comparison (boolean_type_node)?
> >
> > So .. instead of replacing it, remove it?
>
> You're absolutely right.
>
> OK pending tests?
Yes.
> Aldy
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-06-28 10:16 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-03 7:30 [COMMITTED] Implement vrange::supports_type_p Aldy Hernandez
2022-06-13 9:43 ` Richard Biener
2022-06-27 19:00 ` Aldy Hernandez
2022-06-28 7:36 ` Richard Biener
2022-06-28 9:33 ` Aldy Hernandez
2022-06-28 10:15 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).