+\f
+
+/* 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 */
+};
+