aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-query.cc
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2024-03-13 14:18:48 -0400
committerAndrew MacLeod <amacleod@redhat.com>2024-04-30 17:19:57 -0400
commit39fe620963b29e7bdc8dcfa2037490df26b4edf2 (patch)
tree306a72fa5b36955edabcf70160912511587b4f19 /gcc/value-query.cc
parent0ade358cd72ffa591dd2f1404765b379bbf709d4 (diff)
downloadgcc-39fe620963b29e7bdc8dcfa2037490df26b4edf2.zip
gcc-39fe620963b29e7bdc8dcfa2037490df26b4edf2.tar.gz
gcc-39fe620963b29e7bdc8dcfa2037490df26b4edf2.tar.bz2
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.
Diffstat (limited to 'gcc/value-query.cc')
-rw-r--r--gcc/value-query.cc100
1 files changed, 93 insertions, 7 deletions
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index e88c8e2..c2ab745 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -42,6 +42,18 @@ range_query::range_on_edge (vrange &r, edge, tree 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)
{
if (!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::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)
+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);
}