Implement vrange::supports_type_p.
[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.
This commit is contained in:
parent
6124f42488
commit
a9058b0838
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
@ -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 ()
|
||||
{
|
||||
|
@ -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 ();
|
||||
|
Loading…
Reference in New Issue
Block a user