summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2013-08-07 17:17:07 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2013-08-07 17:17:07 +0000
commit5cf6635b26c757412e1a3124c604c9ccb319ff9d (patch)
treebf69301266f96ab07cb8e81f040fa1c0f1d8b4cc
parent3c8ca1abdedb2c0663e24e9dc5942280a8c7820f (diff)
downloadgcc-5cf6635b26c757412e1a3124c604c9ccb319ff9d.tar.gz
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
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/final.c67
-rw-r--r--gcc/reorg.c28
-rw-r--r--gcc/rtl.h1
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,5 +1,20 @@
2013-08-07 Eric Botcazou <ebotcazou@adacore.com>
+ * 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 <ebotcazou@adacore.com>
+
* diagnostic.c (diagnostic_classify_diagnostic): Accept zero index and
document its semantics.
(diagnostic_report_diagnostic): Adjust accordingly.
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<rtx> &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 <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;
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<rtx> &);
extern int asm_str_count (const char *templ);
struct rtl_hooks