From b0cbffd5655b9fc108691c6b15e8eaed4ab9746a Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacleod@redhat.com>
Date: Mon, 29 Apr 2024 13:32:00 -0400
Subject: [PATCH 01/12] 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 after deleting it.
* 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.
---
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(-)
@@ -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 ();
}
@@ -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);
@@ -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.
@@ -67,6 +67,7 @@ gimple_ranger::gimple_ranger (bool use_imm_uses) :
gimple_ranger::~gimple_ranger ()
{
+ m_oracle = NULL;
m_stmt_list.release ();
}
@@ -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);
-}
@@ -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
@@ -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
@@ -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 &);
--
2.41.0