summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2021-09-22 16:58:22 -0400
committerAndrew MacLeod <amacleod@redhat.com>2021-09-23 12:56:43 -0400
commit053e1d642104d19d5f9e5fb08a9e7354a0db28f5 (patch)
tree0e842f9e1c0fdd1788cb7465c2ac4f14b397b519
parent1b07d9dce6c51c98d011236c3d4cd84a2ed59ba2 (diff)
downloadgcc-053e1d642104d19d5f9e5fb08a9e7354a0db28f5.tar.gz
Create a ranger-local flag for non-executable edges.
Instead of repurposing EDGE_EXECUTABLE, ranger creates a local flag and ultizes it throughout. * gimple-range-cache.cc (ranger_cache::ranger_cache): Take non-executable_edge flag as parameter. * gimple-range-cache.h (ranger_cache): Adjust prototype. * gimple-range-gori.cc (gori_compute::gori_compute): Take non-executable_edge flag as parameter. (gori_compute::outgoing_edge_range_p): Check new flag. * gimple-range-gori.h (gori_compute): Adjust prototype. * gimple-range.cc (gimple_ranger::gimple_ranger): Create new flag. (gimple_ranger::range_on_edge): Check new flag. * gimple-range.h (gimple_ranger::non_executable_edge_flag): New. * gimple-ssa-evrp.c (rvrp_folder): Pass ranger flag to simplifer. (hybrid_folder::hybrid_folder): Set ranger non-executable flag value. (hybrid_folder::fold_stmt): Set flag value in the simplifer. * vr-values.c (simplify_using_ranges::set_and_propagate_unexecutable): Use not_executable flag if provided inmstead of EDGE_EXECUTABLE. (simplify_using_ranges::simplify_switch_using_ranges): Clear EDGE_EXECUTABLE like it originally did. (simplify_using_ranges::cleanup_edges_and_switches): Clear any NON_EXECUTABLE flags. (simplify_using_ranges::simplify_using_ranges): Adjust. * vr-values.h (class simplify_using_ranges): Adjust. (simplify_using_ranges::set_range_query): Add non-executable flag param.
-rw-r--r--gcc/gimple-range-cache.cc3
-rw-r--r--gcc/gimple-range-cache.h2
-rw-r--r--gcc/gimple-range-gori.cc5
-rw-r--r--gcc/gimple-range-gori.h7
-rw-r--r--gcc/gimple-range.cc22
-rw-r--r--gcc/gimple-range.h1
-rw-r--r--gcc/gimple-ssa-evrp.c12
-rw-r--r--gcc/vr-values.c24
-rw-r--r--gcc/vr-values.h8
9 files changed, 64 insertions, 20 deletions
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index b856b212169..61043d3f375 100644
--- a/gcc/gimple-range-cache.cc
+++ b/gcc/gimple-range-cache.cc
@@ -750,7 +750,8 @@ temporal_cache::set_always_current (tree name)
// --------------------------------------------------------------------------
-ranger_cache::ranger_cache ()
+ranger_cache::ranger_cache (int not_executable_flag)
+ : m_gori (not_executable_flag)
{
m_workback.create (0);
m_workback.safe_grow_cleared (last_basic_block_for_fn (cfun));
diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h
index 3b55673fd29..4937a0b305a 100644
--- a/gcc/gimple-range-cache.h
+++ b/gcc/gimple-range-cache.h
@@ -92,7 +92,7 @@ private:
class ranger_cache : public range_query
{
public:
- ranger_cache ();
+ ranger_cache (int not_executable_flag);
~ranger_cache ();
virtual bool range_of_expr (irange &r, tree name, gimple *stmt);
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index f5a35287bed..4a1ade7f921 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -634,8 +634,9 @@ debug (gori_map &g)
// Construct a gori_compute object.
-gori_compute::gori_compute () : tracer ("GORI ")
+gori_compute::gori_compute (int not_executable_flag) : tracer ("GORI ")
{
+ m_not_executable_flag = not_executable_flag;
// Create a boolean_type true and false range.
m_bool_zero = int_range<2> (boolean_false_node, boolean_false_node);
m_bool_one = int_range<2> (boolean_true_node, boolean_true_node);
@@ -1214,7 +1215,7 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name,
int_range_max lhs;
unsigned idx;
- if ((e->flags & EDGE_EXECUTABLE) == 0)
+ if ((e->flags & m_not_executable_flag))
{
r.set_undefined ();
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h
index 688468c8790..ec0b95145f0 100644
--- a/gcc/gimple-range-gori.h
+++ b/gcc/gimple-range-gori.h
@@ -147,12 +147,16 @@ private:
// expr_range_in_bb is simply a wrapper which calls ssa_range_in_bb for
// SSA_NAMES and otherwise simply calculates the range of the expression.
//
+// The constructor takes a flag value to use on edges to check for the
+// NON_EXECUTABLE_EDGE property. The zero default means no flag is checked.
+// All value requests from NON_EXECUTABLE_EDGE edges are returned UNDEFINED.
+//
// The remaining routines are internal use only.
class gori_compute : public gori_map
{
public:
- gori_compute ();
+ gori_compute (int not_executable_flag = 0);
bool outgoing_edge_range_p (irange &r, edge e, tree name, range_query &q);
bool has_edge_range_p (tree name, edge e = NULL);
void dump (FILE *f);
@@ -181,6 +185,7 @@ private:
gimple_outgoing_range outgoing; // Edge values for COND_EXPR & SWITCH_EXPR.
range_tracer tracer;
+ int m_not_executable_flag;
};
// These routines provide a GIMPLE interface to the range-ops code.
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 625d13647f7..d4108db1855 100644
--- a/gcc/gimple-range.cc
+++ b/gcc/gimple-range.cc
@@ -34,15 +34,29 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "gimple-range.h"
-#include "domwalk.h"
-gimple_ranger::gimple_ranger () : tracer ("")
+gimple_ranger::gimple_ranger () :
+ non_executable_edge_flag (cfun),
+ m_cache (non_executable_edge_flag),
+ tracer ("")
{
// If the cache has a relation oracle, use it.
m_oracle = m_cache.oracle ();
if (dump_file && (param_evrp_mode & EVRP_MODE_TRACE))
tracer.enable_trace ();
- set_all_edges_as_executable (cfun);
+
+ // Ensure the not_executable flag is clear everywhere.
+ if (flag_checking)
+ {
+ basic_block bb;
+ FOR_ALL_BB_FN (bb, cfun)
+ {
+ edge_iterator ei;
+ edge e;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ gcc_checking_assert ((e->flags & non_executable_edge_flag) == 0);
+ }
+ }
}
bool
@@ -174,7 +188,7 @@ gimple_ranger::range_on_edge (irange &r, edge e, tree name)
}
// Check to see if the edge is executable.
- if ((e->flags & EDGE_EXECUTABLE) == 0)
+ if ((e->flags & non_executable_edge_flag))
{
r.set_undefined ();
if (idx)
diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h
index eaebb9c5833..191a075a1b0 100644
--- a/gcc/gimple-range.h
+++ b/gcc/gimple-range.h
@@ -56,6 +56,7 @@ public:
inline gori_compute &gori () { return m_cache.m_gori; }
virtual void dump (FILE *f) OVERRIDE;
void dump_bb (FILE *f, basic_block bb);
+ auto_edge_flag non_executable_edge_flag;
protected:
bool fold_range_internal (irange &r, gimple *s, tree name);
ranger_cache m_cache;
diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index 254542ef4cc..437f19471f1 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -121,7 +121,7 @@ public:
rvrp_folder () : substitute_and_fold_engine (), m_simplifier ()
{
m_ranger = enable_ranger (cfun);
- m_simplifier.set_range_query (m_ranger);
+ m_simplifier.set_range_query (m_ranger, m_ranger->non_executable_edge_flag);
m_pta = new pointer_equiv_analyzer (m_ranger);
}
@@ -205,12 +205,16 @@ public:
if (evrp_first)
{
first = &m_range_analyzer;
+ first_exec_flag = 0;
second = m_ranger;
+ second_exec_flag = m_ranger->non_executable_edge_flag;
}
else
{
first = m_ranger;
+ first_exec_flag = m_ranger->non_executable_edge_flag;
second = &m_range_analyzer;
+ second_exec_flag = 0;
}
m_pta = new pointer_equiv_analyzer (m_ranger);
}
@@ -227,11 +231,11 @@ public:
bool fold_stmt (gimple_stmt_iterator *gsi) OVERRIDE
{
- simplifier.set_range_query (first);
+ simplifier.set_range_query (first, first_exec_flag);
if (simplifier.simplify (gsi))
return true;
- simplifier.set_range_query (second);
+ simplifier.set_range_query (second, second_exec_flag);
if (simplifier.simplify (gsi))
{
if (dump_file)
@@ -267,7 +271,9 @@ private:
DISABLE_COPY_AND_ASSIGN (hybrid_folder);
gimple_ranger *m_ranger;
range_query *first;
+ int first_exec_flag;
range_query *second;
+ int second_exec_flag;
pointer_equiv_analyzer *m_pta;
tree choose_value (tree evrp_val, tree ranger_val);
};
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 3b8d0674471..9bf58f416f2 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -3460,19 +3460,21 @@ range_fits_type_p (const value_range *vr,
void
simplify_using_ranges::set_and_propagate_unexecutable (edge e)
{
- // If EXECUUTABLE is already clear, we're done.
- if ((e->flags & EDGE_EXECUTABLE) == 0)
+ // If not_executable is already set, we're done.
+ // This works in the absence of a flag as well.
+ if ((e->flags & m_not_executable_flag) == m_not_executable_flag)
return;
- e->flags &= ~EDGE_EXECUTABLE;
+ e->flags |= m_not_executable_flag;
+ m_flag_set_edges.safe_push (e);
// Check if the destination block needs to propagate the property.
basic_block bb = e->dest;
- // If any entry edge is marked EXECUTABLE, we are done.
+ // If any incoming edge is executable, we are done.
edge_iterator ei;
FOR_EACH_EDGE (e, ei, bb->preds)
- if (e->flags & EDGE_EXECUTABLE)
+ if ((e->flags & m_not_executable_flag) == 0)
return;
// This block is also unexecutable, propagate to all exit edges as well.
@@ -3805,6 +3807,7 @@ simplify_using_ranges::simplify_switch_using_ranges (gswitch *stmt)
}
to_remove_edges.safe_push (e);
set_and_propagate_unexecutable (e);
+ e->flags &= ~EDGE_EXECUTABLE;
e->flags |= EDGE_IGNORE;
}
@@ -3822,6 +3825,12 @@ simplify_using_ranges::cleanup_edges_and_switches (void)
edge e;
switch_update *su;
+ /* Clear any edges marked as not executable. */
+ if (m_not_executable_flag)
+ {
+ FOR_EACH_VEC_ELT (m_flag_set_edges, i, e)
+ e->flags &= ~m_not_executable_flag;
+ }
/* Remove dead edges from SWITCH_EXPR optimization. This leaves the
CFG in a broken state and requires a cfg_cleanup run. */
FOR_EACH_VEC_ELT (to_remove_edges, i, e)
@@ -4124,11 +4133,14 @@ simplify_using_ranges::two_valued_val_range_p (tree var, tree *a, tree *b,
return false;
}
-simplify_using_ranges::simplify_using_ranges (range_query *query)
+simplify_using_ranges::simplify_using_ranges (range_query *query,
+ int not_executable_flag)
: query (query)
{
to_remove_edges = vNULL;
to_update_switch_stmts = vNULL;
+ m_not_executable_flag = not_executable_flag;
+ m_flag_set_edges = vNULL;
}
simplify_using_ranges::~simplify_using_ranges ()
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 46939081c61..821bcb9d58d 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -30,9 +30,11 @@ along with GCC; see the file COPYING3. If not see
class simplify_using_ranges
{
public:
- simplify_using_ranges (class range_query *query = NULL);
+ simplify_using_ranges (range_query *query = NULL,
+ int not_executable_flag = 0);
~simplify_using_ranges ();
- void set_range_query (class range_query *q) { query = q; }
+ void set_range_query (class range_query *q, int not_executable_flag = 0)
+ { query = q; m_not_executable_flag = not_executable_flag; }
bool simplify (gimple_stmt_iterator *);
@@ -82,6 +84,8 @@ private:
vec<edge> to_remove_edges;
vec<switch_update> to_update_switch_stmts;
class range_query *query;
+ int m_not_executable_flag; // Non zero if not_executable flag exists.
+ vec<edge> m_flag_set_edges; // List of edges with flag to be cleared.
};
/* The VR_VALUES class holds the current view of range information