diff mbox

Refactor doloop by moving cheaper checks earlier.

Message ID VI1PR0802MB21768CE12B22070F10B12FCAE71F0@VI1PR0802MB2176.eurprd08.prod.outlook.com
State New
Headers show

Commit Message

Bin Cheng Aug. 12, 2016, 9:13 a.m. UTC
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.cheng@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.

Comments

Jeff Law Aug. 16, 2016, 4:58 p.m. UTC | #1
On 08/12/2016 03:13 AM, Bin Cheng wrote:
> 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.cheng@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.
>
Presumably it's the call into the IV code that you're trying to avoid, 
right?

I'd issue distinct messages for the !doloop_insn_valid_p and 
!doloop_niter_valid_p cases.  Then you can include the testcase and 
check for which of the two exit paths you took from doloop_optimize to 
ensure you're getting the early exit you want.

OK with that change.

jeff
diff mbox

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;