Hi,
This is a simple refactoring patch which can help long compile time issue 
reported as PR72855.
Basically, it moves cheaper checks before expensive ones.  By doing this, 
doloop -optimization
fails on cheap checks, thus following expensive data-flow analysis is skipped.
Bill helped bootstrap/test on powerpc64le-unknown-linux-gnu.  Is it OK?

Thanks,
bin

2016-08-12  Bin Cheng  <bin.ch...@arm.com>

        PR rtl-optimization/72855
        * loop-doloop.c (doloop_insn_valid_p): New function.
        (doloop_valid_p): Rename to...
        (doloop_niter_valid_p): ...this.  Factor out insn check to function
        doloop_insn_valid_p.
        (doloop_optimize): Update uses.
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;

Reply via email to