diff options
Diffstat (limited to 'gcc/reorg.c')
-rw-r--r-- | gcc/reorg.c | 132 |
1 files changed, 92 insertions, 40 deletions
diff --git a/gcc/reorg.c b/gcc/reorg.c index e601818a0d0..d39cc7d8a4a 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -1856,10 +1856,15 @@ update_reg_unused_notes (rtx insn, rtx redundant_insn) } } -/* Return the label before INSN, or put a new label there. */ +static vec <rtx> sibling_labels; + +/* Return the label before INSN, or put a new label there. If SIBLING is + non-zero, it is another label associated with the new label (if any), + typically the former target of the jump that will be redirected to + the new label. */ static rtx -get_label_before (rtx insn) +get_label_before (rtx insn, rtx sibling) { rtx label; @@ -1874,6 +1879,11 @@ get_label_before (rtx insn) label = gen_label_rtx (); emit_label_after (label, prev); LABEL_NUSES (label) = 0; + if (sibling) + { + sibling_labels.safe_push (label); + sibling_labels.safe_push (sibling); + } } return label; } @@ -2219,7 +2229,7 @@ fill_simple_delay_slots (int non_jumps_p) rtx new_label = next_real_insn (next_trial); if (new_label != 0) - new_label = get_label_before (new_label); + new_label = get_label_before (new_label, JUMP_LABEL (trial)); else new_label = find_end_label (simple_return_rtx); @@ -2770,7 +2780,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread, else if (LABEL_P (new_thread)) label = new_thread; else - label = get_label_before (new_thread); + label = get_label_before (new_thread, JUMP_LABEL (insn)); if (label) { @@ -3321,7 +3331,7 @@ relax_delay_slots (rtx first) /* Now emit a label before the special USE insn, and redirect our jump to the new label. */ - target_label = get_label_before (PREV_INSN (tmp)); + target_label = get_label_before (PREV_INSN (tmp), target_label); reorg_redirect_jump (delay_insn, target_label); next = insn; continue; @@ -3495,7 +3505,7 @@ make_return_insns (rtx first) for (insn = first; insn; insn = NEXT_INSN (insn)) if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn))) { - rtx t = get_label_before (insn); + rtx t = get_label_before (insn, NULL_RTX); if (PATTERN (insn) == ret_rtx) real_return_label = t; else @@ -3825,6 +3835,12 @@ dbr_schedule (rtx first) fprintf (dump_file, "\n"); } + if (!sibling_labels.is_empty ()) + { + update_alignments (sibling_labels); + sibling_labels.release (); + } + free_resource_info (); free (uid_to_ruid); crtl->dbr_scheduled_p = true; @@ -3852,26 +3868,44 @@ rest_of_handle_delay_slots (void) return 0; } -struct rtl_opt_pass pass_delay_slots = +namespace { + +const pass_data pass_data_delay_slots = { - { - RTL_PASS, - "dbr", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - gate_handle_delay_slots, /* gate */ - rest_of_handle_delay_slots, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_DBR_SCHED, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ - } + RTL_PASS, /* type */ + "dbr", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_gate */ + true, /* has_execute */ + TV_DBR_SCHED, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ }; +class pass_delay_slots : public rtl_opt_pass +{ +public: + pass_delay_slots(gcc::context *ctxt) + : rtl_opt_pass(pass_data_delay_slots, ctxt) + {} + + /* opt_pass methods: */ + bool gate () { return gate_handle_delay_slots (); } + unsigned int execute () { return rest_of_handle_delay_slots (); } + +}; // class pass_delay_slots + +} // anon namespace + +rtl_opt_pass * +make_pass_delay_slots (gcc::context *ctxt) +{ + return new pass_delay_slots (ctxt); +} + /* Machine dependent reorg pass. */ static bool gate_handle_machine_reorg (void) @@ -3887,22 +3921,40 @@ rest_of_handle_machine_reorg (void) return 0; } -struct rtl_opt_pass pass_machine_reorg = +namespace { + +const pass_data pass_data_machine_reorg = { - { - RTL_PASS, - "mach", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - gate_handle_machine_reorg, /* gate */ - rest_of_handle_machine_reorg, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_MACH_DEP, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ - } + RTL_PASS, /* type */ + "mach", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_gate */ + true, /* has_execute */ + TV_MACH_DEP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ }; + +class pass_machine_reorg : public rtl_opt_pass +{ +public: + pass_machine_reorg(gcc::context *ctxt) + : rtl_opt_pass(pass_data_machine_reorg, ctxt) + {} + + /* opt_pass methods: */ + bool gate () { return gate_handle_machine_reorg (); } + unsigned int execute () { return rest_of_handle_machine_reorg (); } + +}; // class pass_machine_reorg + +} // anon namespace + +rtl_opt_pass * +make_pass_machine_reorg (gcc::context *ctxt) +{ + return new pass_machine_reorg (ctxt); +} |