From: Andrew MacLeod Date: Fri, 17 May 2024 18:27:12 +0000 (-0400) Subject: Make GORI a range_query component. X-Git-Tag: basepoints/gcc-16~8747 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac0bc89aea79b940a17697fb4a758254631c2400;p=thirdparty%2Fgcc.git Make GORI a range_query component. This patch moves the GORI component into the range_query object, and makes it generally available. This makes it much easier to share between ranger and the passes. * gimple-range-cache.cc (ranger_cache::ranger_cache): Create GORi via the range_query instead of a local member. (ranger_cache::dump_bb): Use gori via from the range_query parent. (ranger_cache::get_global_range): Likewise. (ranger_cache::set_global_range): Likewise. (ranger_cache::edge_range): Likewise. (anger_cache::block_range): Likewise. (ranger_cache::fill_block_cache): Likewise. (ranger_cache::range_from_dom): Likewise. (ranger_cache::register_inferred_value): Likewise. * gimple-range-cache.h (ranger_cache::m_gori): Delete. * gimple-range-fold.cc (fur_source::fur_source): Set m_depend_p. (fur_depend::fur_depend): Remove gori parameter. * gimple-range-fold.h (fur_source::gori): Adjust. (fur_source::m_gori): Delete. (fur_source::m_depend): New. (fur_depend::fur_depend): Adjust prototype. * gimple-range-path.cc (path_range_query::path_range_query): Share ranger oracles. (path_range_query::range_defined_in_block): Use oracle directly. (path_range_query::compute_ranges_in_block): Use new gori() method. (path_range_query::adjust_for_non_null_uses): Use oracle directly. (path_range_query::compute_exit_dependencies): Likewise. (jt_fur_source::jt_fur_source): No gori in the parameters. (path_range_query::range_of_stmt): Likewise. (path_range_query::compute_outgoing_relations): Likewise. * gimple-range.cc (gimple_ranger::fold_range_internal): Likewise. (gimple_ranger::range_of_stmt): Access gori via gori () method. (assume_query::range_of_expr): Create a gori object. (assume_query::~assume_query): Destroy a gori object. (assume_query::calculate_op): Remove old gori() accessor. * gimple-range.h (gimple_ranger::gori): Delete. (assume_query::~assume_query): New. (assume_query::m_gori): Delete. * tree-ssa-dom.cc (set_global_ranges_from_unreachable_edges): use gori () method. * tree-ssa-threadedge.cc (compute_exit_dependencies): Likewise. * value-query.cc (default_gori): New. (range_query::create_gori): New. (range_query::destroy_gori): New. (range_query::share_oracles): Set m_gori. (range_query::range_query): Set m_gori to default. (range_query::~range_query): call destroy gori. * value-query.h (range_query): Adjust prototypes (range_query::m_gori): New. --- diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 40e4baa6289..e75cac66902 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -950,7 +950,6 @@ update_list::pop () // -------------------------------------------------------------------------- ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) - : m_gori (not_executable_flag, param_vrp_switch_limit) { m_workback.create (0); m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun)); @@ -960,6 +959,7 @@ ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) // If DOM info is available, spawn an oracle as well. create_relation_oracle (); create_infer_oracle (use_imm_uses); + create_gori (not_executable_flag, param_vrp_switch_limit); unsigned x, lim = last_basic_block_for_fn (cfun); // Calculate outgoing range info upfront. This will fully populate the @@ -969,7 +969,7 @@ ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) { basic_block bb = BASIC_BLOCK_FOR_FN (cfun, x); if (bb) - m_gori.map ()->exports (bb); + gori ().map ()->exports (bb); } m_update = new update_list (); } @@ -1000,7 +1000,7 @@ ranger_cache::dump (FILE *f) void ranger_cache::dump_bb (FILE *f, basic_block bb) { - m_gori.map ()->dump (f, bb, false); + gori ().map ()->dump (f, bb, false); m_on_entry.dump (f, bb); m_relation->dump (f, bb); } @@ -1033,8 +1033,8 @@ ranger_cache::get_global_range (vrange &r, tree name, bool ¤t_p) current_p = false; if (had_global) current_p = r.singleton_p () - || m_temporal->current_p (name, m_gori.map ()->depend1 (name), - m_gori.map ()->depend2 (name)); + || m_temporal->current_p (name, gori ().map ()->depend1 (name), + gori ().map ()->depend2 (name)); else { // If no global value has been set and value is VARYING, fold the stmt @@ -1071,8 +1071,8 @@ ranger_cache::set_global_range (tree name, const vrange &r, bool changed) if (!changed) { // If there are dependencies, make sure this is not out of date. - if (!m_temporal->current_p (name, m_gori.map ()->depend1 (name), - m_gori.map ()->depend2 (name))) + if (!m_temporal->current_p (name, gori ().map ()->depend1 (name), + gori ().map ()->depend2 (name))) m_temporal->set_timestamp (name); return; } @@ -1097,7 +1097,7 @@ ranger_cache::set_global_range (tree name, const vrange &r, bool changed) if (r.singleton_p () || (POINTER_TYPE_P (TREE_TYPE (name)) && r.nonzero_p ())) - m_gori.map ()->set_range_invariant (name); + gori ().map ()->set_range_invariant (name); m_temporal->set_timestamp (name); } @@ -1178,7 +1178,7 @@ ranger_cache::edge_range (vrange &r, edge e, tree name, enum rfd_mode mode) if ((e->flags & (EDGE_EH | EDGE_ABNORMAL)) == 0) infer_oracle ().maybe_adjust_range (r, name, e->src); Value_Range er (TREE_TYPE (name)); - if (m_gori.edge_range_p (er, e, name, *this)) + if (gori ().edge_range_p (er, e, name, *this)) r.intersect (er); return true; } @@ -1230,7 +1230,7 @@ ranger_cache::block_range (vrange &r, basic_block bb, tree name, bool calc) // If there are no range calculations anywhere in the IL, global range // applies everywhere, so don't bother caching it. - if (!m_gori.has_edge_range_p (name)) + if (!gori ().has_edge_range_p (name)) return false; if (calc) @@ -1449,7 +1449,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb) continue; // Check if the equiv has any ranges calculated. - if (!m_gori.has_edge_range_p (equiv_name)) + if (!gori ().has_edge_range_p (equiv_name)) continue; // Check if the equiv definition dominates this block @@ -1562,7 +1562,7 @@ ranger_cache::fill_block_cache (tree name, basic_block bb, basic_block def_bb) r.dump (dump_file); fprintf (dump_file, ", "); } - if (!r.undefined_p () || m_gori.has_edge_range_p (name, e)) + if (!r.undefined_p () || gori ().has_edge_range_p (name, e)) { m_update->add (node); if (DEBUG_RANGE_CACHE) @@ -1671,7 +1671,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb, infer_oracle ().maybe_adjust_range (infer, name, bb); // This block has an outgoing range. - if (m_gori.has_edge_range_p (name, bb)) + if (gori ().has_edge_range_p (name, bb)) m_workback.quick_push (prev_bb); else { @@ -1683,7 +1683,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb, // If the first pred does not generate a range, then we will be // using the dominator range anyway, so that's all the check needed. if (EDGE_COUNT (prev_bb->preds) > 1 - && m_gori.has_edge_range_p (name, EDGE_PRED (prev_bb, 0)->src)) + && gori ().has_edge_range_p (name, EDGE_PRED (prev_bb, 0)->src)) { edge e; edge_iterator ei; @@ -1738,7 +1738,7 @@ ranger_cache::range_from_dom (vrange &r, tree name, basic_block start_bb, edge e = single_pred_edge (prev_bb); bb = e->src; - if (m_gori.edge_range_p (er, e, name, *this)) + if (gori ().edge_range_p (er, e, name, *this)) { r.intersect (er); // If this is a normal edge, apply any inferred ranges. @@ -1782,8 +1782,8 @@ ranger_cache::register_inferred_value (const vrange &ir, tree name, { m_on_entry.set_bb_range (name, bb, r); // If this range was invariant before, remove invariant. - if (!m_gori.has_edge_range_p (name)) - m_gori.map ()->set_range_invariant (name, false); + if (!gori ().has_edge_range_p (name)) + gori ().map ()->set_range_invariant (name, false); } } diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h index e3ab89de02e..c7499f928a9 100644 --- a/gcc/gimple-range-cache.h +++ b/gcc/gimple-range-cache.h @@ -114,7 +114,6 @@ public: void register_inferred_value (const vrange &r, tree name, basic_block bb); void apply_inferred_ranges (gimple *s); - gori_compute m_gori; void dump_bb (FILE *f, basic_block bb); virtual void dump (FILE *f) override; diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index 37c16761ba6..e9e387c7d59 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -59,7 +59,7 @@ fur_source::fur_source (range_query *q) m_query = q; else m_query = get_range_query (cfun); - m_gori = NULL; + m_depend_p = false; } // Invoke range_of_expr on EXPR. @@ -184,11 +184,10 @@ fur_stmt::query_relation (tree op1, tree op2) // Instantiate a stmt based fur_source with a GORI object. -fur_depend::fur_depend (gimple *s, gori_compute *gori, range_query *q) +fur_depend::fur_depend (gimple *s, range_query *q) : fur_stmt (s, q) { - gcc_checking_assert (gori); - m_gori = gori; + m_depend_p = true; } // Register a relation on a stmt if there is an oracle. diff --git a/gcc/gimple-range-fold.h b/gcc/gimple-range-fold.h index d974b0192c8..9ae6cf56d2a 100644 --- a/gcc/gimple-range-fold.h +++ b/gcc/gimple-range-fold.h @@ -106,7 +106,8 @@ class fur_source public: fur_source (range_query *q = NULL); inline range_query *query () { return m_query; } - inline class gori_compute *gori () { return m_gori; }; + inline class gimple_outgoing_range *gori () + { return m_depend_p ? &(m_query->gori ()) : NULL; } virtual bool get_operand (vrange &r, tree expr); virtual bool get_phi_operand (vrange &r, tree expr, edge e); virtual relation_kind query_relation (tree op1, tree op2); @@ -117,7 +118,7 @@ public: void register_outgoing_edges (gcond *, irange &lhs_range, edge e0, edge e1); protected: range_query *m_query; - gori_compute *m_gori; + bool m_depend_p; }; // fur_stmt is the specification for drawing an operand from range_query Q @@ -140,7 +141,7 @@ private: class fur_depend : public fur_stmt { public: - fur_depend (gimple *s, gori_compute *gori, range_query *q = NULL); + fur_depend (gimple *s, range_query *q = NULL); virtual void register_relation (gimple *stmt, relation_kind k, tree op1, tree op2) override; virtual void register_relation (edge e, relation_kind k, tree op1, diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index 03f73218a57..707bd0ebd94 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -44,6 +44,8 @@ path_range_query::path_range_query (gimple_ranger &ranger, m_ranger (ranger), m_resolve (resolve) { + share_query (ranger); + // Override the relation oracle with a local path relation oracle. m_relation = new path_oracle (&(m_ranger.relation ())); reset_path (path, dependencies); @@ -54,6 +56,8 @@ path_range_query::path_range_query (gimple_ranger &ranger, bool resolve) m_ranger (ranger), m_resolve (resolve) { + share_query (ranger); + // Override the relation oracle with a local path relation oracle. m_relation = new path_oracle (&(m_ranger.relation ())); } @@ -303,7 +307,7 @@ path_range_query::range_defined_in_block (vrange &r, tree name, basic_block bb) } if (bb && POINTER_TYPE_P (TREE_TYPE (name))) - m_ranger.infer_oracle ().maybe_adjust_range (r, name, bb); + infer_oracle ().maybe_adjust_range (r, name, bb); if (DEBUG_SOLVER && (bb || !r.varying_p ())) { @@ -409,13 +413,12 @@ path_range_query::compute_ranges_in_block (basic_block bb) p->reset_path (); } - gori_compute &g = m_ranger.gori (); - bitmap exports = g.map()->exports (bb); + bitmap exports = gori ().map ()->exports (bb); EXECUTE_IF_AND_IN_BITMAP (m_exit_dependencies, exports, 0, i, bi) { tree name = ssa_name (i); Value_Range r (TREE_TYPE (name)); - if (g.edge_range_p (r, e, name, *this)) + if (gori ().edge_range_p (r, e, name, *this)) { Value_Range cached_range (TREE_TYPE (name)); if (get_cache (cached_range, name)) @@ -463,7 +466,7 @@ path_range_query::adjust_for_non_null_uses (basic_block bb) else r.set_varying (TREE_TYPE (name)); - if (m_ranger.infer_oracle ().maybe_adjust_range (r, name, bb)) + if (infer_oracle ().maybe_adjust_range (r, name, bb)) m_cache.set_range (name, r); } } @@ -487,8 +490,7 @@ path_range_query::compute_exit_dependencies (bitmap dependencies) { // Start with the imports from the exit block... basic_block exit = m_path[0]; - gori_compute &gori = m_ranger.gori (); - bitmap_copy (dependencies, gori.map()->imports (exit)); + bitmap_copy (dependencies, gori ().map()->imports (exit)); auto_vec worklist (bitmap_count_bits (dependencies)); bitmap_iterator bi; @@ -536,7 +538,7 @@ path_range_query::compute_exit_dependencies (bitmap dependencies) { basic_block bb = m_path[i]; tree name; - FOR_EACH_GORI_EXPORT_NAME (*(gori.map ()), bb, name) + FOR_EACH_GORI_EXPORT_NAME (*(gori ().map ()), bb, name) if (TREE_CODE (TREE_TYPE (name)) == BOOLEAN_TYPE) bitmap_set_bit (dependencies, SSA_NAME_VERSION (name)); } @@ -611,8 +613,7 @@ path_range_query::compute_ranges (const bitmap_head *dependencies) class jt_fur_source : public fur_depend { public: - jt_fur_source (gimple *s, path_range_query *, gori_compute *, - const vec &); + jt_fur_source (gimple *s, path_range_query *, const vec &); relation_kind query_relation (tree op1, tree op2) override; void register_relation (gimple *, relation_kind, tree op1, tree op2) override; void register_relation (edge, relation_kind, tree op1, tree op2) override; @@ -622,9 +623,8 @@ private: jt_fur_source::jt_fur_source (gimple *s, path_range_query *query, - gori_compute *gori, const vec &path) - : fur_depend (s, gori, query) + : fur_depend (s, query) { gcc_checking_assert (!path.is_empty ()); @@ -671,7 +671,7 @@ path_range_query::range_of_stmt (vrange &r, gimple *stmt, tree) if (m_resolve) { fold_using_range f; - jt_fur_source src (stmt, this, &m_ranger.gori (), m_path); + jt_fur_source src (stmt, this, m_path); if (!f.fold_stmt (r, stmt, src)) r.set_varying (type); } @@ -761,7 +761,7 @@ path_range_query::compute_outgoing_relations (basic_block bb, basic_block next) else gcc_unreachable (); - jt_fur_source src (NULL, this, &m_ranger.gori (), m_path); + jt_fur_source src (NULL, this, m_path); src.register_outgoing_edges (cond, r, e0, e1); } } diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index e7e6fd86581..20294612185 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -273,7 +273,7 @@ bool gimple_ranger::fold_range_internal (vrange &r, gimple *s, tree name) { fold_using_range f; - fur_depend src (s, &(gori ()), this); + fur_depend src (s, this); return f.fold_stmt (r, s, src, name); } @@ -310,7 +310,7 @@ gimple_ranger::range_of_stmt (vrange &r, gimple *s, tree name) // Update any exports in the cache if this is a gimple cond statement. tree exp; basic_block bb = gimple_bb (s); - FOR_EACH_GORI_EXPORT_NAME (*(m_cache.m_gori.map ()), bb, exp) + FOR_EACH_GORI_EXPORT_NAME (*(gori ().map ()), bb, exp) m_cache.propagate_updated_value (exp, bb); } } @@ -755,6 +755,7 @@ assume_query::range_of_expr (vrange &r, tree expr, gimple *stmt) assume_query::assume_query () { + create_gori (0, param_vrp_switch_limit); basic_block exit_bb = EXIT_BLOCK_PTR_FOR_FN (cfun); if (single_pred_p (exit_bb)) { @@ -785,6 +786,11 @@ assume_query::assume_query () } } +assume_query::~assume_query () +{ + destroy_gori (); +} + // Evaluate operand OP on statement S, using the provided LHS range. // If successful, set the range in the global table, then visit OP's def stmt. @@ -792,7 +798,7 @@ void assume_query::calculate_op (tree op, gimple *s, vrange &lhs, fur_source &src) { Value_Range op_range (TREE_TYPE (op)); - if (m_gori.compute_operand_range (op_range, s, lhs, op, src) + if (gori ().compute_operand_range (op_range, s, lhs, op, src) && !op_range.varying_p ()) { // Set the global range, merging if there is already a range. diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index 167b54b2a37..1532951a449 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -55,7 +55,6 @@ public: virtual bool range_on_entry (vrange &r, basic_block bb, tree name) override; virtual bool range_on_exit (vrange &r, basic_block bb, tree name) override; void export_global_ranges (); - inline gori_compute &gori () { return m_cache.m_gori; } virtual void dump (FILE *f) override; void debug (); void dump_bb (FILE *f, basic_block bb); @@ -87,6 +86,7 @@ class assume_query : public range_query { public: assume_query (); + ~assume_query (); bool assume_range_p (vrange &r, tree name); virtual bool range_of_expr (vrange &r, tree expr, gimple * = NULL); void dump (FILE *f); @@ -97,7 +97,6 @@ protected: void check_taken_edge (edge e, fur_source &src); ssa_lazy_cache global; - gori_compute m_gori; }; // DOM based ranger for fast VRP. diff --git a/gcc/tree-ssa-dom.cc b/gcc/tree-ssa-dom.cc index 81c8b16fd12..67c87bbd19e 100644 --- a/gcc/tree-ssa-dom.cc +++ b/gcc/tree-ssa-dom.cc @@ -1430,8 +1430,7 @@ dom_opt_dom_walker::set_global_ranges_from_unreachable_edges (basic_block bb) return; tree name; - gori_compute &gori = m_ranger->gori (); - FOR_EACH_GORI_EXPORT_NAME (*(gori.map()), pred_e->src, name) + FOR_EACH_GORI_EXPORT_NAME (*(m_ranger->gori ().map()), pred_e->src, name) if (all_uses_feed_or_dominated_by_stmt (name, stmt) // The condition must post-dominate the definition point. && (SSA_NAME_IS_DEFAULT_DEF (name) diff --git a/gcc/tree-ssa-threadedge.cc b/gcc/tree-ssa-threadedge.cc index f5268d45516..766b68a007b 100644 --- a/gcc/tree-ssa-threadedge.cc +++ b/gcc/tree-ssa-threadedge.cc @@ -1446,10 +1446,8 @@ hybrid_jt_simplifier::compute_exit_dependencies (bitmap dependencies, const vec &path, gimple *stmt) { - gori_compute &gori = m_ranger->gori (); - // Start with the imports to the final conditional. - bitmap_copy (dependencies, gori.map ()->imports (path[0])); + bitmap_copy (dependencies, m_ranger->gori ().map ()->imports (path[0])); // Add any other interesting operands we may have missed. if (gimple_bb (stmt) != path[0]) diff --git a/gcc/value-query.cc b/gcc/value-query.cc index 41b581b20be..db813ad3094 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -182,6 +182,23 @@ range_query::dump (FILE *) // can be used anywhere. relation_oracle default_relation_oracle; infer_range_oracle default_infer_oracle; +gimple_outgoing_range default_gori; + +void +range_query::create_gori (int not_executable_flag, int sw_max_edges) +{ + gcc_checking_assert (m_gori == &default_gori); + m_gori = new gori_compute (not_executable_flag, sw_max_edges); + gcc_checking_assert (m_gori); +} + +void +range_query::destroy_gori () +{ + if (m_gori && m_gori != &default_gori) + delete m_gori; + m_gori= &default_gori; +} void range_query::create_infer_oracle (bool do_search) @@ -233,6 +250,7 @@ range_query::share_query (range_query &q) { m_relation = q.m_relation; m_infer = q.m_infer; + m_gori = q.m_gori; m_shared_copy_p = true; } @@ -240,6 +258,7 @@ range_query::range_query () { m_relation = &default_relation_oracle; m_infer = &default_infer_oracle; + m_gori = &default_gori; m_shared_copy_p = false; } @@ -248,6 +267,7 @@ range_query::~range_query () // Do not destroy anything if this is a shared copy. if (m_shared_copy_p) return; + destroy_gori (); destroy_infer_oracle (); destroy_relation_oracle (); } diff --git a/gcc/value-query.h b/gcc/value-query.h index 2f65d95bc9b..1481f532d60 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -83,6 +83,10 @@ public: void create_infer_oracle (bool do_search = TRUE); void destroy_infer_oracle (); + inline class gimple_outgoing_range &gori () const { return *m_gori; } + void create_gori (int not_executable_flag = 0, int sw_max_edges = INT_MAX); + void destroy_gori (); + virtual void dump (FILE *); protected: @@ -93,6 +97,7 @@ protected: bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt); relation_oracle *m_relation; infer_range_oracle *m_infer; + gimple_outgoing_range *m_gori; // When multiple related range queries wish to share oracles. // This is an internal interface void share_query (range_query &q);