diff options
author | Andrew Macleod <amacleod@redhat.com> | 2019-09-04 19:08:23 +0000 |
---|---|---|
committer | Andrew Macleod <amacleod@redhat.com> | 2019-09-04 19:08:23 +0000 |
commit | 18dd89d1114cbee3099b2da05997f811f47456ef (patch) | |
tree | da808407e519abe23c7b2026662c08ead89e67e3 | |
parent | ebb00f2f2a2ccfb8c5caa9c49aa11657105ae830 (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.cc | 50 | ||||
-rw-r--r-- | gcc/grange.h | 17 | ||||
-rw-r--r-- | gcc/ssa-range-cache.cc | 2 | ||||
-rw-r--r-- | gcc/ssa-range-gori.cc | 13 | ||||
-rw-r--r-- | gcc/ssa-range.cc | 133 | ||||
-rw-r--r-- | gcc/ssa-range.h | 9 |
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); |