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;
}
// 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)
{
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)));
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;
type = TREE_TYPE (type);
}
}
- if (type && vrange::supports_type_p (type))
+ if (type && Value_Range::supports_type_p (type))
return type;
return NULL_TREE;
}
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;
}
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))
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;
}
{
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
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)
print_header = false;
}
- if (!irange::supports_type_p (TREE_TYPE (name)))
+ if (!irange::supports_p (TREE_TYPE (name)))
continue;
vrange &v = r;
/* 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;
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);
}
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;
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;
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 ())
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));
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;
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));
}
}
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;
{
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));
{
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))
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))
else
type = TREE_TYPE (expr);
- if (!vrange::supports_type_p (type))
+ if (!Value_Range::supports_type_p (type))
{
r.set_undefined ();
return false;
{
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);
}
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);
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);
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. */
gcc_unreachable ();
}
+bool
+irange::supports_type_p (tree type) const
+{
+ return supports_p (type);
+}
+
// Return TRUE if R fits in THIS.
bool
return nullptr;
}
+bool
+unsupported_range::supports_type_p (tree) const
+{
+ return false;
+}
+
void
unsupported_range::set_undefined ()
{
};
// 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
{
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;
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 &);
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.
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;
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)
{
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;
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
}
inline bool
-irange::supports_type_p (tree type)
+irange::supports_p (tree type)
{
return INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type);
}
}
}
-inline bool
-vrange::supports_type_p (tree type)
-{
- return irange::supports_type_p (type);
-}
-
// Return the maximum value for TYPE.
inline tree
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 ();