https://gcc.gnu.org/bugzilla/show_bug.cgi?id=72855

--- Comment #4 from amker at gcc dot gnu.org ---
Here is a simple refactoring patch.

diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index c311516..9fb04cf 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -254,18 +254,51 @@ doloop_condition_get (rtx doloop_pat)
   return 0;
 }

-/* Return nonzero if the loop specified by LOOP is suitable for
-   the use of special low-overhead looping instructions.  DESC
-   describes the number of iterations of the loop.  */
+/* Check all insns of LOOP to see if the loop is suitable for the use of
+   special low-overhead looping instructions.  Return TRUE if yes, false
+   otherwise.  */

 static bool
-doloop_valid_p (struct loop *loop, struct niter_desc *desc)
+doloop_insn_valid_p (struct loop *loop)
 {
-  basic_block *body = get_loop_body (loop), bb;
-  rtx_insn *insn;
   unsigned i;
-  bool result = true;
+  rtx_insn *insn;
+  basic_block *body = get_loop_body (loop), bb;

+  for (i = 0; i < loop->num_nodes; i++)
+    {
+      bb = body[i];
+
+      for (insn = BB_HEAD (bb);
+          insn != NEXT_INSN (BB_END (bb));
+          insn = NEXT_INSN (insn))
+       {
+         /* Different targets have different necessities for low-overhead
+            looping.  Call the back end for each instruction within the loop
+            to let it decide whether the insn prohibits a low-overhead loop.
+            It will then return the cause for it to emit to the dump file.  */
+         const char * invalid = targetm.invalid_within_doloop (insn);
+         if (invalid)
+           {
+             if (dump_file)
+               fprintf (dump_file, "Doloop: %s\n", invalid);
+
+             free (body);
+             return false;
+           }
+       }
+    }
+  free (body);
+  return true;
+}
+
+/* Check the number of iterations described by DESC of a loop to see if
+   the loop is suitable for the use of special low-overhead looping
+   instructions.  Return true if yes, false otherwise.  */
+
+static bool
+doloop_niter_valid_p (struct loop *, struct niter_desc *desc)
+{
   /* Check for loops that may not terminate under special conditions.  */
   if (!desc->simple_p
       || desc->assumptions
@@ -295,38 +328,10 @@ doloop_valid_p (struct loop *loop, struct niter_desc
*desc)
         enable count-register loops in this case.  */
       if (dump_file)
        fprintf (dump_file, "Doloop: Possible infinite iteration case.\n");
-      result = false;
-      goto cleanup;
-    }
-
-  for (i = 0; i < loop->num_nodes; i++)
-    {
-      bb = body[i];
-
-      for (insn = BB_HEAD (bb);
-          insn != NEXT_INSN (BB_END (bb));
-          insn = NEXT_INSN (insn))
-       {
-         /* Different targets have different necessities for low-overhead
-            looping.  Call the back end for each instruction within the loop
-            to let it decide whether the insn prohibits a low-overhead loop.
-            It will then return the cause for it to emit to the dump file.  */
-         const char * invalid = targetm.invalid_within_doloop (insn);
-         if (invalid)
-           {
-             if (dump_file)
-               fprintf (dump_file, "Doloop: %s\n", invalid);
-             result = false;
-             goto cleanup;
-           }
-       }
+      return false;
     }
-  result = true;
-
-cleanup:
-  free (body);

-  return result;
+  return true;
 }

 /* Adds test of COND jumping to DEST on edge *E and set *E to the new fallthru
@@ -621,17 +626,25 @@ doloop_optimize (struct loop *loop)
   if (dump_file)
     fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);

+  if (!doloop_insn_valid_p (loop))
+    {
+      if (dump_file)
+       fprintf (dump_file, "Doloop: The loop is not suitable.\n");
+
+      return false;
+    }
+
   iv_analysis_loop_init (loop);

   /* Find the simple exit of a LOOP.  */
   desc = get_simple_loop_desc (loop);

   /* Check that loop is a candidate for a low-overhead looping insn.  */
-  if (!doloop_valid_p (loop, desc))
+  if (!doloop_niter_valid_p (loop, desc))
     {
       if (dump_file)
-       fprintf (dump_file,
-                "Doloop: The loop is not suitable.\n");
+       fprintf (dump_file, "Doloop: The loop is not suitable.\n");
+
       return false;
     }
   mode = desc->mode;

It reduces compile time for powerpc-elf on x86_64 machine from 54m to 5m.  The
compiler is configured with checking.  With "--enable-checking=release", the
current trunk compiles for ~5m too, but gcc in Ubuntu has the issue even it's
configured as release?

Reply via email to