aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/function.c4
-rw-r--r--gcc/function.h17
-rw-r--r--gcc/gimple-range-cache.cc1
-rw-r--r--gcc/gimple-range.cc126
-rw-r--r--gcc/gimple-range.h60
-rw-r--r--gcc/gimple-ssa-evrp.c2
-rw-r--r--gcc/tree-vrp.c2
-rw-r--r--gcc/value-query.cc5
-rw-r--r--gcc/value-query.h1
-rw-r--r--gcc/vr-values.c2
-rw-r--r--gcc/vr-values.h2
11 files changed, 172 insertions, 50 deletions
diff --git a/gcc/function.c b/gcc/function.c
index fc7b147..6757695 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "options.h"
#include "function-abi.h"
+#include "value-range.h"
+#include "gimple-range.h"
/* So we can assign to cfun in this file. */
#undef cfun
@@ -4856,6 +4858,8 @@ allocate_struct_function (tree fndecl, bool abstract_p)
binding annotations among them. */
cfun->debug_nonbind_markers = lang_hooks.emits_begin_stmt
&& MAY_HAVE_DEBUG_MARKER_STMTS;
+
+ cfun->x_range_query = &global_ranges;
}
/* This is like allocate_struct_function, but pushes a new cfun for FNDECL
diff --git a/gcc/function.h b/gcc/function.h
index 66cfa97..0db5177 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -157,6 +157,7 @@ struct GTY(()) rtl_eh {
struct gimple_df;
struct call_site_record_d;
struct dw_fde_node;
+class range_query;
struct GTY(()) varasm_status {
/* If we're using a per-function constant pool, this is it. */
@@ -309,6 +310,11 @@ struct GTY(()) function {
debugging is enabled. */
struct dw_fde_node *fde;
+ /* Range query mechanism for functions. The default is to pick up
+ global ranges. If a pass wants on-demand ranges OTOH, it must
+ call enable/disable_ranger(). */
+ range_query * GTY ((skip)) x_range_query;
+
/* Last statement uid. */
int last_stmt_uid;
@@ -712,4 +718,15 @@ extern const char *current_function_name (void);
extern void used_types_insert (tree);
+/* Returns the currently active range access class. When there is no active
+ range class, global ranges are used. */
+
+inline range_query *
+get_range_query (struct function *fun)
+{
+ return fun->x_range_query;
+}
+
+extern range_query *get_global_range_query ();
+
#endif /* GCC_FUNCTION_H */
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 3969c4d..889cac1 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -384,7 +384,6 @@ block_range_cache::dump (FILE *f, basic_block bb, bool print_varying)
ssa_global_cache::ssa_global_cache ()
{
m_tab.create (0);
- m_tab.safe_grow_cleared (num_ssa_names);
m_irange_allocator = new irange_allocator;
}
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index e2d24d6..e351a84 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -1440,3 +1440,129 @@ trace_ranger::range_of_expr (irange &r, tree name, gimple *s)
return trailer (idx, "range_of_expr", res, name, r);
}
+
+// Return the legacy global range for NAME if it has one, otherwise
+// return VARYING.
+
+static void
+get_range_global (irange &r, tree name)
+{
+ tree type = TREE_TYPE (name);
+
+ if (SSA_NAME_IS_DEFAULT_DEF (name))
+ {
+ tree sym = SSA_NAME_VAR (name);
+ // Adapted from vr_values::get_lattice_entry().
+ // Use a range from an SSA_NAME's available range.
+ if (TREE_CODE (sym) == PARM_DECL)
+ {
+ // Try to use the "nonnull" attribute to create ~[0, 0]
+ // anti-ranges for pointers. Note that this is only valid with
+ // default definitions of PARM_DECLs.
+ if (POINTER_TYPE_P (type)
+ && ((cfun && nonnull_arg_p (sym)) || get_ptr_nonnull (name)))
+ r.set_nonzero (type);
+ else if (INTEGRAL_TYPE_P (type))
+ {
+ get_range_info (name, r);
+ if (r.undefined_p ())
+ r.set_varying (type);
+ }
+ else
+ r.set_varying (type);
+ }
+ // If this is a local automatic with no definition, use undefined.
+ else if (TREE_CODE (sym) != RESULT_DECL)
+ r.set_undefined ();
+ else
+ r.set_varying (type);
+ }
+ else if (!POINTER_TYPE_P (type) && SSA_NAME_RANGE_INFO (name))
+ {
+ get_range_info (name, r);
+ if (r.undefined_p ())
+ r.set_varying (type);
+ }
+ else if (POINTER_TYPE_P (type) && SSA_NAME_PTR_INFO (name))
+ {
+ if (get_ptr_nonnull (name))
+ r.set_nonzero (type);
+ else
+ r.set_varying (type);
+ }
+ else
+ r.set_varying (type);
+}
+
+// ?? Like above, but only for default definitions of NAME. This is
+// so VRP passes using ranger do not start with known ranges,
+// otherwise we'd eliminate builtin_unreachables too early because of
+// inlining.
+//
+// Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has
+// all of its unreachable calls removed too early. We should
+// investigate whether we should just adjust the test above.
+
+value_range
+gimple_range_global (tree name)
+{
+ gcc_checking_assert (gimple_range_ssa_p (name));
+ tree type = TREE_TYPE (name);
+
+ if (SSA_NAME_IS_DEFAULT_DEF (name))
+ {
+ value_range vr;
+ get_range_global (vr, name);
+ return vr;
+ }
+ return value_range (type);
+}
+
+// ----------------------------------------------
+// global_range_query implementation.
+
+global_range_query global_ranges;
+
+// Like get_range_query, but for accessing global ranges.
+
+range_query *
+get_global_range_query ()
+{
+ return &global_ranges;
+}
+
+bool
+global_range_query::range_of_expr (irange &r, tree expr, gimple *)
+{
+ tree type = TREE_TYPE (expr);
+
+ if (!irange::supports_type_p (type) || !gimple_range_ssa_p (expr))
+ return get_tree_range (r, expr);
+
+ get_range_global (r, expr);
+
+ return true;
+}
+
+gimple_ranger *
+enable_ranger (struct function *fun)
+{
+ gimple_ranger *r;
+
+ if (param_evrp_mode & EVRP_MODE_TRACE)
+ r = new trace_ranger;
+ else
+ r = new gimple_ranger;
+
+ fun->x_range_query = r;
+
+ return r;
+}
+
+void
+disable_ranger (struct function *fun)
+{
+ delete fun->x_range_query;
+
+ fun->x_range_query = &global_ranges;
+}
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index 707dcfe..23734c6 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -65,7 +65,7 @@ public:
virtual void range_on_entry (irange &r, basic_block bb, tree name);
virtual void range_on_exit (irange &r, basic_block bb, tree name);
void export_global_ranges ();
- void dump (FILE *f);
+ virtual void dump (FILE *f) OVERRIDE;
void dump_bb (FILE *f, basic_block bb);
protected:
bool fold_range_internal (irange &r, gimple *s, tree name);
@@ -227,50 +227,6 @@ range_compatible_p (tree type1, tree type2)
&& TYPE_SIGN (type1) == TYPE_SIGN (type2));
}
-// Return the legacy GCC global range for NAME if it has one, otherwise
-// return VARYING.
-
-static inline value_range
-gimple_range_global (tree name)
-{
- gcc_checking_assert (gimple_range_ssa_p (name));
- tree type = TREE_TYPE (name);
-
- if (SSA_NAME_IS_DEFAULT_DEF (name))
- {
- tree sym = SSA_NAME_VAR (name);
- // Adapted from vr_values::get_lattice_entry().
- // Use a range from an SSA_NAME's available range.
- if (TREE_CODE (sym) == PARM_DECL)
- {
- // Try to use the "nonnull" attribute to create ~[0, 0]
- // anti-ranges for pointers. Note that this is only valid with
- // default definitions of PARM_DECLs.
- if (POINTER_TYPE_P (type)
- && (nonnull_arg_p (sym) || get_ptr_nonnull (name)))
- {
- value_range r;
- r.set_nonzero (type);
- return r;
- }
- else if (INTEGRAL_TYPE_P (type))
- {
- value_range r;
- get_range_info (name, r);
- if (r.undefined_p ())
- r.set_varying (type);
- return r;
- }
- }
- // If this is a local automatic with no definition, use undefined.
- else if (TREE_CODE (sym) != RESULT_DECL)
- return value_range ();
- }
- // Otherwise return range for the type.
- return value_range (type);
-}
-
-
// This class overloads the ranger routines to provide tracing facilties
// Entry and exit values to each of the APIs is placed in the dumpfile.
@@ -296,4 +252,18 @@ private:
// Flag to enable debugging the various internal Caches.
#define DEBUG_RANGE_CACHE (dump_file && (param_evrp_mode & EVRP_MODE_DEBUG))
+// Global ranges for SSA names using SSA_NAME_RANGE_INFO.
+
+class global_range_query : public range_query
+{
+public:
+ bool range_of_expr (irange &r, tree expr, gimple * = NULL) OVERRIDE;
+};
+
+extern global_range_query global_ranges;
+extern value_range gimple_range_global (tree name);
+
+extern gimple_ranger *enable_ranger (struct function *);
+extern void disable_ranger (struct function *);
+
#endif // GCC_GIMPLE_RANGE_STMT_H
diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index 5f566ae..829fdcd 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -60,7 +60,7 @@ public:
if (dump_file)
{
fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
- m_range_analyzer.dump_all_value_ranges (dump_file);
+ m_range_analyzer.dump (dump_file);
fprintf (dump_file, "\n");
}
}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 12e6e6f..b0f1c47 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4044,7 +4044,7 @@ vrp_prop::finalize ()
if (dump_file)
{
fprintf (dump_file, "\nValue ranges after VRP:\n\n");
- m_vr_values->dump_all_value_ranges (dump_file);
+ m_vr_values->dump (dump_file);
fprintf (dump_file, "\n");
}
diff --git a/gcc/value-query.cc b/gcc/value-query.cc
index 4bb0897..509d2d3 100644
--- a/gcc/value-query.cc
+++ b/gcc/value-query.cc
@@ -135,6 +135,11 @@ range_query::value_of_stmt (gimple *stmt, tree name)
}
+void
+range_query::dump (FILE *)
+{
+}
+
// valuation_query support routines for value_range_equiv's.
class equiv_allocator : public object_allocator<value_range_equiv>
diff --git a/gcc/value-query.h b/gcc/value-query.h
index e2cbc68..5eff931 100644
--- a/gcc/value-query.h
+++ b/gcc/value-query.h
@@ -95,6 +95,7 @@ public:
// rewrite all uses of it to the above API.
virtual const class value_range_equiv *get_value_range (const_tree,
gimple * = NULL);
+ virtual void dump (FILE *);
protected:
class value_range_equiv *allocate_value_range_equiv ();
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 02bc0db..e0c8844 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -1819,7 +1819,7 @@ vr_values::adjust_range_with_scev (value_range_equiv *vr, class loop *loop,
/* Dump value ranges of all SSA_NAMEs to FILE. */
void
-vr_values::dump_all_value_ranges (FILE *file)
+vr_values::dump (FILE *file)
{
size_t i;
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 8c1b2e0..81b9131 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -116,7 +116,7 @@ class vr_values : public range_query
tree op_with_constant_singleton_value_range (tree);
void adjust_range_with_scev (value_range_equiv *, class loop *,
gimple *, tree);
- void dump_all_value_ranges (FILE *);
+ virtual void dump (FILE *) OVERRIDE;
void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
tree, tree,