OSDN Git Service

* loop.c (load_mems): Avoid using next_label to find end_label. If
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Nov 2000 19:44:30 +0000 (19:44 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 28 Nov 2000 19:44:30 +0000 (19:44 +0000)
jumping outside of the loop (other than loop end), don't hoist MEMs
out of loop.

* gcc.c-torture/execute/loop-8.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37823 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/loop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/loop-8.c [new file with mode: 0644]

index d988b9c..662b849 100644 (file)
@@ -1,3 +1,9 @@
+2000-11-28  Jakub Jelinek  <jakub@redhat.com>
+
+       * loop.c (load_mems): Avoid using next_label to find end_label. If
+       jumping outside of the loop (other than loop end), don't hoist MEMs
+       out of loop.
+
 2000-11-28  Jan Hubicka  <jh@suse.cz>
 
        * calls.c (expand_call): Don't disable tail recursion based
index 7b4fd31..75c94cd 100644 (file)
@@ -8716,7 +8716,7 @@ load_mems (loop)
   int i;
   rtx p;
   rtx label = NULL_RTX;
-  rtx end_label = NULL_RTX;
+  rtx end_label;
   /* Nonzero if the next instruction may never be executed.  */
   int next_maybe_never = 0;
   int last_max_reg = max_reg_num ();
@@ -8724,21 +8724,14 @@ load_mems (loop)
   if (loop_info->mems_idx == 0)
     return;
 
-  /* Find start of the extended basic block that enters the loop.  */
-  for (p = loop->start;
-       PREV_INSN (p) && GET_CODE (p) != CODE_LABEL;
-       p = PREV_INSN (p))
-    ;
-
-  cselib_init ();
+  /* We cannot use next_label here because it skips over normal insns.  */
+  end_label = next_nonnote_insn (loop->end);
+  if (end_label && GET_CODE (end_label) != CODE_LABEL)
+    end_label = NULL_RTX;
 
-  /* Build table of mems that get set to constant values before the
-     loop.  */
-  for (; p != loop->start; p = NEXT_INSN (p))
-    cselib_process_insn (p);
-
-  /* Check to see if it's possible that some instructions in the
-     loop are never executed.  */
+  /* Check to see if it's possible that some instructions in the loop are
+     never executed.  Also check if there is a goto out of the loop other
+     than right after the end of the loop.  */
   for (p = next_insn_in_loop (loop, loop->scan_start);
        p != NULL_RTX && ! maybe_never;
        p = next_insn_in_loop (loop, p))
@@ -8757,6 +8750,15 @@ load_mems (loop)
                     && NEXT_INSN (NEXT_INSN (p)) == loop->end
                     && any_uncondjump_p (p)))
        {
+         /* If this is a jump outside of the loop but not right
+            after the end of the loop, we would have to emit new fixup
+            sequences for each such label.  */
+         if (JUMP_LABEL (p) != end_label
+             && (INSN_UID (JUMP_LABEL (p)) >= max_uid_for_loop
+                 || INSN_LUID (JUMP_LABEL (p)) < INSN_LUID (loop->start)
+                 || INSN_LUID (JUMP_LABEL (p)) > INSN_LUID (loop->end)))
+           return;
+
          if (!any_condjump_p (p))
            /* Something complicated.  */
            maybe_never = 1;
@@ -8769,6 +8771,19 @@ load_mems (loop)
        maybe_never = 1;
     }
 
+  /* Find start of the extended basic block that enters the loop.  */
+  for (p = loop->start;
+       PREV_INSN (p) && GET_CODE (p) != CODE_LABEL;
+       p = PREV_INSN (p))
+    ;
+
+  cselib_init ();
+
+  /* Build table of mems that get set to constant values before the
+     loop.  */
+  for (; p != loop->start; p = NEXT_INSN (p))
+    cselib_process_insn (p);
+
   /* Actually move the MEMs.  */
   for (i = 0; i < loop_info->mems_idx; ++i)
     {
@@ -8960,10 +8975,6 @@ load_mems (loop)
            {
              if (label == NULL_RTX)
                {
-                 /* We must compute the former
-                    right-after-the-end label before we insert
-                    the new one.  */
-                 end_label = next_label (loop->end);
                  label = gen_label_rtx ();
                  emit_label_after (label, loop->end);
                }
@@ -9001,7 +9012,7 @@ load_mems (loop)
        }
     }
 
-  if (label != NULL_RTX)
+  if (label != NULL_RTX && end_label != NULL_RTX)
     {
       /* Now, we need to replace all references to the previous exit
         label with the new one.  */
index f60af3f..f854473 100644 (file)
@@ -1,3 +1,7 @@
+2000-11-28  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c-torture/execute/loop-8.c: New test.
+
 2000-11-28  Nathan Sidwell  <nathan@codesourcery.com>
 
        * g++.old-deja/g++.other/base1.C: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/loop-8.c b/gcc/testsuite/gcc.c-torture/execute/loop-8.c
new file mode 100644 (file)
index 0000000..e8d8cb5
--- /dev/null
@@ -0,0 +1,23 @@
+double a[3] = { 0.0, 1.0, 2.0 };
+
+void bar (int x, double *y)
+{
+  if (x || *y != 1.0)
+    abort ();
+}
+
+int main ()
+{
+  double c;
+  int d;
+  for (d = 0; d < 3; d++)
+  {
+    c = a[d];
+    if (c > 0.0) goto e;
+  }
+  bar(1, &c);
+  exit (1);
+e:
+  bar(0, &c);
+  exit (0);
+}