From 5cf6635b26c757412e1a3124c604c9ccb319ff9d Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 7 Aug 2013 17:17:07 +0000 Subject: [PATCH] rtl.h (update_alignments): Declare. * rtl.h (update_alignments): Declare. * final.c (grow_label_align): New function extracted from... (shorten_branches): ...here. Call it. (update_alignments): New function. * reorg.c (sibling_labels): New variable. (get_label_before): Add SIBLING parameter. If it is non-zero, push the new label along with it onto the sibling_labels vector. (fill_simple_delay_slots): Adjust call to get_label_before. (fill_slots_from_thread): Likewise. (relax_delay_slots): Likewise. (make_return_insns): Likewise. (dbr_schedule): Invoke update_alignment on the sibling_labels vector. From-SVN: r201575 --- gcc/ChangeLog | 15 ++++++++++++ gcc/final.c | 67 ++++++++++++++++++++++++++++++++++++--------------- gcc/reorg.c | 28 ++++++++++++++++----- gcc/rtl.h | 1 + 4 files changed, 86 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d55f0f450fc..798a89966b0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2013-08-07 Eric Botcazou + + * rtl.h (update_alignments): Declare. + * final.c (grow_label_align): New function extracted from... + (shorten_branches): ...here. Call it. + (update_alignments): New function. + * reorg.c (sibling_labels): New variable. + (get_label_before): Add SIBLING parameter. If it is non-zero, push + the new label along with it onto the sibling_labels vector. + (fill_simple_delay_slots): Adjust call to get_label_before. + (fill_slots_from_thread): Likewise. + (relax_delay_slots): Likewise. + (make_return_insns): Likewise. + (dbr_schedule): Invoke update_alignment on the sibling_labels vector. + 2013-08-07 Eric Botcazou * diagnostic.c (diagnostic_classify_diagnostic): Accept zero index and diff --git a/gcc/final.c b/gcc/final.c index b755957bebd..31ced4f483b 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -795,6 +795,53 @@ compute_alignments (void) return 0; } +/* Grow the LABEL_ALIGN array after new labels are created. */ + +static void +grow_label_align (void) +{ + int old = max_labelno; + int n_labels; + int n_old_labels; + + max_labelno = max_label_num (); + + n_labels = max_labelno - min_labelno + 1; + n_old_labels = old - min_labelno + 1; + + label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels); + + /* Range of labels grows monotonically in the function. Failing here + means that the initialization of array got lost. */ + gcc_assert (n_old_labels <= n_labels); + + memset (label_align + n_old_labels, 0, + (n_labels - n_old_labels) * sizeof (struct label_alignment)); +} + +/* Update the already computed alignment information. LABEL_PAIRS is a vector + made up of pairs of labels for which the alignment information of the first + element will be copied from that of the second element. */ + +void +update_alignments (vec &label_pairs) +{ + unsigned int i = 0; + rtx iter, label; + + if (max_labelno != max_label_num ()) + grow_label_align (); + + FOR_EACH_VEC_ELT (label_pairs, i, iter) + if (i & 1) + { + LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter); + LABEL_TO_MAX_SKIP (label) = LABEL_TO_MAX_SKIP (iter); + } + else + label = iter; +} + namespace { const pass_data pass_data_compute_alignments = @@ -869,25 +916,7 @@ shorten_branches (rtx first) uid_shuid = XNEWVEC (int, max_uid); if (max_labelno != max_label_num ()) - { - int old = max_labelno; - int n_labels; - int n_old_labels; - - max_labelno = max_label_num (); - - n_labels = max_labelno - min_labelno + 1; - n_old_labels = old - min_labelno + 1; - - label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels); - - /* Range of labels grows monotonically in the function. Failing here - means that the initialization of array got lost. */ - gcc_assert (n_old_labels <= n_labels); - - memset (label_align + n_old_labels, 0, - (n_labels - n_old_labels) * sizeof (struct label_alignment)); - } + grow_label_align (); /* Initialize label_align and set up uid_shuid to be strictly monotonically rising with insn order. */ diff --git a/gcc/reorg.c b/gcc/reorg.c index 78804088a43..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 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; diff --git a/gcc/rtl.h b/gcc/rtl.h index 0846aabbd29..b5bfdffebc1 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -2749,6 +2749,7 @@ extern void simplify_using_condition (rtx, rtx *, bitmap); /* In final.c */ extern unsigned int compute_alignments (void); +extern void update_alignments (vec &); extern int asm_str_count (const char *templ); struct rtl_hooks -- 2.30.2