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.
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
ranger_cache::~ranger_cache ()
{
delete m_update;
- if (m_oracle)
- delete m_oracle;
+ destroy_relation_oracle ();
delete m_temporal;
m_workback.release ();
}
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.
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++)
// 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);
path_range_query::~path_range_query ()
{
delete m_oracle;
+ m_oracle = NULL;
}
// Return TRUE if NAME is an exit dependency for the path.
gimple_ranger::~gimple_ranger ()
{
+ m_oracle = NULL;
m_stmt_list.release ();
}
range_query::~range_query ()
{
+ if (m_oracle)
+ destroy_relation_oracle ();
}
// This routine will invoke the equivalent of range_of_expr on
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);
-}
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);
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
}
}
+// 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
// 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 &);