From 4d9192b50c325156ab000884a57a3d7cfe4f79c6 Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Wed, 18 Sep 2013 02:39:50 +0000 Subject: [PATCH] compare-elim.c (find_comparison_dom_walker): New class * 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. From-SVN: r202679 --- gcc/ChangeLog | 93 +++++++++++++++++ gcc/compare-elim.c | 27 ++--- gcc/domwalk.c | 87 +++------------- gcc/domwalk.h | 70 +++++-------- gcc/fwprop.c | 30 +++--- gcc/gimple-ssa-strength-reduction.c | 29 +++--- gcc/graphite-sese-to-poly.c | 104 ++++++++----------- gcc/tree-into-ssa.c | 156 +++++++++++----------------- gcc/tree-ssa-dom.c | 71 ++++++------- gcc/tree-ssa-dse.c | 33 ++---- gcc/tree-ssa-loop-im.c | 66 ++++++------ gcc/tree-ssa-phiopt.c | 46 ++++---- gcc/tree-ssa-pre.c | 28 ++--- gcc/tree-ssa-strlen.c | 37 +++---- gcc/tree-ssa-uncprop.c | 72 +++++++------ 15 files changed, 428 insertions(+), 521 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3524ca852e4..c28bd10e6a6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,96 @@ +2013-09-17 Trevor Saunders + + * 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-18 Bin Cheng * config/arm/arm.c (thumb1_reorg): Search for flag setting insn diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c index e907376c577..19cf524b1f9 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 8c1ddc69490..bffa4aa4851 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 54b7f3c86d9..b33d70eda23 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 . */ -typedef void *void_p; +#ifndef GCC_DOM_WALK_H +#define GCC_DOM_WALK_H -/* 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 +/** + * 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 { +public: + dom_walker (cdi_direction direction) : dom_direction_ (direction) {} + + /* Walk the dominator tree. */ + void walk (basic_block); + + /* Function to call before the recursive walk of the dominator children. */ + virtual void before_dom_children (basic_block) {} + + /* Function to call after the recursive walk of the dominator children. */ + virtual void after_dom_children (basic_block) {} + +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. */ - ENUM_BITFIELD (cdi_direction) dom_direction : 2; - - /* Function to initialize block local data. - - 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); - - /* Function to call before the recursive walk of the dominator children. */ - void (*before_dom_children) (struct dom_walk_data *, 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; - - /* 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 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 free_block_data; + 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 8fe02ac2a43..137011d3324 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 53ed6b34332..8d48adde01d 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 1527603a99f..49856914782 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 *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 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 *conditions = data->conditions; - vec *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 *conditions = data->conditions; - vec *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 conditions; - conditions.create (3); - vec 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 726744d5003..384d3b33cff 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,40 +2196,19 @@ 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; - - if (what == REWRITE_ALL) - { - walk_data.before_dom_children = rewrite_enter_block; - walk_data.after_dom_children = rewrite_leave_block; - } - else if (what == REWRITE_UPDATE) - { - walk_data.before_dom_children = rewrite_update_enter_block; - walk_data.after_dom_children = rewrite_update_leave_block; - } - 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); + if (what == REWRITE_ALL) + rewrite_dom_walker (CDI_DOMINATORS).walk (entry); + else if (what == REWRITE_UPDATE) + rewrite_update_dom_walker (CDI_DOMINATORS).walk (entry); + else + gcc_unreachable (); /* 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); } +class mark_def_dom_walker : public dom_walker +{ +public: + mark_def_dom_walker (cdi_direction direction); + ~mark_def_dom_walker (); + + 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. */ + bitmap kills_; +}; + +mark_def_dom_walker::mark_def_dom_walker (cdi_direction direction) + : dom_walker (direction), kills_ (BITMAP_ALLOC (NULL)) +{ +} + +mark_def_dom_walker::~mark_def_dom_walker () +{ + BITMAP_FREE (kills_); +} /* 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) +void +mark_def_dom_walker::before_dom_children (basic_block bb) { - 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); + 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_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; - - /* 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; - - /* 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; - - /* We do not have any local data. */ - walk_data.block_local_data_size = 0; - - /* 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); - - /* We no longer need this bitmap, clear and free it. */ - BITMAP_FREE (mark_def_sites_global_data.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 4a2b48bd93d..aac7aa496bb 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 ee4298ec9dd..d0669504325 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 20d805ac40a..c12ed7fb590 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 ec13ed9c0fd..39d04ab2801 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -1264,9 +1264,6 @@ struct ssa_names_hasher : typed_free_remove 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; + nontrapping_dom_walker (CDI_DOMINATORS, nontrap) + .walk (cfun->cfg->x_entry_block_ptr); - init_walk_dominator_tree (&walk_data); - walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR); - fini_walk_dominator_tree (&walk_data); seen_ssa_names.dispose (); clear_aux_for_blocks (); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 36082147439..c53ec44913a 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 8d6126764e4..c30ab33ef28 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 8439df164dd..a13ccf01135 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 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; -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 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); + uncprop_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); - /* Finalize and clean up. */ - fini_walk_dominator_tree (&walk_data); - - /* 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); }