re PR bootstrap/16326 (Bootstrap failure after "RTL prologue/epilogue for SPARC"...
authorEric Botcazou <ebotcazou@libertysurf.fr>
Thu, 8 Jul 2004 06:41:13 +0000 (08:41 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 8 Jul 2004 06:41:13 +0000 (06:41 +0000)
PR bootstrap/16326
* reorg.c: Revert 2004-06-30 change.
(find_end_label): If HAVE_epilogue and !HAVE_return,
return 0 instead of creating a label at the end of the insn chain.
(optimize_skip): Account for the failure mode of find_end_label.
(fill_simple_delay_slots): Likewise.
(fill_slots_from_thread): Likewise.
(relax_delay_slots): Likewise.

From-SVN: r84273

gcc/ChangeLog
gcc/reorg.c

index 8e5f51936e9b48682e77bc73ff16b923138711e2..9e1b8ee5d2fd4a0e28da79bce748732eb58f6048 100644 (file)
@@ -1,3 +1,14 @@
+2004-07-08  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       PR bootstrap/16326
+       * reorg.c: Revert 2004-06-30 change.
+       (find_end_label): If HAVE_epilogue and !HAVE_return,
+       return 0 instead of creating a label at the end of the insn chain.
+       (optimize_skip): Account for the failure mode of find_end_label.
+       (fill_simple_delay_slots): Likewise.
+       (fill_slots_from_thread): Likewise.
+       (relax_delay_slots): Likewise.
+
 2004-07-08  Diego Novillo  <dnovillo@redhat.com>
 
        * tree-flow.h (addressable_vars): Declare.
index da4a1a03e83691d474f43a9561a69a6d557e4847..eb3836696c1922e9ae25e12528e3e1c42a051c33 100644 (file)
@@ -317,23 +317,25 @@ insn_sets_resource_p (rtx insn, struct resources *res,
   mark_set_resources (insn, &insn_sets, 0, include_delayed_effects);
   return resource_conflicts_p (&insn_sets, res);
 }
-
-/* Return TRUE if INSN is a return, possibly with a filled delay slot.  */
-
-static bool
-return_insn_p (rtx insn)
-{
-  if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == RETURN)
-    return true;
-
-  if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
-    return return_insn_p (XVECEXP (PATTERN (insn), 0, 0));
-
-  return false;
-}
 \f
-/* Find a label at the end of the function or before a RETURN.  If there is
-   none, make one.  */
+/* Find a label at the end of the function or before a RETURN.  If there
+   is none, try to make one.  If that fails, returns 0.
+
+   The property of such a label is that it is placed just before the
+   epilogue or a bare RETURN insn, so that another bare RETURN can be
+   turned into a jump to the label unconditionally.  In particular, the
+   label cannot be placed before a RETURN insn with a filled delay slot.
+
+   ??? There may be a problem with the current implementation.  Suppose
+   we start with a bare RETURN insn and call find_end_label.  It may set
+   end_of_function_label just before the RETURN.  Suppose the machinery
+   is able to fill the delay slot of the RETURN insn afterwards.  Then
+   end_of_function_label is no longer valid according to the property
+   described above and find_end_label will still return it unmodified.
+   Note that this is probably mitigated by the following observation:
+   once end_of_function_label is made, it is very likely the target of
+   a jump, so filling the delay slot of the RETURN will be much more
+   difficult.  */
 
 static rtx
 find_end_label (void)
@@ -358,13 +360,15 @@ find_end_label (void)
   /* When a target threads its epilogue we might already have a
      suitable return insn.  If so put a label before it for the
      end_of_function_label.  */
-  if (GET_CODE (insn) == BARRIER && return_insn_p (PREV_INSN (insn)))
+  if (GET_CODE (insn) == BARRIER
+      && GET_CODE (PREV_INSN (insn)) == JUMP_INSN
+      && GET_CODE (PATTERN (PREV_INSN (insn))) == RETURN)
     {
       rtx temp = PREV_INSN (PREV_INSN (insn));
       end_of_function_label = gen_label_rtx ();
       LABEL_NUSES (end_of_function_label) = 0;
 
-      /* Put the label before an USE insn that may precede the RETURN insn.  */
+      /* Put the label before an USE insns that may precede the RETURN insn.  */
       while (GET_CODE (temp) == USE)
        temp = PREV_INSN (temp);
 
@@ -380,7 +384,8 @@ find_end_label (void)
       /* If the basic block reorder pass moves the return insn to
         some other place try to locate it again and put our
         end_of_function_label there.  */
-      while (insn && ! return_insn_p (insn))
+      while (insn && ! (GET_CODE (insn) == JUMP_INSN
+                       && (GET_CODE (PATTERN (insn)) == RETURN)))
        insn = PREV_INSN (insn);
       if (insn)
        {
@@ -395,6 +400,22 @@ find_end_label (void)
        }
       else
        {
+#ifdef HAVE_epilogue
+         if (HAVE_epilogue
+#ifdef HAVE_return
+             && ! HAVE_return
+#endif
+             )
+           {
+             /* The RETURN insn has its delay slot filled so we cannot
+                emit the label just before it.  Since we already have
+                an epilogue and cannot emit a new RETURN, we cannot
+                emit the label at all.  */
+             end_of_function_label = NULL_RTX;
+             return end_of_function_label;
+           }
+#endif /* HAVE_epilogue */
+
          /* Otherwise, make a new label and emit a RETURN and BARRIER,
             if needed.  */
          emit_label (end_of_function_label);
@@ -742,7 +763,6 @@ optimize_skip (rtx insn)
   rtx trial = next_nonnote_insn (insn);
   rtx next_trial = next_active_insn (trial);
   rtx delay_list = 0;
-  rtx target_label;
   int flags;
 
   flags = get_jump_flags (insn, JUMP_LABEL (insn));
@@ -791,17 +811,20 @@ optimize_skip (rtx insn)
          && (simplejump_p (next_trial)
              || GET_CODE (PATTERN (next_trial)) == RETURN))
        {
-         target_label = JUMP_LABEL (next_trial);
+         rtx target_label = JUMP_LABEL (next_trial);
          if (target_label == 0)
            target_label = find_end_label ();
 
-         /* Recompute the flags based on TARGET_LABEL since threading
-            the jump to TARGET_LABEL may change the direction of the
-            jump (which may change the circumstances in which the
-            delay slot is nullified).  */
-         flags = get_jump_flags (insn, target_label);
-         if (eligible_for_annul_true (insn, 0, trial, flags))
-           reorg_redirect_jump (insn, target_label);
+         if (target_label)
+           {
+             /* Recompute the flags based on TARGET_LABEL since threading
+                the jump to TARGET_LABEL may change the direction of the
+                jump (which may change the circumstances in which the
+                delay slot is nullified).  */
+             flags = get_jump_flags (insn, target_label);
+             if (eligible_for_annul_true (insn, 0, trial, flags))
+               reorg_redirect_jump (insn, target_label);
+           }
        }
 
       INSN_ANNULLED_BRANCH_P (insn) = 1;
@@ -2373,15 +2396,18 @@ fill_simple_delay_slots (int non_jumps_p)
              else
                new_label = find_end_label ();
 
-             delay_list
-               = add_to_delay_list (copy_rtx (next_trial), delay_list);
-             slots_filled++;
-             reorg_redirect_jump (trial, new_label);
-
-             /* If we merged because we both jumped to the same place,
-                redirect the original insn also.  */
-             if (target)
-               reorg_redirect_jump (insn, new_label);
+             if (new_label)
+               {
+                 delay_list
+                   = add_to_delay_list (copy_rtx (next_trial), delay_list);
+                 slots_filled++;
+                 reorg_redirect_jump (trial, new_label);
+
+                 /* If we merged because we both jumped to the same place,
+                    redirect the original insn also.  */
+                 if (target)
+                   reorg_redirect_jump (insn, new_label);
+               }
            }
        }
 
@@ -2926,7 +2952,8 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
       else
        label = get_label_before (new_thread);
 
-      reorg_redirect_jump (insn, label);
+      if (label)
+       reorg_redirect_jump (insn, label);
     }
 
   return delay_list;
@@ -3094,14 +3121,14 @@ relax_delay_slots (rtx first)
          if (target_label == 0)
            target_label = find_end_label ();
 
-         if (next_active_insn (target_label) == next
+         if (target_label && next_active_insn (target_label) == next
              && ! condjump_in_parallel_p (insn))
            {
              delete_jump (insn);
              continue;
            }
 
-         if (target_label != JUMP_LABEL (insn))
+         if (target_label && target_label != JUMP_LABEL (insn))
            reorg_redirect_jump (insn, target_label);
 
          /* See if this jump branches around an unconditional jump.
@@ -3109,6 +3136,7 @@ relax_delay_slots (rtx first)
             second jump.  */
          if (next && GET_CODE (next) == JUMP_INSN
              && (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN)
+             && target_label
              && next_active_insn (target_label) == next_active_insn (next)
              && no_labels_between_p (insn, next))
            {
@@ -3242,7 +3270,7 @@ relax_delay_slots (rtx first)
          if (trial == 0)
            trial = find_end_label ();
 
-         if (trial != target_label
+         if (trial && trial != target_label
              && redirect_with_delay_slots_safe_p (delay_insn, trial, insn))
            {
              reorg_redirect_jump (delay_insn, trial);
@@ -3256,23 +3284,24 @@ relax_delay_slots (rtx first)
              && redundant_insn (trial, insn, 0)
              && ! can_throw_internal (trial))
            {
-             rtx tmp;
-
              /* Figure out where to emit the special USE insn so we don't
                 later incorrectly compute register live/death info.  */
-             tmp = next_active_insn (trial);
+             rtx tmp = next_active_insn (trial);
              if (tmp == 0)
                tmp = find_end_label ();
 
-             /* Insert the special USE insn and update dataflow info.  */
-             update_block (trial, tmp);
+             if (tmp)
+               {
+                 /* Insert the special USE insn and update dataflow info.  */
+                 update_block (trial, tmp);
 
-             /* 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));
-             reorg_redirect_jump (delay_insn, target_label);
-             next = insn;
-             continue;
+                 /* 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));
+                 reorg_redirect_jump (delay_insn, target_label);
+                 next = insn;
+                 continue;
+               }
            }
 
          /* Similarly, if it is an unconditional jump with one insn in its
@@ -3286,17 +3315,10 @@ relax_delay_slots (rtx first)
            {
              target_label = JUMP_LABEL (XVECEXP (PATTERN (trial), 0, 0));
              if (target_label == 0)
-               {
-                 target_label = find_end_label ();
-                 /* The following condition may be true if TRIAL contains
-                    the unique RETURN.  In this case, threading would be
-                    a nop and we would enter an infinite loop if we did it.  */
-                 if (next_active_insn (target_label) == trial)
-                   target_label = 0;
-               }
+               target_label = find_end_label ();
 
              if (target_label
-                 && redirect_with_delay_slots_safe_p (delay_insn, target_label,
+                 && redirect_with_delay_slots_safe_p (delay_insn, target_label,
                                                       insn))
                {
                  reorg_redirect_jump (delay_insn, target_label);
@@ -3382,7 +3404,8 @@ relax_delay_slots (rtx first)
            label = find_end_label ();
 
          /* find_end_label can generate a new label. Check this first.  */
-         if (no_labels_between_p (insn, next)
+         if (label
+             && no_labels_between_p (insn, next)
              && redirect_with_delay_slots_safe_p (delay_insn, label, insn))
            {
              /* Be careful how we do this to avoid deleting code or labels