Patchwork manage dom-walk_data initialization and finalization with constructors and destructors

login
register
mail settings
Submitter Trevor Saunders
Date Sept. 11, 2013, 12:03 a.m.
Message ID <20130911000350.GA28492@tsaunders-iceball.corp.tor1.mozilla.com>
Download mbox | patch
Permalink /patch/274089/
State New
Headers show

Comments

Trevor Saunders - Sept. 11, 2013, 12:03 a.m.
On Wed, Sep 04, 2013 at 10:03:20AM -0600, Jeff Law wrote:
> On 09/04/2013 08:59 AM, Trevor Saunders wrote:
> >On Wed, Sep 04, 2013 at 10:32:17AM +0200, Richard Biener wrote:
> >>On Wed, Sep 4, 2013 at 5:16 AM,  <tsaunders@mozilla.com> wrote:
> >>>From: Trevor Saunders <tsaunders@mozilla.com>
> >>>
> >>>bootstrapped on x86_64-unknown-linux-gnu with same test results as unpatched r202185 ok?
> >>
> >>That looks like a not too useful part-C++-ification of domwalk.  A proper
> >>C++-ification would include the use of functors and possibly templating it
> >>on the user specific data type.
> >
> >  It's true this patch isn't that aggressive, I was thinking about going
> >  farther incrementally.  I also haven't quiet convinced my self inlining
> >  all of domwalk.c or adding a whole bunch of explicit template
> >  instantiations to domwalk.c was really a good idea.  Are you saying you
> >  believe the removal of the indirect calls is worth the extra code size?
> >
> >>So, what do you think is the advantage (other than dropping two or three lines
> >>of code in the users)?
> >
> >I'd say its the same as for all other raii things, you don't have to be
> >sure to free data when you're done with it, and imho reducing boiler
> >plate is a fairly good thing on its own.
> More importantly, I think converting the walker to a C++ object with
> methods ought to be rather straightforward.   The state each
> optimizer attaches to the walker naturally falls into a derived
> class.

yeah, how does the attached look then?  I moved some of the state, but
some of it appeared at least moderately entagled with other things, so I
figured it made sense to leave that to another patch.

Trev

Patch

From dff56f109497c1f6d4d2821427c89160ccc01f93 Mon Sep 17 00:00:00 2001
From: Trevor Saunders <tsaunders@mozilla.com>
Date: Tue, 3 Sep 2013 23:06:30 -0400
Subject: [PATCH] convert dom_walk_data into a c++ class dom_walker

 * compare-elim.c (find_comparison_dom_walker): new class
 (find_comparisons_in_bb): Rename to
 find_comparison_dom_walker::before_dom_children
 (find_comparisons): adjust
 * domwalk.c (walk_dominator_tree): Rename to dom_walker::walk, and adjust.
 (init_walk_dominator_tree): remove
 (fini_walk_dominator_tree): remove
 * domwalk.h (dom_walk_data): convert it To a class dom_walker.
 (init_walk_dominator_tree): remove declaration
 (fini_walk_dominator_tree): remove declaration
 * fwprop.c (single_def_use_dom_walker): new class
 (single_def_use_enter_block): Convert to
 single_def_use_dom_walker::before_dom_children.
 (single_def_use_leave_block): Convert to
 single_def_use_dom_walker::after_dom_children.
 (build_single_def_use_links): adjust
 * gimple-ssa-strength-reduction.c (find_candidates_dom_walker): new class
 (find_candidates_in_block): Convert to
 find_candidates_dom_walker::before_dom_children.
 (execute_strength_reduction): adjust
 * graphite-sese-to-poly.c (struct bsc): remove
 (sese_dom_walker): new class
 (sese_dom_walker::sese_dom_walker): new constructor
 (sese_dom_walker::~sese_dom_walker): new destructor
 (build_sese_conditions_before): Convert to
 sese_dom_walker::before_dom_children.
 (build_sese_conditions_after): Convert to
 sese_dom_walker::after_dom_children.
 (build_sese_conditions): remove
 (build_poly_scop): adjust
 * tree-into-ssa.c (rewrite_dom_walker): new class
 (rewrite_enter_block): convert to rewrite_dom_walker::before_dom_children.
 (rewrite_leave_block): convert to rewrite_dom_walker::after_dom_children.
 (rewrite_update_dom_walker): new class
 (rewrite_update_enter_block): convert to
 rewrite_update_dom_walker::before_dom_children.
 (rewrite_update_leave_block): convert to
 rewrite_update_dom_walker::after_dom_children.
 (rewrite_blocks): adjust
 (mark_def_dom_walker): new class
 (mark_def_dom_walker::mark_def_dom_walker): new constructor
 (mark_def_dom_walker::~mark_def_dom_walker): new destructor
 (mark_def_sites_blocks): Convert to mark_def_dom_walker::before_dom_children.
 (mark_def_site_blocks): remove
 (rewrite_into_ssa): adjust
 * tree-ssa-dom.c (dom_opt_dom_walker): new class
 (tree_ssa_dominator_optimize): adjust
 (dom_thread_across_edge): Convert to method
 dom_opt_dom_walker::thread_across_edge.
 (dom_opt_enter_block): Convert to member function
 dom_opt_dom_walker::before_dom_children.
 (dom_opt_leave_block): Convert to member function
 dom_opt_dom_walker::after_dom_children.
 * tree-ssa-dse.c (dse_dom_walker): new class
 (dse_enter_block): Convert to Member function
 dse_dom_walker::before_dom_children.
 (tree_ssa_dse): adjust
 * tree-ssa-loop-im.c (invariantness_dom_walker): new class
 (determine_invariantness_stmt): Convert to method
 invariantness_dom_walker::before_dom_children.
 (determine_invariantness): remove
 (move_computations_dom_walker): new class
 (move_computations_stmt): Convert to method
 move_computations_dom_walker::before_dom_children.
 (move_computations): adjust
 (tree_ssa_lim): adjust
 * tre-ssa-phiopt.c (nontrapping_dom_walker): new class
 (nt_init_block): Make method notrappping_dom_walker::before_dom_children.
 (nt_fini_block): Make method nontrapping_dom_walker::after_dom_children.
 (get_non_trapping): adjust
 * tree-ssa-pre.c (eliminate_dom_walker): new class
 (eliminate_bb): Make method eliminate_dom_walker::before_dom_children.
 (eliminate_leave_block): Make method
 eliminate_dom_walker::after_dom_children.
 (eliminate): adjust
 * tree-ssa-strlen.c (strlen_dom_walker): new class
 (strlen_enter_block): Make method strlen_dom_walker::before_dom_children.
 (strlen_leave_block): Make method strlen_dom_walker::after_dom_children.
 (tree_ssa_strlen): adjust
 * tree-ssa-uncprop.c (uncprop_dom_walker): new class
 (tree_ssa_uncprop): adjust
 (uncprop_leave_block): Make method uncprop_dom_walker::after_dom_children.
 (uncprop_leave_block): Make method uncprop_dom_walker::before_dom_children.
---
 gcc/compare-elim.c                  |  27 +++----
 gcc/domwalk.c                       |  87 +++------------------
 gcc/domwalk.h                       |  71 +++++++----------
 gcc/fwprop.c                        |  30 ++++----
 gcc/gimple-ssa-strength-reduction.c |  29 +++----
 gcc/graphite-sese-to-poly.c         | 104 ++++++++++---------------
 gcc/tree-into-ssa.c                 | 148 ++++++++++++++----------------------
 gcc/tree-ssa-dom.c                  |  71 ++++++++---------
 gcc/tree-ssa-dse.c                  |  33 +++-----
 gcc/tree-ssa-loop-im.c              |  66 ++++++++--------
 gcc/tree-ssa-phiopt.c               |  48 ++++++------
 gcc/tree-ssa-pre.c                  |  28 +++----
 gcc/tree-ssa-strlen.c               |  37 ++++-----
 gcc/tree-ssa-uncprop.c              |  72 +++++++++---------
 14 files changed, 334 insertions(+), 517 deletions(-)

diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c
index e907376..19cf524 100644
--- a/gcc/compare-elim.c
+++ b/gcc/compare-elim.c
@@ -243,13 +243,21 @@  find_flags_uses_in_insn (struct comparison *cmp, rtx insn)
   cmp->missing_uses = true;
 }
 
+class find_comparison_dom_walker : public dom_walker
+{
+public:
+  find_comparison_dom_walker (cdi_direction direction)
+    : dom_walker(direction) {}
+
+  virtual void before_dom_children (basic_block);
+};
+
 /* Identify comparison instructions within BB.  If the flags from the last
    compare in the BB is live at the end of the block, install the compare
-   in BB->AUX.  Called via walk_dominators_tree.  */
+   in BB->AUX.  Called via dom_walker.walk ().  */
 
-static void
-find_comparisons_in_bb (struct dom_walk_data *data ATTRIBUTE_UNUSED,
-			basic_block bb)
+void
+find_comparison_dom_walker::before_dom_children (basic_block bb)
 {
   struct comparison *last_cmp;
   rtx insn, next, last_clobber;
@@ -403,17 +411,10 @@  find_comparisons_in_bb (struct dom_walk_data *data ATTRIBUTE_UNUSED,
 static void
 find_comparisons (void)
 {
-  struct dom_walk_data data;
-
-  memset (&data, 0, sizeof(data));
-  data.dom_direction = CDI_DOMINATORS;
-  data.before_dom_children = find_comparisons_in_bb;
-
   calculate_dominance_info (CDI_DOMINATORS);
 
-  init_walk_dominator_tree (&data);
-  walk_dominator_tree (&data, ENTRY_BLOCK_PTR);
-  fini_walk_dominator_tree (&data);
+  find_comparison_dom_walker (CDI_DOMINATORS)
+    .walk (cfun->cfg->x_entry_block_ptr);
 
   clear_aux_for_blocks ();
   free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/domwalk.c b/gcc/domwalk.c
index 8c1ddc6..e835dbd 100644
--- a/gcc/domwalk.c
+++ b/gcc/domwalk.c
@@ -144,23 +144,17 @@  cmp_bb_postorder (const void *a, const void *b)
 }
 
 /* Recursively walk the dominator tree.
-
-   WALK_DATA contains a set of callbacks to perform pass-specific
-   actions during the dominator walk as well as a stack of block local
-   data maintained during the dominator walk.
-
    BB is the basic block we are currently visiting.  */
 
 void
-walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
+dom_walker::walk (basic_block bb)
 {
-  void *bd = NULL;
   basic_block dest;
   basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2);
   int sp = 0;
   int *postorder, postorder_num;
 
-  if (walk_data->dom_direction == CDI_DOMINATORS)
+  if (dom_direction_ == CDI_DOMINATORS)
     {
       postorder = XNEWVEC (int, n_basic_blocks);
       postorder_num = inverted_post_order_compute (postorder);
@@ -177,37 +171,9 @@  walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
 	  || bb == ENTRY_BLOCK_PTR
 	  || bb == EXIT_BLOCK_PTR)
 	{
-	  /* Callback to initialize the local data structure.  */
-	  if (walk_data->initialize_block_local_data)
-	    {
-	      bool recycled;
-
-	      /* First get some local data, reusing any local data
-		 pointer we may have saved.  */
-	      if (walk_data->free_block_data.length () > 0)
-		{
-		  bd = walk_data->free_block_data.pop ();
-		  recycled = 1;
-		}
-	      else
-		{
-		  bd = xcalloc (1, walk_data->block_local_data_size);
-		  recycled = 0;
-		}
-
-	      /* Push the local data into the local data stack.  */
-	      walk_data->block_data_stack.safe_push (bd);
-
-	      /* Call the initializer.  */
-	      walk_data->initialize_block_local_data (walk_data, bb,
-						      recycled);
-
-	    }
-
-	  /* Callback for operations to execute before we have walked the
-	     dominator children, but before we walk statements.  */
-	  if (walk_data->before_dom_children)
-	    (*walk_data->before_dom_children) (walk_data, bb);
+	  /* Callback for subclasses to do custom things before we have walked
+	   * the dominator children, but before we walk statements.  */
+	    before_dom_children (bb);
 
 	  /* Mark the current BB to be popped out of the recursion stack
 	     once children are processed.  */
@@ -215,10 +181,10 @@  walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
 	  worklist[sp++] = NULL;
 
 	  int saved_sp = sp;
-	  for (dest = first_dom_son (walk_data->dom_direction, bb);
-	       dest; dest = next_dom_son (walk_data->dom_direction, dest))
+	  for (dest = first_dom_son (dom_direction_, bb);
+	       dest; dest = next_dom_son (dom_direction_, dest))
 	    worklist[sp++] = dest;
-	  if (walk_data->dom_direction == CDI_DOMINATORS)
+	  if (dom_direction_ == CDI_DOMINATORS)
 	    switch (sp - saved_sp)
 	      {
 	      case 0:
@@ -235,48 +201,19 @@  walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
 	  --sp;
 	  bb = worklist[--sp];
 
-	  /* Callback for operations to execute after we have walked the
-	     dominator children, but before we walk statements.  */
-	  if (walk_data->after_dom_children)
-	    (*walk_data->after_dom_children) (walk_data, bb);
-
-	  if (walk_data->initialize_block_local_data)
-	    {
-	      /* And finally pop the record off the block local data stack.  */
-	      bd = walk_data->block_data_stack.pop ();
-	      /* And save the block data so that we can re-use it.  */
-	      walk_data->free_block_data.safe_push (bd);
-	    }
+	  /* Callback allowing subclasses to do custom things after we have
+	   * walked dominator children, but before we walk statements.  */
+    after_dom_children (bb);
 	}
       if (sp)
 	bb = worklist[--sp];
       else
 	break;
     }
-  if (walk_data->dom_direction == CDI_DOMINATORS)
+  if (dom_direction_ == CDI_DOMINATORS)
     {
       free (bb_postorder);
       bb_postorder = NULL;
     }
   free (worklist);
 }
-
-void
-init_walk_dominator_tree (struct dom_walk_data *walk_data)
-{
-  walk_data->free_block_data.create (0);
-  walk_data->block_data_stack.create (0);
-}
-
-void
-fini_walk_dominator_tree (struct dom_walk_data *walk_data)
-{
-  if (walk_data->initialize_block_local_data)
-    {
-      while (walk_data->free_block_data.length () > 0)
-	free (walk_data->free_block_data.pop ());
-    }
-
-  walk_data->free_block_data.release ();
-  walk_data->block_data_stack.release ();
-}
diff --git a/gcc/domwalk.h b/gcc/domwalk.h
index 54b7f3c..4b10fc6 100644
--- a/gcc/domwalk.h
+++ b/gcc/domwalk.h
@@ -18,57 +18,38 @@  You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-typedef void *void_p;
-
-/* This is the main data structure for the dominator walker.  It provides
-   the callback hooks as well as a convenient place to hang block local
-   data and pass-global data.  */
-
-struct dom_walk_data
+#ifndef GCC_DOM_WALK_H
+#define GCC_DOM_WALK_H
+
+/**
+ * This is the main class for the dominator walker. It is expected that
+ * consumers will have a custom class inheriting from it, which will over ride
+ * at least one of before_dom_children and after_dom_children to implement the
+ * custom behavior.
+ */
+class dom_walker
 {
-  /* This is the direction of the dominator tree we want to walk.  i.e.,
-     if it is set to CDI_DOMINATORS, then we walk the dominator tree,
-     if it is set to CDI_POST_DOMINATORS, then we walk the post
-     dominator tree.  */
-  ENUM_BITFIELD (cdi_direction) dom_direction : 2;
-
-  /* Function to initialize block local data.
+public:
+  dom_walker (cdi_direction direction)
+    : dom_direction_ (direction) {}
 
-     Note that the dominator walker infrastructure may provide a new
-     fresh, and zero'd block local data structure, or it may re-use an
-     existing block local data structure.
-
-     If the block local structure has items such as virtual arrays, then
-     that allows your optimizer to re-use those arrays rather than
-     creating new ones.  */
-  void (*initialize_block_local_data) (struct dom_walk_data *,
-				       basic_block, bool);
+  /**
+   * Walk the dominator tree.
+   */
+  void walk (basic_block);
 
   /* Function to call before the recursive walk of the dominator children.  */
-  void (*before_dom_children) (struct dom_walk_data *, basic_block);
+  virtual void before_dom_children (basic_block) {}
 
   /* Function to call after the recursive walk of the dominator children.  */
-  void (*after_dom_children) (struct dom_walk_data *, basic_block);
-
-  /* Global data for a walk through the dominator tree.  */
-  void *global_data;
+  virtual void after_dom_children (basic_block) {}
 
-  /* Stack of any data we need to keep on a per-block basis.
-
-     If you have no local data, then BLOCK_DATA_STACK will be NULL.  */
-  vec<void_p> block_data_stack;
-
-  /* Size of the block local data.   If this is zero, then it is assumed
-     you have no local data and thus no BLOCK_DATA_STACK as well.  */
-  size_t block_local_data_size;
-
-  /* From here below are private data.  Please do not use this
-     information/data outside domwalk.c.  */
-
-  /* Stack of available block local structures.  */
-  vec<void_p> free_block_data;
+private:
+  /* This is the direction of the dominator tree we want to walk.  i.e.,
+     if it is set to CDI_DOMINATORS, then we walk the dominator tree,
+     if it is set to CDI_POST_DOMINATORS, then we walk the post
+     dominator tree.  */
+  const ENUM_BITFIELD (cdi_direction) dom_direction_ : 2;
 };
 
-void walk_dominator_tree (struct dom_walk_data *, basic_block);
-void init_walk_dominator_tree (struct dom_walk_data *);
-void fini_walk_dominator_tree (struct dom_walk_data *);
+#endif
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 8fe02ac..137011d 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -205,10 +205,17 @@  process_uses (df_ref *use_rec, int top_flag)
       }
 }
 
+class single_def_use_dom_walker : public dom_walker
+{
+public:
+  single_def_use_dom_walker (cdi_direction direction)
+    : dom_walker (direction) {}
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+};
 
-static void
-single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-			    basic_block bb)
+void
+single_def_use_dom_walker::before_dom_children (basic_block bb)
 {
   int bb_index = bb->index;
   struct df_md_bb_info *md_bb_info = df_md_get_bb_info (bb_index);
@@ -245,9 +252,8 @@  single_def_use_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 /* Pop the definitions created in this basic block when leaving its
    dominated parts.  */
 
-static void
-single_def_use_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-			    basic_block bb ATTRIBUTE_UNUSED)
+void
+single_def_use_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
 {
   df_ref saved_def;
   while ((saved_def = reg_defs_stack.pop ()) != NULL)
@@ -269,8 +275,6 @@  single_def_use_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 static void
 build_single_def_use_links (void)
 {
-  struct dom_walk_data walk_data;
-
   /* We use the multiple definitions problem to compute our restricted
      use-def chains.  */
   df_set_flags (DF_EQ_NOTES);
@@ -291,14 +295,8 @@  build_single_def_use_links (void)
 
   /* Walk the dominator tree looking for single reaching definitions
      dominating the uses.  This is similar to how SSA form is built.  */
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = single_def_use_enter_block;
-  walk_data.after_dom_children = single_def_use_leave_block;
-
-  init_walk_dominator_tree (&walk_data);
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-  fini_walk_dominator_tree (&walk_data);
+  single_def_use_dom_walker (CDI_DOMINATORS)
+    .walk (cfun->cfg->x_entry_block_ptr);
 
   BITMAP_FREE (local_lr);
   BITMAP_FREE (local_md);
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index e85e629..a8579e8 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -1512,11 +1512,18 @@  slsr_process_copy (gimple gs, tree rhs1, bool speed)
   add_cand_for_stmt (gs, c);
 }
 
+class find_candidates_dom_walker : public dom_walker
+{
+public:
+  find_candidates_dom_walker (cdi_direction direction)
+    : dom_walker (direction) {}
+  virtual void before_dom_children (basic_block);
+};
+
 /* Find strength-reduction candidates in block BB.  */
 
-static void
-find_candidates_in_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-			  basic_block bb)
+void
+find_candidates_dom_walker::before_dom_children (basic_block bb)
 {
   bool speed = optimize_bb_for_speed_p (bb);
   gimple_stmt_iterator gsi;
@@ -3429,8 +3436,6 @@  analyze_candidates_and_replace (void)
 static unsigned
 execute_strength_reduction (void)
 {
-  struct dom_walk_data walk_data;
-
   /* Create the obstack where candidates will reside.  */
   gcc_obstack_init (&cand_obstack);
 
@@ -3450,18 +3455,10 @@  execute_strength_reduction (void)
      back edges, and this gives us dominator information as well.  */
   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
 
-  /* Set up callbacks for the generic dominator tree walker.  */
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = find_candidates_in_block;
-  walk_data.after_dom_children = NULL;
-  walk_data.global_data = NULL;
-  walk_data.block_local_data_size = 0;
-  init_walk_dominator_tree (&walk_data);
-
   /* Walk the CFG in predominator order looking for strength reduction
      candidates.  */
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
+  find_candidates_dom_walker (CDI_DOMINATORS)
+    .walk (cfun->cfg->x_entry_block_ptr);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -3472,8 +3469,6 @@  execute_strength_reduction (void)
   /* Analyze costs and make appropriate replacements.  */
   analyze_candidates_and_replace ();
 
-  /* Free resources.  */
-  fini_walk_dominator_tree (&walk_data);
   loop_optimizer_finalize ();
   base_cand_map.dispose ();
   obstack_free (&chain_obstack, NULL);
diff --git a/gcc/graphite-sese-to-poly.c b/gcc/graphite-sese-to-poly.c
index c4c3eb4..e16ca82 100644
--- a/gcc/graphite-sese-to-poly.c
+++ b/gcc/graphite-sese-to-poly.c
@@ -1191,14 +1191,6 @@  add_conditions_to_constraints (scop_p scop)
     add_conditions_to_domain (pbb);
 }
 
-/* Structure used to pass data to dom_walk.  */
-
-struct bsc
-{
-  vec<gimple> *conditions, *cases;
-  sese region;
-};
-
 /* Returns a COND_EXPR statement when BB has a single predecessor, the
    edge between BB and its predecessor is not a loop exit edge, and
    the last statement of the single predecessor is a COND_EXPR.  */
@@ -1224,20 +1216,43 @@  single_pred_cond_non_loop_exit (basic_block bb)
   return NULL;
 }
 
+class sese_dom_walker : public dom_walker
+{
+public:
+  sese_dom_walker (cdi_direction, sese);
+  ~sese_dom_walker ();
+
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+
+private:
+  vec<gimple> conditions_, cases_;
+  sese region_;
+};
+
+sese_dom_walker::sese_dom_walker (cdi_direction direction, sese region)
+  : dom_walker (direction), region_ (region)
+{
+  conditions_.create (3);
+  cases_.create (3);
+}
+
+sese_dom_walker::~sese_dom_walker ()
+{
+  conditions_.release ();
+  cases_.release ();
+}
+
 /* Call-back for dom_walk executed before visiting the dominated
    blocks.  */
 
-static void
-build_sese_conditions_before (struct dom_walk_data *dw_data,
-			      basic_block bb)
+void
+sese_dom_walker::before_dom_children (basic_block bb)
 {
-  struct bsc *data = (struct bsc *) dw_data->global_data;
-  vec<gimple> *conditions = data->conditions;
-  vec<gimple> *cases = data->cases;
   gimple_bb_p gbb;
   gimple stmt;
 
-  if (!bb_in_sese_p (bb, data->region))
+  if (!bb_in_sese_p (bb, region_))
     return;
 
   stmt = single_pred_cond_non_loop_exit (bb);
@@ -1246,75 +1261,39 @@  build_sese_conditions_before (struct dom_walk_data *dw_data,
     {
       edge e = single_pred_edge (bb);
 
-      conditions->safe_push (stmt);
+      conditions_.safe_push (stmt);
 
       if (e->flags & EDGE_TRUE_VALUE)
-	cases->safe_push (stmt);
+	cases_.safe_push (stmt);
       else
-	cases->safe_push (NULL);
+	cases_.safe_push (NULL);
     }
 
   gbb = gbb_from_bb (bb);
 
   if (gbb)
     {
-      GBB_CONDITIONS (gbb) = conditions->copy ();
-      GBB_CONDITION_CASES (gbb) = cases->copy ();
+      GBB_CONDITIONS (gbb) = conditions_.copy ();
+      GBB_CONDITION_CASES (gbb) = cases_.copy ();
     }
 }
 
 /* Call-back for dom_walk executed after visiting the dominated
    blocks.  */
 
-static void
-build_sese_conditions_after (struct dom_walk_data *dw_data,
-			     basic_block bb)
+void
+sese_dom_walker::after_dom_children (basic_block bb)
 {
-  struct bsc *data = (struct bsc *) dw_data->global_data;
-  vec<gimple> *conditions = data->conditions;
-  vec<gimple> *cases = data->cases;
-
-  if (!bb_in_sese_p (bb, data->region))
+  if (!bb_in_sese_p (bb, region_))
     return;
 
   if (single_pred_cond_non_loop_exit (bb))
     {
-      conditions->pop ();
-      cases->pop ();
+      conditions_.pop ();
+      cases_.pop ();
     }
 }
 
-/* Record all conditions in REGION.  */
-
-static void
-build_sese_conditions (sese region)
-{
-  struct dom_walk_data walk_data;
-  vec<gimple> conditions;
-  conditions.create (3);
-  vec<gimple> cases;
-  cases.create (3);
-  struct bsc data;
-
-  data.conditions = &conditions;
-  data.cases = &cases;
-  data.region = region;
-
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = build_sese_conditions_before;
-  walk_data.after_dom_children = build_sese_conditions_after;
-  walk_data.global_data = &data;
-  walk_data.block_local_data_size = 0;
-
-  init_walk_dominator_tree (&walk_data);
-  walk_dominator_tree (&walk_data, SESE_ENTRY_BB (region));
-  fini_walk_dominator_tree (&walk_data);
-
-  conditions.release ();
-  cases.release ();
-}
-
 /* Add constraints on the possible values of parameter P from the type
    of P.  */
 
@@ -3179,7 +3158,8 @@  build_poly_scop (scop_p scop)
     rewrite_commutative_reductions_out_of_ssa (scop);
 
   build_sese_loop_nests (region);
-  build_sese_conditions (region);
+  /* Record all conditions in REGION.  */
+  sese_dom_walker (CDI_DOMINATORS, region).walk (cfun->cfg->x_entry_block_ptr);
   find_scop_parameters (scop);
 
   max_dim = PARAM_VALUE (PARAM_GRAPHITE_MAX_NB_SCOP_PARAMS);
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 33d4ba8..c62fdf1 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1399,14 +1399,22 @@  rewrite_add_phi_arguments (basic_block bb)
     }
 }
 
+class rewrite_dom_walker : public dom_walker
+{
+public:
+  rewrite_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+};
+
 /* SSA Rewriting Step 1.  Initialization, create a block local stack
    of reaching definitions for new SSA names produced in this block
    (BLOCK_DEFS).  Register new definitions for every PHI node in the
    block.  */
 
-static void
-rewrite_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		     basic_block bb)
+void
+rewrite_dom_walker::before_dom_children (basic_block bb)
 {
   gimple_stmt_iterator gsi;
 
@@ -1444,9 +1452,8 @@  rewrite_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 /* Called after visiting all the statements in basic block BB and all
    of its dominator children.  Restore CURRDEFS to its original value.  */
 
-static void
-rewrite_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		     basic_block bb ATTRIBUTE_UNUSED)
+void
+rewrite_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
 {
   /* Restore CURRDEFS to its original state.  */
   while (block_defs_stack.length () > 0)
@@ -2065,15 +2072,22 @@  rewrite_update_phi_arguments (basic_block bb)
     }
 }
 
+class rewrite_update_dom_walker : public dom_walker
+{
+public:
+  rewrite_update_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+};
 
 /* Initialization of block data structures for the incremental SSA
    update pass.  Create a block local stack of reaching definitions
    for new SSA names produced in this block (BLOCK_DEFS).  Register
    new definitions for every PHI node in the block.  */
 
-static void
-rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		            basic_block bb)
+void
+rewrite_update_dom_walker::before_dom_children (basic_block bb)
 {
   bool is_abnormal_phi;
   gimple_stmt_iterator gsi;
@@ -2146,9 +2160,8 @@  rewrite_update_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
    unwinding must be done in the opposite order to what is done in
    register_new_update_set.  */
 
-static void
-rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-			    basic_block bb ATTRIBUTE_UNUSED)
+void
+rewrite_update_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
 {
   while (block_defs_stack.length () > 0)
     {
@@ -2183,41 +2196,20 @@  rewrite_update_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 static void
 rewrite_blocks (basic_block entry, enum rewrite_mode what)
 {
-  struct dom_walk_data walk_data;
-
   /* Rewrite all the basic blocks in the program.  */
   timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
 
-  /* Setup callbacks for the generic dominator tree walker.  */
-  memset (&walk_data, 0, sizeof (walk_data));
-
-  walk_data.dom_direction = CDI_DOMINATORS;
+  block_defs_stack.create (10);
 
+  /* Recursively walk the dominator tree rewriting each statement in
+     each basic block.  */
   if (what == REWRITE_ALL)
-    {
-      walk_data.before_dom_children = rewrite_enter_block;
-      walk_data.after_dom_children = rewrite_leave_block;
-    }
+      rewrite_dom_walker (CDI_DOMINATORS).walk (entry);
   else if (what == REWRITE_UPDATE)
-    {
-      walk_data.before_dom_children = rewrite_update_enter_block;
-      walk_data.after_dom_children = rewrite_update_leave_block;
-    }
+      rewrite_update_dom_walker (CDI_DOMINATORS).walk (entry);
   else
     gcc_unreachable ();
 
-  block_defs_stack.create (10);
-
-  /* Initialize the dominator walker.  */
-  init_walk_dominator_tree (&walk_data);
-
-  /* Recursively walk the dominator tree rewriting each statement in
-     each basic block.  */
-  walk_dominator_tree (&walk_data, entry);
-
-  /* Finalize the dominator walker.  */
-  fini_walk_dominator_tree (&walk_data);
-
   /* Debugging dumps.  */
   if (dump_file && (dump_flags & TDF_STATS))
     {
@@ -2231,69 +2223,44 @@  rewrite_blocks (basic_block entry, enum rewrite_mode what)
   timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
 }
 
-
-/* Block processing routine for mark_def_sites.  Clear the KILLS bitmap
-   at the start of each block, and call mark_def_sites for each statement.  */
-
-static void
-mark_def_sites_block (struct dom_walk_data *walk_data, basic_block bb)
+class mark_def_dom_walker : public dom_walker
 {
-  struct mark_def_sites_global_data *gd;
-  bitmap kills;
-  gimple_stmt_iterator gsi;
-
-  gd = (struct mark_def_sites_global_data *) walk_data->global_data;
-  kills = gd->kills;
-
-  bitmap_clear (kills);
-  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    mark_def_sites (bb, gsi_stmt (gsi), kills);
-}
-
-
-/* Mark the definition site blocks for each variable, so that we know
-   where the variable is actually live.
-
-   The INTERESTING_BLOCKS global will be filled in with all the blocks
-   that should be processed by the renamer.  It is assumed that the
-   caller has already initialized and zeroed it.  */
-
-static void
-mark_def_site_blocks (void)
-{
-  struct dom_walk_data walk_data;
-  struct mark_def_sites_global_data mark_def_sites_global_data;
+public:
+  mark_def_dom_walker (cdi_direction direction);
+  ~mark_def_dom_walker ();
 
-  /* Setup callbacks for the generic dominator tree walker to find and
-     mark definition sites.  */
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = mark_def_sites_block;
-  walk_data.after_dom_children = NULL;
+  virtual void before_dom_children (basic_block);
 
+private:
   /* Notice that this bitmap is indexed using variable UIDs, so it must be
      large enough to accommodate all the variables referenced in the
      function, not just the ones we are renaming.  */
-  mark_def_sites_global_data.kills = BITMAP_ALLOC (NULL);
-  walk_data.global_data = &mark_def_sites_global_data;
+  bitmap kills_;
+};
 
-  /* We do not have any local data.  */
-  walk_data.block_local_data_size = 0;
+mark_def_dom_walker::mark_def_dom_walker (cdi_direction direction)
+  : dom_walker (direction), kills_ (BITMAP_ALLOC (NULL))
+{
+}
 
-  /* Initialize the dominator walker.  */
-  init_walk_dominator_tree (&walk_data);
+mark_def_dom_walker::~mark_def_dom_walker ()
+{
+  BITMAP_FREE (kills_);
+}
 
-  /* Recursively walk the dominator tree.  */
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
+/* Block processing routine for mark_def_sites.  Clear the KILLS bitmap
+   at the start of each block, and call mark_def_sites for each statement.  */
 
-  /* Finalize the dominator walker.  */
-  fini_walk_dominator_tree (&walk_data);
+void
+mark_def_dom_walker::before_dom_children (basic_block bb)
+{
+  gimple_stmt_iterator gsi;
 
-  /* We no longer need this bitmap, clear and free it.  */
-  BITMAP_FREE (mark_def_sites_global_data.kills);
+  bitmap_clear (kills_);
+  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+    mark_def_sites (bb, gsi_stmt (gsi), kills_);
 }
 
-
 /* Initialize internal data needed during renaming.  */
 
 static void
@@ -2331,8 +2298,7 @@  fini_ssa_renamer (void)
       insert PHI nodes and rename the function in dominator tree
       order.
 
-   2- Find and mark all the blocks that define variables
-      (mark_def_site_blocks).
+   2- Find and mark all the blocks that define variables.
 
    3- Insert PHI nodes at dominance frontiers (insert_phi_nodes).
 
@@ -2370,7 +2336,7 @@  rewrite_into_ssa (void)
   compute_dominance_frontiers (dfs);
 
   /* 2- Find and mark definition sites.  */
-  mark_def_site_blocks ();
+  mark_def_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
 
   /* 3- Insert PHI nodes at dominance frontiers of definition blocks.  */
   insert_phi_nodes (dfs);
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index f999a64..72c13a9 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -244,9 +244,6 @@  static void record_equivalences_from_phis (basic_block);
 static void record_equivalences_from_incoming_edge (basic_block);
 static void eliminate_redundant_computations (gimple_stmt_iterator *);
 static void record_equivalences_from_stmt (gimple, int);
-static void dom_thread_across_edge (struct dom_walk_data *, edge);
-static void dom_opt_leave_block (struct dom_walk_data *, basic_block);
-static void dom_opt_enter_block (struct dom_walk_data *, basic_block);
 static void remove_local_expressions_from_table (void);
 static void restore_vars_to_original_value (void);
 static edge single_incoming_edge_ignoring_loop_edges (basic_block);
@@ -773,6 +770,21 @@  free_all_edge_infos (void)
     }
 }
 
+class dom_opt_dom_walker : public dom_walker
+{
+public:
+  dom_opt_dom_walker (cdi_direction direction)
+    : dom_walker (direction), dummy_cond_ (NULL) {}
+
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+
+private:
+  void thread_across_edge (edge);
+
+  gimple dummy_cond_;
+};
+
 /* Jump threading, redundancy elimination and const/copy propagation.
 
    This pass may expose new symbols that need to be renamed into SSA.  For
@@ -782,8 +794,6 @@  free_all_edge_infos (void)
 static unsigned int
 tree_ssa_dominator_optimize (void)
 {
-  struct dom_walk_data walk_data;
-
   memset (&opt_stats, 0, sizeof (opt_stats));
 
   /* Create our hash tables.  */
@@ -792,20 +802,6 @@  tree_ssa_dominator_optimize (void)
   const_and_copies_stack.create (20);
   need_eh_cleanup = BITMAP_ALLOC (NULL);
 
-  /* Setup callbacks for the generic dominator tree walker.  */
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = dom_opt_enter_block;
-  walk_data.after_dom_children = dom_opt_leave_block;
-  /* Right now we only attach a dummy COND_EXPR to the global data pointer.
-     When we attach more stuff we'll need to fill this out with a real
-     structure.  */
-  walk_data.global_data = NULL;
-  walk_data.block_local_data_size = 0;
-
-  /* Now initialize the dominator walker.  */
-  init_walk_dominator_tree (&walk_data);
-
   calculate_dominance_info (CDI_DOMINATORS);
   cfg_altered = false;
 
@@ -824,7 +820,7 @@  tree_ssa_dominator_optimize (void)
   mark_dfs_back_edges ();
 
   /* Recursively walk the dominator tree optimizing statements.  */
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
+  dom_opt_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
 
   {
     gimple_stmt_iterator gsi;
@@ -897,9 +893,6 @@  tree_ssa_dominator_optimize (void)
   /* Delete our main hashtable.  */
   avail_exprs.dispose ();
 
-  /* And finalize the dominator walker.  */
-  fini_walk_dominator_tree (&walk_data);
-
   /* Free asserted bitmaps and stacks.  */
   BITMAP_FREE (need_eh_cleanup);
 
@@ -1081,21 +1074,18 @@  simplify_stmt_for_jump_threading (gimple stmt,
    it handles lazily building the dummy condition and the bookkeeping
    when jump threading is successful.  */
 
-static void
-dom_thread_across_edge (struct dom_walk_data *walk_data, edge e)
+void
+dom_opt_dom_walker::thread_across_edge (edge e)
 {
-  if (! walk_data->global_data)
-  {
-    gimple dummy_cond =
+  if (! dummy_cond_)
+    dummy_cond_ =
         gimple_build_cond (NE_EXPR,
                            integer_zero_node, integer_zero_node,
                            NULL, NULL);
-    walk_data->global_data = dummy_cond;
-  }
 
-  thread_across_edge ((gimple) walk_data->global_data, e, false,
-		      &const_and_copies_stack,
-		      simplify_stmt_for_jump_threading);
+  ::thread_across_edge (dummy_cond_, e, false,
+		        &const_and_copies_stack,
+		        simplify_stmt_for_jump_threading);
 }
 
 /* PHI nodes can create equivalences too.
@@ -1864,9 +1854,8 @@  record_edge_info (basic_block bb)
     }
 }
 
-static void
-dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		     basic_block bb)
+void
+dom_opt_dom_walker::before_dom_children (basic_block bb)
 {
   gimple_stmt_iterator gsi;
 
@@ -1903,8 +1892,8 @@  dom_opt_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
    any finalization actions in preparation for leaving this node in
    the dominator tree.  */
 
-static void
-dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
+void
+dom_opt_dom_walker::after_dom_children (basic_block bb)
 {
   gimple last;
 
@@ -1919,7 +1908,7 @@  dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
       /* Push a marker on the stack, which thread_across_edge expects
 	 and will remove.  */
       const_and_copies_stack.safe_push (NULL_TREE);
-      dom_thread_across_edge (walk_data, single_succ_edge (bb));
+      thread_across_edge (single_succ_edge (bb));
     }
   else if ((last = last_stmt (bb))
 	   && gimple_code (last) == GIMPLE_COND
@@ -1964,7 +1953,7 @@  dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
 		record_cond (eq);
 	    }
 
-	  dom_thread_across_edge (walk_data, true_edge);
+	  thread_across_edge (true_edge);
 
 	  /* And restore the various tables to their state before
 	     we threaded this edge.  */
@@ -1999,7 +1988,7 @@  dom_opt_leave_block (struct dom_walk_data *walk_data, basic_block bb)
 	    }
 
 	  /* Now thread the edge.  */
-	  dom_thread_across_edge (walk_data, false_edge);
+	  thread_across_edge (false_edge);
 
 	  /* No need to remove local expressions from our tables
 	     or restore vars to their original value as that will
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 6578758..56e83fd 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -68,7 +68,6 @@  static bitmap need_eh_cleanup;
 
 static bool gate_dse (void);
 static unsigned int tree_ssa_dse (void);
-static void dse_enter_block (struct dom_walk_data *, basic_block);
 
 
 /* A helper of dse_optimize_stmt.
@@ -292,9 +291,16 @@  dse_optimize_stmt (gimple_stmt_iterator *gsi)
     }
 }
 
-static void
-dse_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		 basic_block bb)
+class dse_dom_walker : public dom_walker
+{
+public:
+  dse_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+
+  virtual void before_dom_children (basic_block);
+};
+
+void
+dse_dom_walker::before_dom_children (basic_block bb)
 {
   gimple_stmt_iterator gsi;
 
@@ -313,8 +319,6 @@  dse_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 static unsigned int
 tree_ssa_dse (void)
 {
-  struct dom_walk_data walk_data;
-
   need_eh_cleanup = BITMAP_ALLOC (NULL);
 
   renumber_gimple_stmt_uids ();
@@ -328,22 +332,7 @@  tree_ssa_dse (void)
 
   /* Dead store elimination is fundamentally a walk of the post-dominator
      tree and a backwards walk of statements within each block.  */
-  walk_data.dom_direction = CDI_POST_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = dse_enter_block;
-  walk_data.after_dom_children = NULL;
-
-  walk_data.block_local_data_size = 0;
-  walk_data.global_data = NULL;
-
-  /* Initialize the dominator walker.  */
-  init_walk_dominator_tree (&walk_data);
-
-  /* Recursively walk the dominator tree.  */
-  walk_dominator_tree (&walk_data, EXIT_BLOCK_PTR);
-
-  /* Finalize the dominator walker.  */
-  fini_walk_dominator_tree (&walk_data);
+  dse_dom_walker (CDI_POST_DOMINATORS).walk (cfun->cfg->x_exit_block_ptr);
 
   /* Removal of stores may make some EH edges dead.  Purge such edges from
      the CFG as needed.  */
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index e5e502b..f247565 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -1040,14 +1040,25 @@  rewrite_bittest (gimple_stmt_iterator *bsi)
   return stmt;
 }
 
+/* For each statement determines the outermost loop in that it is invariant,
+   -   statements on whose motion it depends and the cost of the computation.
+   -   This information is stored to the LIM_DATA structure associated with
+   -   each statement.  */
+class invariantness_dom_walker : public dom_walker
+{
+public:
+  invariantness_dom_walker (cdi_direction direction)
+    : dom_walker (direction) {}
+
+  virtual void before_dom_children (basic_block);
+};
 
 /* Determine the outermost loops in that statements in basic block BB are
    invariant, and record them to the LIM_DATA associated with the statements.
-   Callback for walk_dominator_tree.  */
+   Callback for dom_walker.  */
 
-static void
-determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
-			      basic_block bb)
+void
+invariantness_dom_walker::before_dom_children (basic_block bb)
 {
   enum move_pos pos;
   gimple_stmt_iterator bsi;
@@ -1177,32 +1188,23 @@  determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
     }
 }
 
-/* For each statement determines the outermost loop in that it is invariant,
-   statements on whose motion it depends and the cost of the computation.
-   This information is stored to the LIM_DATA structure associated with
-   each statement.  */
-
-static void
-determine_invariantness (void)
+class move_computations_dom_walker : public dom_walker
 {
-  struct dom_walk_data walk_data;
+public:
+  move_computations_dom_walker (cdi_direction direction)
+    : dom_walker (direction), todo_ (0) {}
 
-  memset (&walk_data, 0, sizeof (struct dom_walk_data));
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.before_dom_children = determine_invariantness_stmt;
+  virtual void before_dom_children (basic_block);
 
-  init_walk_dominator_tree (&walk_data);
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-  fini_walk_dominator_tree (&walk_data);
-}
+  unsigned int todo_;
+};
 
 /* Hoist the statements in basic block BB out of the loops prescribed by
    data stored in LIM_DATA structures associated with each statement.  Callback
    for walk_dominator_tree.  */
 
-static void
-move_computations_stmt (struct dom_walk_data *dw_data,
-			basic_block bb)
+void
+move_computations_dom_walker::before_dom_children (basic_block bb)
 {
   struct loop *level;
   gimple_stmt_iterator bsi;
@@ -1266,7 +1268,7 @@  move_computations_stmt (struct dom_walk_data *dw_data,
 						   gimple_phi_result (stmt),
 						   t, arg0, arg1);
 	  SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt;
-	  *((unsigned int *)(dw_data->global_data)) |= TODO_cleanup_cfg;
+	  todo_ |= TODO_cleanup_cfg;
 	}
       gsi_insert_on_edge (loop_preheader_edge (level), new_stmt);
       remove_phi_node (&bsi, false);
@@ -1337,23 +1339,14 @@  move_computations_stmt (struct dom_walk_data *dw_data,
 static unsigned int
 move_computations (void)
 {
-  struct dom_walk_data walk_data;
-  unsigned int todo = 0;
-
-  memset (&walk_data, 0, sizeof (struct dom_walk_data));
-  walk_data.global_data = &todo;
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.before_dom_children = move_computations_stmt;
-
-  init_walk_dominator_tree (&walk_data);
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-  fini_walk_dominator_tree (&walk_data);
+  move_computations_dom_walker walker (CDI_DOMINATORS);
+  walker.walk (cfun->cfg->x_entry_block_ptr);
 
   gsi_commit_edge_inserts ();
   if (need_ssa_update_p (cfun))
     rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
 
-  return todo;
+  return walker.todo_;
 }
 
 /* Checks whether the statement defining variable *INDEX can be hoisted
@@ -2632,7 +2625,8 @@  tree_ssa_lim (void)
 
   /* For each statement determine the outermost loop in that it is
      invariant and cost for computing the invariant.  */
-  determine_invariantness ();
+  invariantness_dom_walker (CDI_DOMINATORS)
+    .walk (cfun->cfg->x_entry_block_ptr);
 
   /* Execute store motion.  Force the necessary invariants to be moved
      out of the loops as well.  */
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index ddcd040..9744e90 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -1264,9 +1264,6 @@  struct ssa_names_hasher : typed_free_remove <name_to_bb>
    Hash entries with phase < nt_call_phase are invalid.  */
 static unsigned int nt_call_phase;
 
-/* The set of MEM_REFs which can't trap.  */
-static struct pointer_set_t *nontrap_set;
-
 /* The hash function.  */
 
 inline hashval_t
@@ -1378,9 +1375,22 @@  nonfreeing_call_p (gimple call)
   return false;
 }
 
+class nontrapping_dom_walker : public dom_walker
+{
+public:
+  nontrapping_dom_walker (cdi_direction direction, pointer_set_t *ps)
+    : dom_walker (direction), nontrapping_ (ps) {}
+
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+
+private:
+  pointer_set_t *nontrapping_;
+};
+
 /* Called by walk_dominator_tree, when entering the block BB.  */
-static void
-nt_init_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
+void
+nontrapping_dom_walker::before_dom_children (basic_block bb)
 {
   edge e;
   edge_iterator ei;
@@ -1406,15 +1416,15 @@  nt_init_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
 	nt_call_phase++;
       else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt))
 	{
-	  add_or_mark_expr (bb, gimple_assign_lhs (stmt), nontrap_set, true);
-	  add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), nontrap_set, false);
+	  add_or_mark_expr (bb, gimple_assign_lhs (stmt), nontrapping_, true);
+	  add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), nontrapping_, false);
 	}
     }
 }
 
 /* Called by walk_dominator_tree, when basic block BB is exited.  */
-static void
-nt_fini_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
+void
+nontrapping_dom_walker::after_dom_children (basic_block bb)
 {
   /* This BB isn't on the path to dominator root anymore.  */
   bb->aux = (void*)2;
@@ -1427,28 +1437,16 @@  nt_fini_block (struct dom_walk_data *data ATTRIBUTE_UNUSED, basic_block bb)
 static struct pointer_set_t *
 get_non_trapping (void)
 {
-  struct pointer_set_t *nontrap;
-  struct dom_walk_data walk_data;
-
   nt_call_phase = 0;
-  nontrap = pointer_set_create ();
+  pointer_set_t *nontrap = pointer_set_create ();
   seen_ssa_names.create (128);
   /* We're going to do a dominator walk, so ensure that we have
      dominance information.  */
   calculate_dominance_info (CDI_DOMINATORS);
 
-  /* Setup callbacks for the generic dominator tree walker.  */
-  nontrap_set = nontrap;
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = nt_init_block;
-  walk_data.after_dom_children = nt_fini_block;
-  walk_data.global_data = NULL;
-  walk_data.block_local_data_size = 0;
-
-  init_walk_dominator_tree (&walk_data);
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-  fini_walk_dominator_tree (&walk_data);
+  nontrapping_dom_walker (CDI_DOMINATORS, nontrap)
+    .walk (cfun->cfg->x_entry_block_ptr);
+
   seen_ssa_names.dispose ();
 
   clear_aux_for_blocks ();
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 56b0573..0015622 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -4051,10 +4051,19 @@  eliminate_insert (gimple_stmt_iterator *gsi, tree val)
   return res;
 }
 
+class eliminate_dom_walker : public dom_walker
+{
+public:
+  eliminate_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+};
+
 /* Perform elimination for the basic-block B during the domwalk.  */
 
-static void
-eliminate_bb (dom_walk_data *, basic_block b)
+void
+eliminate_dom_walker::before_dom_children (basic_block b)
 {
   gimple_stmt_iterator gsi;
   gimple stmt;
@@ -4403,8 +4412,8 @@  eliminate_bb (dom_walk_data *, basic_block b)
 
 /* Make no longer available leaders no longer available.  */
 
-static void
-eliminate_leave_block (dom_walk_data *, basic_block)
+void
+eliminate_dom_walker::after_dom_children (basic_block)
 {
   tree entry;
   while ((entry = el_avail_stack.pop ()) != NULL_TREE)
@@ -4416,7 +4425,6 @@  eliminate_leave_block (dom_walk_data *, basic_block)
 static unsigned int
 eliminate (void)
 {
-  struct dom_walk_data walk_data;
   gimple_stmt_iterator gsi;
   gimple stmt;
   unsigned i;
@@ -4430,15 +4438,7 @@  eliminate (void)
   el_avail.create (0);
   el_avail_stack.create (0);
 
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = eliminate_bb;
-  walk_data.after_dom_children = eliminate_leave_block;
-  walk_data.global_data = NULL;
-  walk_data.block_local_data_size = 0;
-  init_walk_dominator_tree (&walk_data);
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-  fini_walk_dominator_tree (&walk_data);
+  eliminate_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
 
   el_avail.release ();
   el_avail_stack.release ();
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 5c21b92..e6bca9a 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -1926,12 +1926,20 @@  do_invalidate (basic_block dombb, gimple phi, bitmap visited, int *count)
     }
 }
 
+class strlen_dom_walker : public dom_walker
+{
+public:
+  strlen_dom_walker (cdi_direction direction) : dom_walker (direction) {}
+
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+};
+
 /* Callback for walk_dominator_tree.  Attempt to optimize various
    string ops by remembering string lenths pointed by pointer SSA_NAMEs.  */
 
-static void
-strlen_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		    basic_block bb)
+void
+strlen_dom_walker::before_dom_children (basic_block bb)
 {
   gimple_stmt_iterator gsi;
   basic_block dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
@@ -2014,9 +2022,8 @@  strlen_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 /* Callback for walk_dominator_tree.  Free strinfo vector if it is
    owned by the current bb, clear bb->aux.  */
 
-static void
-strlen_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		    basic_block bb)
+void
+strlen_dom_walker::after_dom_children (basic_block bb)
 {
   if (bb->aux)
     {
@@ -2040,8 +2047,6 @@  strlen_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 static unsigned int
 tree_ssa_strlen (void)
 {
-  struct dom_walk_data walk_data;
-
   ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names);
   max_stridx = 1;
   strinfo_pool = create_alloc_pool ("strinfo_struct pool",
@@ -2051,21 +2056,7 @@  tree_ssa_strlen (void)
 
   /* String length optimization is implemented as a walk of the dominator
      tree and a forward walk of statements within each block.  */
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = strlen_enter_block;
-  walk_data.after_dom_children = strlen_leave_block;
-  walk_data.block_local_data_size = 0;
-  walk_data.global_data = NULL;
-
-  /* Initialize the dominator walker.  */
-  init_walk_dominator_tree (&walk_data);
-
-  /* Recursively walk the dominator tree.  */
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-
-  /* Finalize the dominator walker.  */
-  fini_walk_dominator_tree (&walk_data);
+  strlen_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
 
   ssa_ver_to_stridx.release ();
   free_alloc_pool (strinfo_pool);
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 837c4ea..b5a2580 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -259,11 +259,6 @@  associate_equivalences_with_edges (void)
    so with each value we have a list of SSA_NAMEs that have the
    same value.  */
 
-/* As we enter each block we record the value for any edge equivalency
-   leading to this block.  If no such edge equivalency exists, then we
-   record NULL.  These equivalences are live until we leave the dominator
-   subtree rooted at the block where we record the equivalency.  */
-static vec<tree> equiv_stack;
 
 /* Main structure for recording equivalences into our hash table.  */
 struct equiv_hash_elt
@@ -316,8 +311,6 @@  val_ssa_equiv_hasher::remove (value_type *elt)
    able to reuse tree-vn for this code.  */
 static hash_table <val_ssa_equiv_hasher> val_ssa_equiv;
 
-static void uncprop_enter_block (struct dom_walk_data *, basic_block);
-static void uncprop_leave_block (struct dom_walk_data *, basic_block);
 static void uncprop_into_successor_phis (basic_block);
 
 /* Remove the most recently recorded equivalency for VALUE.  */
@@ -361,47 +354,54 @@  record_equiv (tree value, tree equivalence)
   an_equiv_elt_p->equivalences.safe_push (equivalence);
 }
 
+class uncprop_dom_walker : public dom_walker
+{
+public:
+  uncprop_dom_walker (cdi_direction direction)
+    : dom_walker (direction)
+  {
+    equiv_stack_.create (2);
+  }
+  ~uncprop_dom_walker ()
+  {
+    equiv_stack_.release ();
+  }
+
+  virtual void before_dom_children (basic_block);
+  virtual void after_dom_children (basic_block);
+
+private:
+
+/* As we enter each block we record the value for any edge equivalency
+   leading to this block.  If no such edge equivalency exists, then we
+   record NULL.  These equivalences are live until we leave the dominator
+   subtree rooted at the block where we record the equivalency.  */
+  vec<tree> equiv_stack_;
+};
+
 /* Main driver for un-cprop.  */
 
 static unsigned int
 tree_ssa_uncprop (void)
 {
-  struct dom_walk_data walk_data;
   basic_block bb;
 
   associate_equivalences_with_edges ();
 
   /* Create our global data structures.  */
   val_ssa_equiv.create (1024);
-  equiv_stack.create (2);
 
   /* We're going to do a dominator walk, so ensure that we have
      dominance information.  */
   calculate_dominance_info (CDI_DOMINATORS);
 
-  /* Setup callbacks for the generic dominator tree walker.  */
-  walk_data.dom_direction = CDI_DOMINATORS;
-  walk_data.initialize_block_local_data = NULL;
-  walk_data.before_dom_children = uncprop_enter_block;
-  walk_data.after_dom_children = uncprop_leave_block;
-  walk_data.global_data = NULL;
-  walk_data.block_local_data_size = 0;
-
-  /* Now initialize the dominator walker.  */
-  init_walk_dominator_tree (&walk_data);
-
   /* Recursively walk the dominator tree undoing unprofitable
      constant/copy propagations.  */
-  walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
-
-  /* Finalize and clean up.  */
-  fini_walk_dominator_tree (&walk_data);
+  uncprop_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr);
 
-  /* EQUIV_STACK should already be empty at this point, so we just
-     need to empty elements out of the hash table, free EQUIV_STACK,
-     and cleanup the AUX field on the edges.  */
+  /* we just need to empty elements out of the hash table, and cleanup the
+    AUX field on the edges.  */
   val_ssa_equiv.dispose ();
-  equiv_stack.release ();
   FOR_EACH_BB (bb)
     {
       edge e;
@@ -424,12 +424,11 @@  tree_ssa_uncprop (void)
    any finalization actions in preparation for leaving this node in
    the dominator tree.  */
 
-static void
-uncprop_leave_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		     basic_block bb ATTRIBUTE_UNUSED)
+void
+uncprop_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED)
 {
   /* Pop the topmost value off the equiv stack.  */
-  tree value = equiv_stack.pop ();
+  tree value = equiv_stack_.pop ();
 
   /* If that value was non-null, then pop the topmost equivalency off
      its equivalency stack.  */
@@ -547,9 +546,8 @@  single_incoming_edge_ignoring_loop_edges (basic_block bb)
   return retval;
 }
 
-static void
-uncprop_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
-		     basic_block bb)
+void
+uncprop_dom_walker::before_dom_children (basic_block bb)
 {
   basic_block parent;
   edge e;
@@ -568,13 +566,13 @@  uncprop_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 	  struct edge_equivalency *equiv = (struct edge_equivalency *) e->aux;
 
 	  record_equiv (equiv->rhs, equiv->lhs);
-	  equiv_stack.safe_push (equiv->rhs);
+	  equiv_stack_.safe_push (equiv->rhs);
 	  recorded = true;
 	}
     }
 
   if (!recorded)
-    equiv_stack.safe_push (NULL_TREE);
+    equiv_stack_.safe_push (NULL_TREE);
 
   uncprop_into_successor_phis (bb);
 }
-- 
1.8.4.rc3