https://gcc.gnu.org/g:67afcf28570ff62210e1998f35def2be5cb8cb08
commit r15-797-g67afcf28570ff62210e1998f35def2be5cb8cb08 Author: Andrew MacLeod <amacl...@redhat.com> Date: Mon Apr 29 13:32:00 2024 -0400 Move all relation queries into relation_oracle. Move relation queries from range_query object into the relation oracle. * gimple-range-cache.cc (ranger_cache::ranger_cache): Call create_relation_oracle. (ranger_cache::~ranger_cache): Call destroy_relation_oracle. * gimple-range-fold.cc (fur_stmt::get_phi_operand): Check for relation oracle bnefore calling query_relation. (fold_using_range::range_of_phi): Likewise. * gimple-range-path.cc (path_range_query::~path_range_query): Set relation oracle pointer to NULL when done. * gimple-range.cc (gimple_ranger::~gimple_ranger): Likewise. * value-query.cc (range_query::~range_query): Ensure any relation oracle is destroyed. (range_query::query_relation): relocate to relation_oracle object. * value-query.h (class range_query): Adjust method proototypes. (range_query::create_relation_oracle): New. (range_query::destroy_relation_oracle): New. * value-relation.cc (relation_oracle::query_relation): Relocate from range query class. * value-relation.h (Call relation_oracle): New prototypes. Diff: --- gcc/gimple-range-cache.cc | 9 +++----- gcc/gimple-range-fold.cc | 9 ++++++-- gcc/gimple-range-path.cc | 1 + gcc/gimple-range.cc | 1 + gcc/value-query.cc | 52 ++--------------------------------------------- gcc/value-query.h | 32 +++++++++++++++++++++++------ gcc/value-relation.cc | 33 ++++++++++++++++++++++++++++++ gcc/value-relation.h | 4 +++- 8 files changed, 76 insertions(+), 65 deletions(-) diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index bdd2832873a..cf17a6af9db 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -957,11 +957,9 @@ ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun)); m_workback.truncate (0); m_temporal = new temporal_cache; + // If DOM info is available, spawn an oracle as well. - if (dom_info_available_p (CDI_DOMINATORS)) - m_oracle = new dom_oracle (); - else - m_oracle = NULL; + create_relation_oracle (); unsigned x, lim = last_basic_block_for_fn (cfun); // Calculate outgoing range info upfront. This will fully populate the @@ -979,8 +977,7 @@ ranger_cache::ranger_cache (int not_executable_flag, bool use_imm_uses) ranger_cache::~ranger_cache () { delete m_update; - if (m_oracle) - delete m_oracle; + destroy_relation_oracle (); delete m_temporal; m_workback.release (); } diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index a9c8c4d03e6..41b6d350c40 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -178,7 +178,10 @@ fur_stmt::get_phi_operand (vrange &r, tree expr, edge e) relation_kind fur_stmt::query_relation (tree op1, tree op2) { - return m_query->query_relation (m_stmt, op1, op2); + relation_oracle *oracle = m_query->oracle (); + if (!oracle) + return VREL_VARYING; + return oracle->query_relation (m_stmt, op1, op2); } // Instantiate a stmt based fur_source with a GORI object. @@ -860,6 +863,7 @@ fold_using_range::range_of_phi (vrange &r, gphi *phi, fur_source &src) tree single_arg = NULL_TREE; bool seen_arg = false; + relation_oracle *oracle = src.query()->oracle (); // Start with an empty range, unioning in each argument's range. r.set_undefined (); for (x = 0; x < gimple_phi_num_args (phi); x++) @@ -880,7 +884,8 @@ fold_using_range::range_of_phi (vrange &r, gphi *phi, fur_source &src) // Likewise, if the incoming PHI argument is equivalent to this // PHI definition, it provides no new info. Accumulate these ranges // in case all arguments are equivalences. - if (src.query ()->query_relation (e, arg, phi_def, false) == VREL_EQ) + if (oracle + && oracle->query_relation (e, arg, phi_def) == VREL_EQ) equiv_range.union_(arg_range); else r.union_ (arg_range); diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index f1a12f76144..ef3db10470e 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -60,6 +60,7 @@ path_range_query::path_range_query (gimple_ranger &ranger, bool resolve) path_range_query::~path_range_query () { delete m_oracle; + m_oracle = NULL; } // Return TRUE if NAME is an exit dependency for the path. diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index e75e2e17dc3..22e8add5de1 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -67,6 +67,7 @@ gimple_ranger::gimple_ranger (bool use_imm_uses) : gimple_ranger::~gimple_ranger () { + m_oracle = NULL; m_stmt_list.release (); } diff --git a/gcc/value-query.cc b/gcc/value-query.cc index c2ab745a466..b275a43b679 100644 --- a/gcc/value-query.cc +++ b/gcc/value-query.cc @@ -185,6 +185,8 @@ range_query::range_query () range_query::~range_query () { + if (m_oracle) + destroy_relation_oracle (); } // This routine will invoke the equivalent of range_of_expr on @@ -437,53 +439,3 @@ global_range_query::range_of_expr (vrange &r, tree expr, gimple *stmt) return true; } - -// Return any known relation between SSA1 and SSA2 before stmt S is executed. -// If GET_RANGE is true, query the range of both operands first to ensure -// the definitions have been processed and any relations have be created. - -relation_kind -range_query::query_relation (gimple *s, tree ssa1, tree ssa2, bool get_range) -{ - if (!m_oracle || TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME) - return VREL_VARYING; - - // Ensure ssa1 and ssa2 have both been evaluated. - if (get_range) - { - Value_Range tmp1 (TREE_TYPE (ssa1)); - Value_Range tmp2 (TREE_TYPE (ssa2)); - range_of_expr (tmp1, ssa1, s); - range_of_expr (tmp2, ssa2, s); - } - return m_oracle->query_relation (gimple_bb (s), ssa1, ssa2); -} - -// Return any known relation between SSA1 and SSA2 on edge E. -// If GET_RANGE is true, query the range of both operands first to ensure -// the definitions have been processed and any relations have be created. - -relation_kind -range_query::query_relation (edge e, tree ssa1, tree ssa2, bool get_range) -{ - basic_block bb; - if (!m_oracle || TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME) - return VREL_VARYING; - - // Use destination block if it has a single predecessor, and this picks - // up any relation on the edge. - // Otherwise choose the src edge and the result is the same as on-exit. - if (!single_pred_p (e->dest)) - bb = e->src; - else - bb = e->dest; - - // Ensure ssa1 and ssa2 have both been evaluated. - if (get_range) - { - Value_Range tmp (TREE_TYPE (ssa1)); - range_on_edge (tmp, e, ssa1); - range_on_edge (tmp, e, ssa2); - } - return m_oracle->query_relation (bb, ssa1, ssa2); -} diff --git a/gcc/value-query.h b/gcc/value-query.h index 4d2a7bce485..9df89905ace 100644 --- a/gcc/value-query.h +++ b/gcc/value-query.h @@ -75,16 +75,12 @@ public: virtual bool range_on_entry (vrange &r, basic_block bb, tree expr); virtual bool range_on_exit (vrange &r, basic_block bb, tree expr); - // Query if there is any relation between SSA1 and SSA2. - relation_kind query_relation (gimple *s, tree ssa1, tree ssa2, - bool get_range = true); - relation_kind query_relation (edge e, tree ssa1, tree ssa2, - bool get_range = true); - // If present, Access relation oracle for more advanced uses. inline relation_oracle *oracle () const { return m_oracle; } virtual void dump (FILE *); + void create_relation_oracle (); + void destroy_relation_oracle (); protected: bool get_tree_range (vrange &v, tree expr, gimple *stmt, basic_block bbentry = NULL, basic_block bbexit = NULL); @@ -123,4 +119,28 @@ get_range_query (const struct function *fun) extern void gimple_range_global (vrange &v, tree name, struct function *f = cfun); +// Create dominance based range oracle for the current query if dom info is +// available. + +inline void +range_query::create_relation_oracle () +{ + if (!dom_info_available_p (CDI_DOMINATORS)) + return; + gcc_checking_assert (m_oracle == NULL); + m_oracle = new dom_oracle (); +} + +// Destroy any relation oracle that was created. + +inline void +range_query::destroy_relation_oracle () +{ + if (m_oracle != NULL) + { + delete m_oracle; + m_oracle = NULL; + } +} + #endif // GCC_QUERY_H diff --git a/gcc/value-relation.cc b/gcc/value-relation.cc index 619ee5f0867..d1081b3b3f5 100644 --- a/gcc/value-relation.cc +++ b/gcc/value-relation.cc @@ -288,6 +288,39 @@ relation_oracle::valid_equivs (bitmap b, const_bitmap equivs, basic_block bb) } } +// Return any known relation between SSA1 and SSA2 before stmt S is executed. +// If GET_RANGE is true, query the range of both operands first to ensure +// the definitions have been processed and any relations have be created. + +relation_kind +relation_oracle::query_relation (gimple *s, tree ssa1, tree ssa2) +{ + if (TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME) + return VREL_VARYING; + return query_relation (gimple_bb (s), ssa1, ssa2); +} + +// Return any known relation between SSA1 and SSA2 on edge E. +// If GET_RANGE is true, query the range of both operands first to ensure +// the definitions have been processed and any relations have be created. + +relation_kind +relation_oracle::query_relation (edge e, tree ssa1, tree ssa2) +{ + basic_block bb; + if (TREE_CODE (ssa1) != SSA_NAME || TREE_CODE (ssa2) != SSA_NAME) + return VREL_VARYING; + + // Use destination block if it has a single predecessor, and this picks + // up any relation on the edge. + // Otherwise choose the src edge and the result is the same as on-exit. + if (!single_pred_p (e->dest)) + bb = e->src; + else + bb = e->dest; + + return query_relation (bb, ssa1, ssa2); +} // ------------------------------------------------------------------------- // The very first element in the m_equiv chain is actually just a summary diff --git a/gcc/value-relation.h b/gcc/value-relation.h index 61d2497743c..5adf736cf41 100644 --- a/gcc/value-relation.h +++ b/gcc/value-relation.h @@ -105,8 +105,10 @@ public: // register a relation between 2 ssa names in a basic block. virtual void register_relation (basic_block, relation_kind, tree, tree) = 0; - // Query for a relation between two ssa names in a basic block. + // Query if there is any relation between SSA1 and SSA2. virtual relation_kind query_relation (basic_block, tree, tree) = 0; + relation_kind query_relation (gimple *s, tree ssa1, tree ssa2); + relation_kind query_relation (edge e, tree ssa1, tree ssa2); relation_kind validate_relation (relation_kind, tree, tree); relation_kind validate_relation (relation_kind, vrange &, vrange &);