mirror of https://github.com/gcc-mirror/gcc.git
Add range_on_entry/exit to value_query API.
Add range_on_entry and range_on_exit to the value_query API. These will also work with generic trees like range_of_expr does. * gimple-range.cc (gimple_ranger::range_on_entry): Adjust for new API and support non-SSA expressions. (gimple_ranger::range_on_exit): Ditto. * gimple-range.h (range_on_entry, range_on_exit): Adjust API. * value-query.cc (range_query::range_on_entry): New. (range_query::range_on_exit): New. (range_query::value_on_entry): New. (range_query::value_on_exit): New. (range_query::invoke_range_of_expr): New. (range_query::get_tree_range): Allow stmt, on_entry or on_exit range queries. SSA_NAMES should invoke range_of_expr if possible. * value-query.h (class range_query): Adjust prototypes.pull/62/merge
parent
0ade358cd7
commit
39fe620963
|
@ -152,11 +152,13 @@ gimple_ranger::range_of_expr (vrange &r, tree expr, gimple *stmt)
|
|||
|
||||
// Return the range of NAME on entry to block BB in R.
|
||||
|
||||
void
|
||||
bool
|
||||
gimple_ranger::range_on_entry (vrange &r, basic_block bb, tree name)
|
||||
{
|
||||
if (!gimple_range_ssa_p (name))
|
||||
return get_tree_range (r, name, NULL, bb, NULL);
|
||||
|
||||
Value_Range entry_range (TREE_TYPE (name));
|
||||
gcc_checking_assert (gimple_range_ssa_p (name));
|
||||
|
||||
unsigned idx;
|
||||
if ((idx = tracer.header ("range_on_entry (")))
|
||||
|
@ -174,16 +176,17 @@ gimple_ranger::range_on_entry (vrange &r, basic_block bb, tree name)
|
|||
|
||||
if (idx)
|
||||
tracer.trailer (idx, "range_on_entry", true, name, r);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate the range for NAME at the end of block BB and return it in R.
|
||||
// Return false if no range can be calculated.
|
||||
|
||||
void
|
||||
bool
|
||||
gimple_ranger::range_on_exit (vrange &r, basic_block bb, tree name)
|
||||
{
|
||||
// on-exit from the exit block?
|
||||
gcc_checking_assert (gimple_range_ssa_p (name));
|
||||
if (!gimple_range_ssa_p (name))
|
||||
return get_tree_range (r, name, NULL, NULL, bb);
|
||||
|
||||
unsigned idx;
|
||||
if ((idx = tracer.header ("range_on_exit (")))
|
||||
|
@ -208,6 +211,7 @@ gimple_ranger::range_on_exit (vrange &r, basic_block bb, tree name)
|
|||
|
||||
if (idx)
|
||||
tracer.trailer (idx, "range_on_exit", true, name, r);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate a range for NAME on edge E and return it in R.
|
||||
|
|
|
@ -52,8 +52,8 @@ public:
|
|||
virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override;
|
||||
virtual bool range_of_expr (vrange &r, tree name, gimple * = NULL) override;
|
||||
virtual bool range_on_edge (vrange &r, edge e, tree name) override;
|
||||
void range_on_entry (vrange &r, basic_block bb, tree name);
|
||||
void range_on_exit (vrange &r, basic_block bb, tree name);
|
||||
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;
|
||||
|
|
|
@ -41,6 +41,18 @@ range_query::range_on_edge (vrange &r, edge, tree expr)
|
|||
return range_of_expr (r, expr);
|
||||
}
|
||||
|
||||
bool
|
||||
range_query::range_on_entry (vrange &r, basic_block, tree expr)
|
||||
{
|
||||
return range_of_expr (r, expr);
|
||||
}
|
||||
|
||||
bool
|
||||
range_query::range_on_exit (vrange &r, basic_block, tree expr)
|
||||
{
|
||||
return range_of_expr (r, expr);
|
||||
}
|
||||
|
||||
bool
|
||||
range_query::range_of_stmt (vrange &r, gimple *stmt, tree name)
|
||||
{
|
||||
|
@ -54,6 +66,9 @@ range_query::range_of_stmt (vrange &r, gimple *stmt, tree name)
|
|||
return false;
|
||||
}
|
||||
|
||||
// If the range of expr EXPR at STMT is a single value, return it.
|
||||
// Otherwise return NULL_TREE.
|
||||
|
||||
tree
|
||||
range_query::value_of_expr (tree expr, gimple *stmt)
|
||||
{
|
||||
|
@ -76,6 +91,9 @@ range_query::value_of_expr (tree expr, gimple *stmt)
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
// If the range on edge E for EXPR is a single value, return it.
|
||||
// Otherwise return NULL_TREE.
|
||||
|
||||
tree
|
||||
range_query::value_on_edge (edge e, tree expr)
|
||||
{
|
||||
|
@ -94,9 +112,11 @@ range_query::value_on_edge (edge e, tree expr)
|
|||
return t;
|
||||
}
|
||||
return NULL_TREE;
|
||||
|
||||
}
|
||||
|
||||
// If the range of STMT for NAME is a single value, return it.
|
||||
// Otherwise return NULL_TREE.
|
||||
|
||||
tree
|
||||
range_query::value_of_stmt (gimple *stmt, tree name)
|
||||
{
|
||||
|
@ -113,7 +133,44 @@ range_query::value_of_stmt (gimple *stmt, tree name)
|
|||
if (range_of_stmt (r, stmt, name) && r.singleton_p (&t))
|
||||
return t;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
// If the range on entry to BB for EXPR is a single value, return it.
|
||||
// Otherwise return NULL_TREE.
|
||||
|
||||
tree
|
||||
range_query::value_on_entry (basic_block bb, tree expr)
|
||||
{
|
||||
tree t;
|
||||
|
||||
gcc_checking_assert (bb);
|
||||
if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
|
||||
return NULL_TREE;
|
||||
|
||||
Value_Range r (TREE_TYPE (expr));
|
||||
|
||||
if (range_on_entry (r, bb, expr) && r.singleton_p (&t))
|
||||
return t;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
// If the range on exit to BB for EXPR is a single value, return it.
|
||||
// Otherwise return NULL_TREE.
|
||||
|
||||
tree
|
||||
range_query::value_on_exit (basic_block bb, tree expr)
|
||||
{
|
||||
tree t;
|
||||
|
||||
gcc_checking_assert (bb);
|
||||
if (!Value_Range::supports_type_p (TREE_TYPE (expr)))
|
||||
return NULL_TREE;
|
||||
|
||||
Value_Range r (TREE_TYPE (expr));
|
||||
|
||||
if (range_on_exit (r, bb, expr) && r.singleton_p (&t))
|
||||
return t;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -130,11 +187,36 @@ range_query::~range_query ()
|
|||
{
|
||||
}
|
||||
|
||||
// Return a range in R for the tree EXPR. Return true if a range is
|
||||
// representable, and UNDEFINED/false if not.
|
||||
// This routine will invoke the equivalent of range_of_expr on
|
||||
// either a gimple statement STMT, on entry to block BBENTRY, or on
|
||||
// exit from block BBEXIT. Only one of these 3 fields may be set.
|
||||
// It is valid for none of them to be set, in wqhich case there is no context.
|
||||
|
||||
bool
|
||||
range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
|
||||
range_query::invoke_range_of_expr (vrange &r, tree expr, gimple *stmt,
|
||||
basic_block bbentry, basic_block bbexit)
|
||||
{
|
||||
if (bbentry)
|
||||
{
|
||||
gcc_checking_assert (!stmt && !bbexit);
|
||||
return range_on_entry (r, bbentry, expr);
|
||||
}
|
||||
if (bbexit)
|
||||
{
|
||||
gcc_checking_assert (!stmt);
|
||||
return range_on_exit (r, bbexit, expr);
|
||||
}
|
||||
|
||||
return range_of_expr (r, expr, stmt);
|
||||
}
|
||||
|
||||
// Return a range in R for the tree EXPR. The context can be either a STMT,
|
||||
// or on entry to block BBENTRY or exit from block BBEXIT.
|
||||
// Return true if a range is representable, and UNDEFINED/false if not.
|
||||
|
||||
bool
|
||||
range_query::get_tree_range (vrange &r, tree expr, gimple *stmt,
|
||||
basic_block bbentry, basic_block bbexit)
|
||||
{
|
||||
tree type;
|
||||
if (TYPE_P (expr))
|
||||
|
@ -180,6 +262,9 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
|
|||
}
|
||||
|
||||
case SSA_NAME:
|
||||
// If this is not an abnormal or virtual ssa, invoke range_of_expr.
|
||||
if (gimple_range_ssa_p (expr))
|
||||
return invoke_range_of_expr (r, expr, stmt, bbentry, bbexit);
|
||||
gimple_range_global (r, expr);
|
||||
return true;
|
||||
|
||||
|
@ -210,8 +295,8 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
|
|||
{
|
||||
Value_Range r0 (TREE_TYPE (op0));
|
||||
Value_Range r1 (TREE_TYPE (op1));
|
||||
range_of_expr (r0, op0, stmt);
|
||||
range_of_expr (r1, op1, stmt);
|
||||
invoke_range_of_expr (r0, op0, stmt, bbentry, bbexit);
|
||||
invoke_range_of_expr (r1, op1, stmt, bbentry, bbexit);
|
||||
if (!op.fold_range (r, type, r0, r1))
|
||||
r.set_varying (type);
|
||||
}
|
||||
|
@ -228,7 +313,8 @@ range_query::get_tree_range (vrange &r, tree expr, gimple *stmt)
|
|||
Value_Range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
|
||||
Value_Range r1 (type);
|
||||
r1.set_varying (type);
|
||||
range_of_expr (r0, TREE_OPERAND (expr, 0), stmt);
|
||||
invoke_range_of_expr (r0, TREE_OPERAND (expr, 0), stmt, bbentry,
|
||||
bbexit);
|
||||
if (!op.fold_range (r, type, r0, r1))
|
||||
r.set_varying (type);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,8 @@ public:
|
|||
virtual tree value_of_expr (tree expr, gimple * = NULL);
|
||||
virtual tree value_on_edge (edge, tree expr);
|
||||
virtual tree value_of_stmt (gimple *, tree name = NULL);
|
||||
virtual tree value_on_entry (basic_block, tree expr);
|
||||
virtual tree value_on_exit (basic_block, tree expr);
|
||||
|
||||
// These are the range equivalents of the value_* methods. Instead
|
||||
// of returning a singleton, they calculate a range and return it in
|
||||
|
@ -70,6 +72,8 @@ public:
|
|||
virtual bool range_of_expr (vrange &r, tree expr, gimple * = NULL) = 0;
|
||||
virtual bool range_on_edge (vrange &r, edge, tree expr);
|
||||
virtual bool range_of_stmt (vrange &r, gimple *, tree name = NULL);
|
||||
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,
|
||||
|
@ -82,7 +86,10 @@ public:
|
|||
virtual void dump (FILE *);
|
||||
|
||||
protected:
|
||||
bool get_tree_range (vrange &v, tree expr, gimple *stmt);
|
||||
bool get_tree_range (vrange &v, tree expr, gimple *stmt,
|
||||
basic_block bbentry = NULL, basic_block bbexit = NULL);
|
||||
bool invoke_range_of_expr (vrange &v, tree expr, gimple *stmt,
|
||||
basic_block bbentry, basic_block bbexit);
|
||||
bool get_arith_expr_range (vrange &r, tree expr, gimple *stmt);
|
||||
relation_oracle *m_oracle;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue