diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2021-09-22 16:58:22 -0400 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2021-09-23 12:56:43 -0400 |
commit | 053e1d642104d19d5f9e5fb08a9e7354a0db28f5 (patch) | |
tree | 0e842f9e1c0fdd1788cb7465c2ac4f14b397b519 | |
parent | 1b07d9dce6c51c98d011236c3d4cd84a2ed59ba2 (diff) | |
download | gcc-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.cc | 3 | ||||
-rw-r--r-- | gcc/gimple-range-cache.h | 2 | ||||
-rw-r--r-- | gcc/gimple-range-gori.cc | 5 | ||||
-rw-r--r-- | gcc/gimple-range-gori.h | 7 | ||||
-rw-r--r-- | gcc/gimple-range.cc | 22 | ||||
-rw-r--r-- | gcc/gimple-range.h | 1 | ||||
-rw-r--r-- | gcc/gimple-ssa-evrp.c | 12 | ||||
-rw-r--r-- | gcc/vr-values.c | 24 | ||||
-rw-r--r-- | gcc/vr-values.h | 8 |
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 |