[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