diff options
Diffstat (limited to 'gcc/cse.c')
| -rw-r--r-- | gcc/cse.c | 117 |
1 files changed, 117 insertions, 0 deletions
@@ -43,6 +43,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "target.h" #include "params.h" #include "rtlhooks-def.h" +#include "tree-pass.h" /* The basic idea of common subexpression elimination is to go through the code, keeping a record of expressions that would @@ -7741,3 +7742,119 @@ cse_condition_code_reg (void) } } } + + +/* Perform common subexpression elimination. Nonzero value from + `cse_main' means that jumps were simplified and some code may now + be unreachable, so do jump optimization again. */ +static bool +gate_handle_cse (void) +{ + return optimize > 0; +} + +static void +rest_of_handle_cse (void) +{ + int tem; + + if (dump_file) + dump_flow_info (dump_file); + + reg_scan (get_insns (), max_reg_num ()); + + tem = cse_main (get_insns (), max_reg_num (), dump_file); + if (tem) + rebuild_jump_labels (get_insns ()); + if (purge_all_dead_edges ()) + delete_unreachable_blocks (); + + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + + /* If we are not running more CSE passes, then we are no longer + expecting CSE to be run. But always rerun it in a cheap mode. */ + cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse; + + if (tem) + delete_dead_jumptables (); + + if (tem || optimize > 1) + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); +} + +struct tree_opt_pass pass_cse = +{ + "cse1", /* name */ + gate_handle_cse, /* gate */ + rest_of_handle_cse, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_CSE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 's' /* letter */ +}; + + +static bool +gate_handle_cse2 (void) +{ + return optimize > 0 && flag_rerun_cse_after_loop; +} + +/* Run second CSE pass after loop optimizations. */ +static void +rest_of_handle_cse2 (void) +{ + int tem; + + if (dump_file) + dump_flow_info (dump_file); + + tem = cse_main (get_insns (), max_reg_num (), dump_file); + + /* Run a pass to eliminate duplicated assignments to condition code + registers. We have to run this after bypass_jumps, because it + makes it harder for that pass to determine whether a jump can be + bypassed safely. */ + cse_condition_code_reg (); + + purge_all_dead_edges (); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + + if (tem) + { + timevar_push (TV_JUMP); + rebuild_jump_labels (get_insns ()); + delete_dead_jumptables (); + cleanup_cfg (CLEANUP_EXPENSIVE); + timevar_pop (TV_JUMP); + } + reg_scan (get_insns (), max_reg_num ()); + cse_not_expected = 1; +} + + +struct tree_opt_pass pass_cse2 = +{ + "cse2", /* name */ + gate_handle_cse2, /* gate */ + rest_of_handle_cse2, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_CSE2, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 't' /* letter */ +}; + |
