RPO VN is driven through a couple free functions that we can abstract
out to a class to make things a bit tidier, and to make it easier to
call the back threader from within FRE to get value numbering for
free.
Make it an object that we can later sub-class into a path aware VN
object.
OK for trunk?
gcc/ChangeLog:
* tree-ssa-sccvn.h (class vn): New.
(run_rpo_vn, eliminate_with_rpo_vn, free_rpo_vn): Remove.
* tree-ssa-sccvn.cc (class eliminate_dom_walker): Make the
destructor virtual.
(eliminate_with_rpo_vn): Rename to ...
(vn::eliminate): ... this.
(run_rpo_vn): Rename to ...
(vn::enumerate_values): ... this, without the walk.
(free_rpo_vn): Make static.
(vn::vn): New, for the whole function and for a region, which
says whether to skip its entry PHIs.
(vn::~vn): New.
(do_rpo_vn_1): Rename to ...
(vn::walk): ... this, on the object's region and walker.
(do_rpo_vn, pass_fre::execute): Use a vn.
* tree-ssa-pre.cc (pass_pre::execute): Same.
---
gcc/tree-ssa-pre.cc | 8 ++---
gcc/tree-ssa-sccvn.cc | 76 ++++++++++++++++++++++++++++---------------
gcc/tree-ssa-sccvn.h | 27 ++++++++++++---
3 files changed, 77 insertions(+), 34 deletions(-)
diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc
index f1bd8950983..8527eae1f9c 100644
--- a/gcc/tree-ssa-pre.cc
+++ b/gcc/tree-ssa-pre.cc
@@ -4693,7 +4693,9 @@ pass_pre::execute (function *fun)
scev_initialize ();
calculate_dominance_info (CDI_DOMINATORS);
- run_rpo_vn (VN_WALK);
+ vn vn (fun);
+ vn.walk (true, false, VN_WALK);
+ vn.enumerate_values ();
init_pre ();
@@ -4727,7 +4729,7 @@ pass_pre::execute (function *fun)
statistics_counter_event (fun, "HOIST inserted", pre_stats.hoist_insert);
statistics_counter_event (fun, "New PHIs", pre_stats.phis);
- todo |= eliminate_with_rpo_vn (inserted_exprs);
+ todo |= vn.eliminate (inserted_exprs);
vn_valueize = NULL;
@@ -4761,8 +4763,6 @@ pass_pre::execute (function *fun)
- mark TODO_cleanup_cfg when necessary. */
todo |= tail_merge_optimize (need_crit_edge_split);
- free_rpo_vn ();
-
/* Tail merging invalidates the virtual SSA web, together with
cfg-cleanup opportunities exposed by PRE this will wreck the
SSA updating machinery. So make sure to run update-ssa
diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index 7ff14cec119..fc4725972c5 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -2693,7 +2693,7 @@ class eliminate_dom_walker : public dom_walker
{
public:
eliminate_dom_walker (cdi_direction, bitmap);
- ~eliminate_dom_walker ();
+ virtual ~eliminate_dom_walker ();
edge before_dom_children (basic_block) final override;
void after_dom_children (basic_block) final override;
@@ -8055,7 +8055,7 @@ eliminate_dom_walker::eliminate_cleanup (bool region_p)
/* Eliminate fully redundant computations. */
unsigned
-eliminate_with_rpo_vn (bitmap inserted_exprs)
+vn::eliminate (bitmap inserted_exprs)
{
eliminate_dom_walker walker (CDI_DOMINATORS, inserted_exprs);
@@ -8067,16 +8067,11 @@ eliminate_with_rpo_vn (bitmap inserted_exprs)
return walker.eliminate_cleanup ();
}
-static unsigned
-do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
- bool iterate, bool eliminate, bool skip_entry_phis,
- vn_lookup_kind kind);
+/* Give every value a value id, for PRE. */
void
-run_rpo_vn (vn_lookup_kind kind)
+vn::enumerate_values ()
{
- do_rpo_vn_1 (cfun, NULL, NULL, true, false, false, kind);
-
/* ??? Prune requirement of these. */
constant_to_value_id = new hash_table<vn_constant_hasher> (23);
@@ -8127,7 +8122,7 @@ run_rpo_vn (vn_lookup_kind kind)
/* Free VN associated data structures. */
-void
+static void
free_rpo_vn (void)
{
free_vn_table (valid_info);
@@ -8880,19 +8875,49 @@ do_unwind (unwind_state *to, rpo_elim &avail)
}
}
+vn::vn (function *fn)
+ : vn (fn, NULL, NULL, false)
+{
+}
+
+/* A value numbering of the region ENTRY leads into, which exits to EXIT_BBS,
+ or all of FN if ENTRY is NULL. If SKIP_ENTRY_PHIS is set, force PHI nodes
+ in ENTRY->dest to VARYING. */
+
+vn::vn (function *fn, edge entry, bitmap exit_bbs, bool skip_entry_phis)
+ : m_fn (fn), m_entry (entry), m_exit_bbs (exit_bbs),
+ m_skip_entry_phis (skip_entry_phis), m_walked (false)
+{
+ basic_block entry_bb
+ = entry ? entry->dest : single_succ (ENTRY_BLOCK_PTR_FOR_FN (fn));
+ m_avail = new rpo_elim (entry_bb);
+ m_bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
+}
+
+vn::~vn ()
+{
+ if (m_walked)
+ free_rpo_vn ();
+ XDELETEVEC (m_bb_to_rpo);
+ delete m_avail;
+}
+
/* Do VN on a SEME region specified by ENTRY and EXIT_BBS in FN.
If ITERATE is true then treat backedges optimistically as not
executed and iterate. If ELIMINATE is true then perform
- elimination, otherwise leave that to the caller. If SKIP_ENTRY_PHIS
- is true then force PHI nodes in ENTRY->dest to VARYING. */
+ elimination, otherwise leave that to the caller. */
-static unsigned
-do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
- bool iterate, bool eliminate, bool skip_entry_phis,
- vn_lookup_kind kind)
+unsigned
+vn::walk (bool iterate, bool eliminate, vn_lookup_kind kind)
{
+ function *fn = m_fn;
+ edge entry = m_entry;
+ bitmap exit_bbs = m_exit_bbs;
+ bool skip_entry_phis = m_skip_entry_phis;
unsigned todo = 0;
default_vn_walk_kind = kind;
+ gcc_checking_assert (!m_walked);
+ m_walked = true;
/* We currently do not support region-based iteration when
elimination is requested. */
@@ -8935,14 +8960,14 @@ do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
"the entry block, skipping its PHIs.\n");
skip_entry_phis |= e != NULL;
- int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
+ int *bb_to_rpo = m_bb_to_rpo;
for (int i = 0; i < n; ++i)
bb_to_rpo[rpo[i]] = i;
vn_bb_to_rpo = bb_to_rpo;
unwind_state *rpo_state = XNEWVEC (unwind_state, n);
- rpo_elim avail (entry->dest);
+ rpo_elim &avail = *m_avail;
rpo_avail = &avail;
/* Verify we have no extra entries into the region. */
@@ -9281,7 +9306,7 @@ do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
/* Note we can't use avail.walk here because that gets confused
by the existing availability and it will be less efficient
as well. */
- todo |= eliminate_with_rpo_vn (NULL);
+ todo |= this->eliminate (NULL);
}
else
todo |= avail.eliminate_cleanup (do_region);
@@ -9291,7 +9316,6 @@ do_rpo_vn_1 (function *fn, edge entry, bitmap exit_bbs,
rpo_avail = NULL;
vn_bb_to_rpo = NULL;
- XDELETEVEC (bb_to_rpo);
XDELETEVEC (rpo);
XDELETEVEC (rpo_state);
@@ -9314,10 +9338,8 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
vn_lookup_kind kind)
{
auto_timevar tv (TV_TREE_RPO_VN);
- unsigned todo = do_rpo_vn_1 (fn, entry, exit_bbs, iterate, eliminate,
- skip_entry_phis, kind);
- free_rpo_vn ();
- return todo;
+ vn vn (fn, entry, exit_bbs, skip_entry_phis);
+ return vn.walk (iterate, eliminate, kind);
}
@@ -9371,8 +9393,10 @@ pass_fre::execute (function *fun)
if (iterate_p)
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
- todo = do_rpo_vn_1 (fun, NULL, NULL, iterate_p, true, false, VN_WALKREWRITE);
- free_rpo_vn ();
+ {
+ vn vn (fun);
+ todo = vn.walk (iterate_p, true);
+ }
if (iterate_p)
loop_optimizer_finalize ();
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index 78729fbec64..92a4c657c1f 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -309,10 +309,29 @@ unsigned do_rpo_vn (function *, edge, bitmap,
/* skip_entry_phis */ bool = false,
vn_lookup_kind = VN_WALKREWRITE);
-/* Private interface for PRE. */
-void run_rpo_vn (vn_lookup_kind);
-unsigned eliminate_with_rpo_vn (bitmap);
-void free_rpo_vn (void);
+/* An RPO value numbering of a function. */
+
+class vn
+{
+public:
+ vn (function *);
+ vn (function *, edge entry, bitmap exit_bbs, bool skip_entry_phis);
+ virtual ~vn ();
+ unsigned walk (bool iterate, bool eliminate,
+ vn_lookup_kind = VN_WALKREWRITE);
+ void enumerate_values ();
+ unsigned eliminate (bitmap inserted_exprs);
+
+private:
+ DISABLE_COPY_AND_ASSIGN (vn);
+ function *m_fn;
+ edge m_entry;
+ bitmap m_exit_bbs;
+ bool m_skip_entry_phis;
+ class rpo_elim *m_avail;
+ int *m_bb_to_rpo;
+ bool m_walked;
+};
/* Valueize NAME if it is an SSA name, otherwise just return it. This hook
is initialized by run_scc_vn. */
--
2.53.0