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

Reply via email to