This patch is to fix 2 issues found in dbr_schedule when trying to
fix PR target/64761.  The first is relax_delay_slots removes
the jump insn in the insns like below:

(jump_insn/j 74 58 59 (set (pc) (label_ref:SI 29)) ...)
(barrier 59 74 105)
(note 105 59 29 NOTE_INSN_SWITCH_TEXT_SECTIONS)
(code_label 29 105 30 31 "" [5 uses])
(insn 31 30 32 (set (reg ...

i.e. relax_delay_slot tries to delete the jump insn pointing to
the next active insn of that jump insn as a trivial jump even when
there is a NOTE_INSN_SWITCH_TEXT_SECTIONS note between that jump
and its next active insn.
The second issue is that relax_delay_slots does a variant of
follow jump optimization without checking targetm.can_follow_jump.

--
        PR target/64761
        * reorg.c (switch_text_sections_between_p): New function.
        (relax_delay_slots): Call it when testing if the jump insn
        is removable.  Use targetm.can_follow_jump when testing if
        the conditional branch can follow an unconditional jump.

diff --git a/reorg.c b/reorg.c
index 326fa53..2387910 100644
--- a/reorg.c
+++ b/reorg.c
@@ -3211,6 +3211,19 @@ label_before_next_insn (rtx x, rtx scan_limit)
   return insn;
 }
 
+/* Return TRUE if there is a NOTE_INSN_SWITCH_TEXT_SECTIONS note in between
+   BEG and END.  */
+
+static bool
+switch_text_sections_between_p (const rtx_insn *beg, const rtx_insn *end)
+{
+  const rtx_insn *p;
+  for (p = beg; p != end; p = NEXT_INSN (p))
+    if (NOTE_P (p) && NOTE_KIND (p) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
+      return true;
+  return false;
+}
+
 
 /* Once we have tried two ways to fill a delay slot, make a pass over the
    code to try to improve the results and to do such things as more jump
@@ -3247,7 +3260,8 @@ relax_delay_slots (rtx_insn *first)
            target_label = find_end_label (target_label);
 
          if (target_label && next_active_insn (target_label) == next
-             && ! condjump_in_parallel_p (insn))
+             && ! condjump_in_parallel_p (insn)
+             && ! (next && switch_text_sections_between_p (insn, next)))
            {
              delete_jump (insn);
              continue;
@@ -3262,12 +3276,13 @@ relax_delay_slots (rtx_insn *first)
 
          /* See if this jump conditionally branches around an unconditional
             jump.  If so, invert this jump and point it to the target of the
-            second jump.  */
+            second jump.  Check if it's possible on the target.  */
          if (next && simplejump_or_return_p (next)
              && any_condjump_p (insn)
              && target_label
              && next_active_insn (target_label) == next_active_insn (next)
-             && no_labels_between_p (insn, next))
+             && no_labels_between_p (insn, next)
+             && targetm.can_follow_jump (insn, next))
            {
              rtx label = JUMP_LABEL (next);
 

Reply via email to