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 (s) && range_op_handler (s)) return gsi_stmt (gsi); - gswitch *sw = dyn_cast (s); - if (sw && irange::supports_type_p (TREE_TYPE (gimple_switch_index (sw)))) + if (is_a (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 (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 (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 (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 61c04ed9f2e..50b66c13038 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 (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 ();