]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport a fix to the 2.95 branch
authorBernd Schmidt <bernds@redhat.co.uk>
Wed, 20 Dec 2000 13:53:00 +0000 (13:53 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Wed, 20 Dec 2000 13:53:00 +0000 (13:53 +0000)
From-SVN: r38397

gcc/ChangeLog
gcc/loop.c
gcc/rtl.h
gcc/rtlanal.c

index 49b0610895a2e1c9221593f9a682317ec070aad9..3edb05f1b2a91056d28fe944a15635541f8402a8 100644 (file)
@@ -1,5 +1,10 @@
 2000-12-20  Bernd Schmidt  <bernds@redhat.co.uk>
 
+       Sun Sep 19 09:03:40 1999  Mark Mitchell  <mark@codesourcery.com>
+       * rtl.h (insns_safe_to_move_p): New function.
+       * loop.c (find_and_verify_loops): Use it.
+       * rtlanal.c (insns_safe_to_move_p): Define it.
+
        Thu Nov  2 19:20:12 2000  J"orn Rennecke <amylaar@redhat.com>
        * reload.c (find_equiv_reg): Test all hard registers for membership
        in the requested class.
index 1aa56b75029a9978d8a190b25b79629c0e1b712e..a85e6d33d477b5061f525f9063e54a4e4a3d7d96 100644 (file)
@@ -2773,6 +2773,7 @@ find_and_verify_loops (f)
          {
            rtx p;
            rtx our_next = next_real_insn (insn);
+           rtx last_insn_to_move = NEXT_INSN (insn);
            int dest_loop;
            int outer_loop = -1;
 
@@ -2824,7 +2825,11 @@ find_and_verify_loops (f)
                && INSN_UID (JUMP_LABEL (p)) != 0
                && condjump_p (p)
                && ! simplejump_p (p)
-               && next_real_insn (JUMP_LABEL (p)) == our_next)
+               && next_real_insn (JUMP_LABEL (p)) == our_next
+               /* If it's not safe to move the sequence, then we
+                  mustn't try.  */
+               && insns_safe_to_move_p (p, NEXT_INSN (insn), 
+                                        &last_insn_to_move))
              {
                rtx target
                  = JUMP_LABEL (insn) ? JUMP_LABEL (insn) : get_last_insn ();
@@ -2893,11 +2898,13 @@ find_and_verify_loops (f)
 
                       /* Include the BARRIER after INSN and copy the
                          block after LOC.  */
-                      new_label = squeeze_notes (new_label, NEXT_INSN (insn));
-                      reorder_insns (new_label, NEXT_INSN (insn), loc);
+                      new_label = squeeze_notes (new_label, 
+                                                 last_insn_to_move);
+                      reorder_insns (new_label, last_insn_to_move, loc);
 
                       /* All those insns are now in TARGET_LOOP_NUM.  */
-                      for (q = new_label; q != NEXT_INSN (NEXT_INSN (insn));
+                      for (q = new_label; 
+                           q != NEXT_INSN (last_insn_to_move);
                            q = NEXT_INSN (q))
                         uid_loop_num[INSN_UID (q)] = target_loop_num;
 
index 8eba5eab5d9dfa89d713a36e8f54ad17a21e26a2..0f43e87dc751339fd3bc23400e172432b0519b1d 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1084,6 +1084,7 @@ extern int for_each_rtx                 PROTO((rtx *, rtx_function, void *));
 extern rtx regno_use_in                        PROTO((int, rtx));
 extern int auto_inc_p                  PROTO((rtx));
 extern void remove_node_from_expr_list PROTO((rtx, rtx *));
+extern int insns_safe_to_move_p         PROTO((rtx, rtx, rtx *));
 
 /* flow.c */
 
index fb4f87c07de31686ed87a11e512f6bc37b47067e..49131a4efedcc3e4a483f6b7cf0a067d4ee5b4b5 100644 (file)
@@ -2289,3 +2289,82 @@ auto_inc_p (x)
     }
   return 0;
 }
+
+/* Return 1 if the sequence of instructions beginning with FROM and up
+   to and including TO is safe to move.  If NEW_TO is non-NULL, and
+   the sequence is not already safe to move, but can be easily
+   extended to a sequence which is safe, then NEW_TO will point to the
+   end of the extended sequence.  
+   For now, this function only checks that the region contains whole
+   exception regiongs, but it could be extended to check additional
+   conditions as well.  */
+
+int
+insns_safe_to_move_p (from, to, new_to)
+     rtx from;
+     rtx to;
+     rtx *new_to;
+{
+  int eh_region_count = 0;
+  int past_to_p = 0;
+  rtx r = from;
+
+  /* By default, assume the end of the region will be what was
+     suggested.  */
+  if (new_to)
+    *new_to = to;
+
+  while (r)
+    {
+      if (GET_CODE (r) == NOTE)
+       {
+         switch (NOTE_LINE_NUMBER (r))
+           {
+           case NOTE_INSN_EH_REGION_BEG:
+             ++eh_region_count;
+             break;
+
+           case NOTE_INSN_EH_REGION_END:
+             if (eh_region_count == 0)
+               /* This sequence of instructions contains the end of
+                  an exception region, but not he beginning.  Moving
+                  it will cause chaos.  */
+               return 0;
+
+             --eh_region_count;
+             break;
+
+           default:
+             break;
+           }
+       }
+      else if (past_to_p)
+       /* If we've passed TO, and we see a non-note instruction, we
+          can't extend the sequence to a movable sequence.  */
+       return 0;
+
+      if (r == to)
+       {
+         if (!new_to)
+           /* It's OK to move the sequence if there were matched sets of
+              exception region notes.  */
+           return eh_region_count == 0;
+         
+         past_to_p = 1;
+       }
+
+      /* It's OK to move the sequence if there were matched sets of
+        exception region notes.  */
+      if (past_to_p && eh_region_count == 0)
+       {
+         *new_to = r;
+         return 1;
+       }
+
+      /* Go to the next instruction.  */
+      r = NEXT_INSN (r);
+    }
+  
+  return 0;
+}