rtl.h (update_alignments): Declare.
authorEric Botcazou <ebotcazou@adacore.com>
Wed, 7 Aug 2013 17:17:07 +0000 (17:17 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Wed, 7 Aug 2013 17:17:07 +0000 (17:17 +0000)
* 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
gcc/final.c
gcc/reorg.c
gcc/rtl.h

index d55f0f450fc739eedb2753e380b4ed39c2650066..798a89966b04d843a6651b768b357cb46f174071 100644 (file)
@@ -1,3 +1,18 @@
+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
index b755957bebd2526a282d7cdea10c64819442dec6..31ced4f483be92157f34ce43b7ed358a563d6af7 100644 (file)
@@ -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.  */
index 78804088a43f34f1e486af1de8755fc19a0965ee..d39cc7d8a4aa37d909cbd7e11deca4c0877b24c2 100644 (file)
@@ -1856,10 +1856,15 @@ update_reg_unused_notes (rtx insn, rtx redundant_insn)
     }
 }
 \f
-/* 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;
index 0846aabbd292c3e29f275fcd3fca09a5460d3361..b5bfdffebc1278991085816f60cff6435655a02a 100644 (file)
--- 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);
 \f
 struct rtl_hooks