aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Macleod <amacleod@redhat.com>2019-09-04 19:08:23 +0000
committerAndrew Macleod <amacleod@redhat.com>2019-09-04 19:08:23 +0000
commit18dd89d1114cbee3099b2da05997f811f47456ef (patch)
treeda808407e519abe23c7b2026662c08ead89e67e3
parentebb00f2f2a2ccfb8c5caa9c49aa11657105ae830 (diff)
pull range_of_ssa_nme out of range_of_expr, then combine get_tree_range with range_of_expr
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ssa-range@275380 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/grange.cc50
-rw-r--r--gcc/grange.h17
-rw-r--r--gcc/ssa-range-cache.cc2
-rw-r--r--gcc/ssa-range-gori.cc13
-rw-r--r--gcc/ssa-range.cc133
-rw-r--r--gcc/ssa-range.h9
6 files changed, 120 insertions, 104 deletions
diff --git a/gcc/grange.cc b/gcc/grange.cc
index 65c1f897000..b7fe2dec6c1 100644
--- a/gcc/grange.cc
+++ b/gcc/grange.cc
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
#include "wide-int.h"
#include "range.h"
#include "grange.h"
+#include "ssa-range.h"
// This file implements the gimple range statement and associated data.
// the grange_op statement kind provides access to the range-op fold machinery
@@ -60,55 +61,6 @@ along with GCC; see the file COPYING3. If not see
// table where a class is implemented for a given tree code, and
// auto-registered into the table for use when it is encountered.
-// This function returns a range for tree node EXPR in R. Return
-// false if ranges are not supported.
-
-irange
-get_tree_range (tree expr)
-{
- tree type;
- if (TYPE_P (expr))
- type = expr;
- else
- type = TREE_TYPE (expr);
-
- gcc_checking_assert (irange::supports_type_p (type));
-
- switch (TREE_CODE (expr))
- {
- case INTEGER_CST:
- // If we encounter an overflow, simply punt and drop to varying
- // since we have no idea how it will be used.
- if (!TREE_OVERFLOW_P (expr))
- return irange (expr, expr);
- break;
-
- case SSA_NAME:
- if (irange::supports_ssa_p (expr) && SSA_NAME_RANGE_INFO (expr)
- && !POINTER_TYPE_P (type))
- {
- // Return a range from an SSA_NAME's available range.
- wide_int min, max;
- enum value_range_kind kind = get_range_info (expr, &min, &max);
- return irange (kind, type, min, max);
- }
- break;
-
- case ADDR_EXPR:
- {
- // handle &var which can show up in phi arguments
- bool ov;
- if (tree_single_nonzero_warnv_p (expr, &ov))
- return range_nonzero (type);
- break;
- }
-
- default:
- break;
- }
- return irange (type);
-}
-
static gimple *
calc_single_range (irange &r, gswitch *sw, edge e)
{
diff --git a/gcc/grange.h b/gcc/grange.h
index fa115bec10c..973e5a243d6 100644
--- a/gcc/grange.h
+++ b/gcc/grange.h
@@ -27,7 +27,6 @@ along with GCC; see the file COPYING3. If not see
extern gimple_stmt_iterator gsi_outgoing_range_stmt (basic_block bb);
extern gimple *gimple_outgoing_range_stmt_p (basic_block bb);
extern gimple *gimple_outgoing_edge_range_p (irange &r, edge e);
-extern irange get_tree_range (tree expr);
static inline tree
valid_range_ssa_p (tree exp)
@@ -37,6 +36,22 @@ valid_range_ssa_p (tree exp)
return NULL_TREE;
}
+static inline irange
+ssa_name_range (tree name)
+{
+ gcc_checking_assert (irange::supports_ssa_p (name));
+ tree type = TREE_TYPE (name);
+ if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
+ {
+ // Return a range from an SSA_NAME's available range.
+ wide_int min, max;
+ enum value_range_kind kind = get_range_info (name, &min, &max);
+ return irange (kind, type, min, max);
+ }
+ // Otherwise return range for the type.
+ return irange (type);
+}
+
// Gimple statement which supports range_op operations.
// This can map to gimple assign or cond statements, so quick access to the
// operands is provided so the user does not need to know which it is.
diff --git a/gcc/ssa-range-cache.cc b/gcc/ssa-range-cache.cc
index 53af02bf039..72325b0090b 100644
--- a/gcc/ssa-range-cache.cc
+++ b/gcc/ssa-range-cache.cc
@@ -578,7 +578,7 @@ gori_cache::edge_range (irange &r, edge e, tree name)
{
// Try to pick up any known value first.
if (!m_globals.get_global_range (r, name))
- r = get_tree_range (name);
+ r = ssa_name_range (name);
}
}
else
diff --git a/gcc/ssa-range-gori.cc b/gcc/ssa-range-gori.cc
index 8540fbab0e8..a11241702db 100644
--- a/gcc/ssa-range-gori.cc
+++ b/gcc/ssa-range-gori.cc
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "grange.h"
#include "ssa-range-gori.h"
#include "fold-const.h"
+#include "ssa-range.h"
// Construct a range_def_chain
@@ -478,10 +479,14 @@ gori_map::dump(FILE *f)
static irange
get_tree_range (tree expr, tree name, irange *range_of_name)
{
+ static stmt_ranger sr;
if (expr != name || !range_of_name)
- return get_tree_range (expr);
+ {
+ irange r;
+ gcc_assert (sr.range_of_expr (r, expr));
+ return r;
+ }
- gcc_checking_assert (range_of_name != NULL);
return *range_of_name;
}
@@ -1128,7 +1133,7 @@ gori_compute::range_from_import (irange &r, tree name, irange &import_range)
res = range_from_import (r1, op1, import_range);
}
else
- r1 = get_tree_range (op1);
+ r1 = get_tree_range (op1, NULL_TREE, NULL);
if (!res)
return false;
@@ -1144,7 +1149,7 @@ gori_compute::range_from_import (irange &r, tree name, irange &import_range)
res = range_from_import (r2, op2, import_range);
}
else
- r2 = get_tree_range (op2);
+ r2 = get_tree_range (op2, NULL_TREE, NULL);
if (res)
return s->fold (r, r1, r2);
diff --git a/gcc/ssa-range.cc b/gcc/ssa-range.cc
index a498329824f..b0e93b182c6 100644
--- a/gcc/ssa-range.cc
+++ b/gcc/ssa-range.cc
@@ -65,14 +65,60 @@ stmt_ranger::~stmt_ranger ()
{
}
+irange
+stmt_ranger::range_of_ssa_name (tree name, gimple *s ATTRIBUTE_UNUSED)
+{
+ return ssa_name_range (name);
+}
+
// This function returns a range for a tree node. If optional statement S
// is present, then the range would be if it were to appear as a use on S.
// Return false if ranges are not supported.
bool
-stmt_ranger::range_of_expr (irange &r, tree expr, gimple *s ATTRIBUTE_UNUSED)
+stmt_ranger::range_of_expr (irange &r, tree expr, gimple *s)
{
- r = get_tree_range (expr);
+ tree type;
+ if (TYPE_P (expr))
+ type = expr;
+ else
+ type = TREE_TYPE (expr);
+
+ if (!irange::supports_type_p (type))
+ return false;
+
+ switch (TREE_CODE (expr))
+ {
+ case INTEGER_CST:
+ // If we encounter an overflow, simply punt and drop to varying
+ // since we have no idea how it will be used.
+ if (!TREE_OVERFLOW_P (expr))
+ {
+ r = irange (expr, expr);
+ return true;
+ }
+ break;
+
+ case SSA_NAME:
+ r = range_of_ssa_name (expr, s);
+ return true;
+
+ case ADDR_EXPR:
+ {
+ // handle &var which can show up in phi arguments
+ bool ov;
+ if (tree_single_nonzero_warnv_p (expr, &ov))
+ {
+ r = range_nonzero (type);
+ return true;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ r = irange (type);
return true;
}
@@ -108,7 +154,7 @@ stmt_ranger::range_of_stmt (irange &r, gimple *s, tree name)
return true;
}
// We don't understand the stmt, so return the global range.
- r = get_tree_range (name);
+ r = ssa_name_range (name);
return true;
}
if (res)
@@ -420,7 +466,7 @@ ssa_ranger::range_on_edge (irange &r, edge e, tree name)
if (!valid_range_ssa_p (name))
{
- r = get_tree_range (name);
+ gcc_assert (range_of_expr (r, name));
return;
}
range_on_exit (r, e->src, name);
@@ -638,7 +684,7 @@ global_ranger::range_of_stmt (irange &r, gimple *s, tree name)
return true;
// Avoid infinite recursion by initializing global cache
- irange tmp = get_tree_range (name);
+ irange tmp = ssa_name_range (name);
m_gori.m_globals.set_global_range (name, tmp);
gcc_assert (ssa_ranger::range_of_stmt (r, s, name));
@@ -652,41 +698,37 @@ global_ranger::range_of_stmt (irange &r, gimple *s, tree name)
// Determine a range for OP on stmt S, returning the result in R.
// If OP is not defined in BB, find the range on entry to this block.
-bool
-global_ranger::range_of_expr (irange &r, tree op, gimple *s)
+irange
+global_ranger::range_of_ssa_name (tree name, gimple *s)
{
- if (!irange::supports_p (op))
- return false;
+ // If there is no statement, just get the global value.
+ if (!s)
+ return ssa_name_range (name);
- // If there is a statement, and a valid ssa_name, try to find a range.
- if (s && valid_range_ssa_p (op))
- {
- basic_block bb = gimple_bb (s);
- gimple *def_stmt = SSA_NAME_DEF_STMT (op);
-
- // if name is defined in this block, try to get an range from S.
- if (def_stmt && gimple_bb (def_stmt) == bb)
- gcc_assert (range_of_stmt (r, def_stmt, op));
- else
- // Otherwise OP comes from outside this block, use range on entry.
- range_on_entry (r, bb, op);
-
- // No range yet, see if there is a dereference in the block.
- // We don't care if it's between the def and a use within a block
- // because the entire block must be executed anyway.
- // FIXME:?? For non-call exceptions we could have a statement throw
- // which causes an early block exit.
- // in which case we may need to walk from S back to the def/top of block
- // to make sure the deref happens between S and there before claiming
- // there is a deref. Punt for now.
- if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
- m_gori.non_null_deref_p (op, bb))
- r = range_nonzero (TREE_TYPE (op));
- return true;
- }
+ irange r;
+ basic_block bb = gimple_bb (s);
+ gimple *def_stmt = SSA_NAME_DEF_STMT (name);
+
+ // if name is defined in this block, try to get an range from S.
+ if (def_stmt && gimple_bb (def_stmt) == bb)
+ gcc_assert (range_of_stmt (r, def_stmt, name));
+ else
+ // Otherwise OP comes from outside this block, use range on entry.
+ range_on_entry (r, bb, name);
- // Fall back to the default.
- return ssa_ranger::range_of_expr (r, op);
+ // No range yet, see if there is a dereference in the block.
+ // We don't care if it's between the def and a use within a block
+ // because the entire block must be executed anyway.
+ // FIXME:?? For non-call exceptions we could have a statement throw
+ // which causes an early block exit.
+ // in which case we may need to walk from S back to the def/top of block
+ // to make sure the deref happens between S and there before claiming
+ // there is a deref. Punt for now.
+ if (!cfun->can_throw_non_call_exceptions && r.varying_p () &&
+ m_gori.non_null_deref_p (name, bb))
+ r = range_nonzero (TREE_TYPE (name));
+
+ return r;
}
// Calculate a range on edge E and return it in R. Try to evaluate a range
@@ -731,7 +773,7 @@ global_ranger::export_global_ranges ()
{
// Make sure the new range is a subset of the old range.
irange old_range;
- old_range = get_tree_range (name);
+ old_range = ssa_name_range (name);
old_range.intersect (r);
/* Disable this while we fix tree-ssa/pr61743-2.c. */
//gcc_checking_assert (old_range == r);
@@ -1008,15 +1050,15 @@ trace_ranger::trailer (unsigned counter, const char *caller, bool result,
// Tracing version of range_of_expr. Call it with printing wrappers.
-bool
-trace_ranger::range_of_expr (irange &r, tree expr, gimple *s)
+irange
+trace_ranger::range_of_ssa_name (tree name, gimple *s)
{
- bool res;
+ irange r;
unsigned idx = ++trace_count;
if (dumping (idx))
{
- fprintf (dump_file, "range_of_expr (");
- print_generic_expr (dump_file, expr, TDF_SLIM);
+ fprintf (dump_file, "range_of_ssa_name (");
+ print_generic_expr (dump_file, name, TDF_SLIM);
fprintf (dump_file, ") at stmt ");
if (s)
print_gimple_stmt (dump_file, s , 0, TDF_SLIM);
@@ -1025,9 +1067,10 @@ trace_ranger::range_of_expr (irange &r, tree expr, gimple *s)
indent += bump;
}
- res = super::range_of_expr (r, expr, s);
+ r = super::range_of_ssa_name (name, s);
- return trailer (idx, "range_of_expr", res, expr, r);
+ trailer (idx, "range_of_ssa_name", true, name, r);
+ return r;
}
// Tracing version of range_on_edge. Call it with printing wrappers.
diff --git a/gcc/ssa-range.h b/gcc/ssa-range.h
index 38a15a7fc92..7209403fdf8 100644
--- a/gcc/ssa-range.h
+++ b/gcc/ssa-range.h
@@ -47,8 +47,9 @@ class stmt_ranger
public:
stmt_ranger ();
~stmt_ranger ();
-
- virtual bool range_of_expr (irange &r, tree expr, gimple *s = NULL);
+
+ bool range_of_expr (irange &r, tree expr, gimple *s = NULL);
+ virtual irange range_of_ssa_name (tree name, gimple *s = NULL);
virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
virtual bool range_of_stmt_with_range (irange &r, gimple *s, tree name,
const irange &name_range);
@@ -126,7 +127,7 @@ public:
global_ranger ();
~global_ranger ();
- virtual bool range_of_expr (irange &r, tree op, gimple *s = NULL);
+ virtual irange range_of_ssa_name (tree name, gimple *s = NULL);
virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
virtual void range_on_entry (irange &r, basic_block bb, tree name);
@@ -167,7 +168,7 @@ class trace_ranger : public loop_ranger
public:
trace_ranger();
- virtual bool range_of_expr (irange &r, tree expr, gimple *s = NULL);
+ virtual irange range_of_ssa_name (tree name, gimple *s = NULL);
virtual bool range_of_stmt (irange &r, gimple *s, tree name = NULL_TREE);
virtual void range_on_edge (irange &r, edge e, tree name);
virtual void range_on_entry (irange &r, basic_block bb, tree name);