diff options
Diffstat (limited to 'gcc/tree-into-ssa.c')
-rw-r--r-- | gcc/tree-into-ssa.c | 148 |
1 files changed, 57 insertions, 91 deletions
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,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); |