[PATCH] manage dom-walk_data initialization and finalization with constructors and destructors

Trevor Saunders tsaunders@mozilla.com
Tue Sep 17 19:42:00 GMT 2013


> I'd like to go ahead and get your patch installed -- do you have a
> GCC copyright assignment on file with the FSF?  Your change is large
> enough to require one.

Its my understanding that Mozilla has one covering work done by
employees which would include me.

sorry about the formatting issues.

Trev

> 
> For reference I've attached the updated patch with the style nits I
> noticed fixed.
> 
> +         /* Callback for subclasses to do custom things before we
> have walked
> +          * the dominator children, but before we walk statements.  */
> +           before_dom_children (bb);
> 
> Comments look like
>         /* blah blah
>            blah blah
>            blah blah blah.  */
> 
> And the indention of the before_com_children (bb) statement was
> incorrect.  I've fixed these nits.
> 
> +         /* Callback allowing subclasses to do custom things after we have
> +          * walked dominator children, but before we walk statements.  */
> +    after_dom_children (bb);
> Similarly here.  Comment formatting and indention of the
> after_dom_children statement.
> 
> +public:
> +  dom_walker (cdi_direction direction)
> +    : dom_direction_ (direction) {}
> No reason I can see to split this line.  Fixed.
> 
> +  /**
> +   * Walk the dominator tree.
> +   */
> +  void walk (basic_block);
> Comment style.  Fixed.
> 
> 
> The ChangeLog had numerous formatting problems which I fixed as well.
> 
> 

> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index 78f4cbc..406eae2 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,96 @@
> +2013-09-17  Trevor Saunders  <tsaunders@mozilla.com>
> +
> +	* 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, 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, build_sese_conditions): 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_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, rewrite_into_ssa): 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.
> +	* 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, tree_ssa_lim): Adjust.
> +	* tree-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.
> +
>  2013-09-17  Jeff Law  <law@redhat.com>
>  
>  	* tree-ssa-dom.c (cprop_into_successor_phis): Also propagate
> 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..bffa4aa 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..b33d70e 100644
> --- a/gcc/domwalk.h
> +++ b/gcc/domwalk.h
> @@ -18,57 +18,35 @@ 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 53ed6b3..8d48add 100644
> --- a/gcc/gimple-ssa-strength-reduction.c
> +++ b/gcc/gimple-ssa-strength-reduction.c
> @@ -1571,11 +1571,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;
> @@ -3488,8 +3495,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);
>  
> @@ -3509,18 +3514,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))
>      {
> @@ -3531,8 +3528,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 1527603..4985691 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 726744d..384d3b3 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 4a2b48b..aac7aa4 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 ee4298e..d066950 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 20d805a..c12ed7f 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 ec13ed9..39d04ab 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 3608214..c53ec44 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 8d61267..c30ab33 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 8439df1..a13ccf0 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);
>  }



More information about the Gcc-patches mailing list