stmt.c (expand_end_loop): Grok code emitted by expand_exit_loop_if_false.
authorJ"orn Rennecke <amylaar@cygnus.co.uk>
Thu, 25 Feb 1999 10:46:06 +0000 (10:46 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Thu, 25 Feb 1999 10:46:06 +0000 (10:46 +0000)
* stmt.c (expand_end_loop): Grok code emitted by
expand_exit_loop_if_false.

From-SVN: r25433

gcc/ChangeLog
gcc/stmt.c

index 8a40b4535616f9785f1a73b14ad3edc147130a36..e164e1f3fadf7efe427d0836e9de4e832840dd36 100644 (file)
@@ -1,3 +1,8 @@
+Thu Feb 25 18:40:06 1999  J"orn Rennecke <amylaar@cygnus.co.uk>
+
+       * stmt.c (expand_end_loop): Grok code emitted by
+       expand_exit_loop_if_false.
+
 Thu Feb 25 10:17:32 1999  Nick Clifton  <nickc@cygnus.com>
 
        * config/arm/arm.c (return_in_memory): Float fields in unions
index 2c0f4f640c29fdf7c227aef87b632cf89b22dead..26ac0247332aa16056970a49cef6d532609ca634 100644 (file)
@@ -2069,6 +2069,7 @@ expand_end_loop ()
 {
   rtx start_label = loop_stack->data.loop.start_label;
   rtx insn = get_last_insn ();
+  int needs_end_jump = 1;
 
   /* Mark the continue-point at the top of the loop if none elsewhere.  */
   if (start_label == loop_stack->data.loop.continue_label)
@@ -2076,9 +2077,77 @@ expand_end_loop ()
 
   do_pending_stack_adjust ();
 
-  /* If optimizing, perhaps reorder the loop.  If the loop starts with
-     a loop exit, roll that to the end where it will optimize together
-     with the jump back.
+  /* If optimizing, perhaps reorder the loop.
+     First, try to use a condjump near the end.
+     expand_exit_loop_if_false ends loops with unconditional jumps,
+     like this:
+
+     if (test) goto label;
+     optional: cleanup
+     goto loop_stack->data.loop.end_label
+     barrier
+     label:
+
+     If we find such a pattern, we can end the loop earlier.  */
+
+  if (optimize
+      && GET_CODE (insn) == CODE_LABEL
+      && LABEL_NAME (insn) == NULL
+      && GET_CODE (PREV_INSN (insn)) == BARRIER)
+    {
+      rtx label = insn;
+      rtx jump = PREV_INSN (PREV_INSN (label));
+
+      if (GET_CODE (jump) == JUMP_INSN
+         && GET_CODE (PATTERN (jump)) == SET
+         && SET_DEST (PATTERN (jump)) == pc_rtx
+         && GET_CODE (SET_SRC (PATTERN (jump))) == LABEL_REF
+         && (XEXP (SET_SRC (PATTERN (jump)), 0)
+             == loop_stack->data.loop.end_label))
+       {
+         rtx prev;
+
+         /* The test might be complex and reference LABEL multiple times,
+            like the loop in loop_iterations to set vtop.  To handle this,
+            we move LABEL.  */
+         insn = PREV_INSN (label);
+         reorder_insns (label, label, start_label);
+
+         for (prev = PREV_INSN (jump); ; prev = PREV_INSN (prev))
+          {
+             /* We ignore line number notes, but if we see any other note,
+                in particular NOTE_INSN_BLOCK_*, NOTE_INSN_EH_REGION_*,
+                NOTE_INSN_LOOP_*, we disable this optimization.  */
+             if (GET_CODE (prev) == NOTE)
+               {
+                 if (NOTE_LINE_NUMBER (prev) < 0)
+                   break;
+                 continue;
+               }
+             if (GET_CODE (prev) == CODE_LABEL)
+               break;
+             if (GET_CODE (prev) == JUMP_INSN)
+               {
+                 if (GET_CODE (PATTERN (prev)) == SET
+                     && SET_DEST (PATTERN (prev)) == pc_rtx
+                     && GET_CODE (SET_SRC (PATTERN (prev))) == IF_THEN_ELSE
+                     && (GET_CODE (XEXP (SET_SRC (PATTERN (prev)), 1))
+                         == LABEL_REF)
+                     && XEXP (XEXP (SET_SRC (PATTERN (prev)), 1), 0) == label)
+                   {
+                     XEXP (XEXP (SET_SRC (PATTERN (prev)), 1), 0)
+                       = start_label;
+                     emit_note_after (NOTE_INSN_LOOP_END, prev);
+                     needs_end_jump = 0;
+                   }
+                 break;
+               }
+          }
+       }
+    }
+
+     /* If the loop starts with a loop exit, roll that to the end where
+     it will optimize together with the jump back.
 
      We look for the conditional branch to the exit, except that once
      we find such a branch, we don't look past 30 instructions.
@@ -2105,6 +2174,7 @@ expand_end_loop ()
      code, terminating in a test.  */
 
   if (optimize
+      && needs_end_jump
       &&
       ! (GET_CODE (insn) == JUMP_INSN
         && GET_CODE (PATTERN (insn)) == SET
@@ -2288,8 +2358,11 @@ expand_end_loop ()
        }
     }
 
-  emit_jump (start_label);
-  emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
+  if (needs_end_jump)
+    {
+      emit_jump (start_label);
+      emit_note (NULL_PTR, NOTE_INSN_LOOP_END);
+    }
   emit_label (loop_stack->data.loop.end_label);
 
   POPSTACK (loop_stack);