diff mbox

[PR,rtl-optimization/59446] Don't pessimize threading through loop exits

Message ID 52A8E3F7.8060302@redhat.com
State New
Headers show

Commit Message

Jeff Law Dec. 11, 2013, 10:15 p.m. UTC
59446 is a missed-optimization error where we want to thread through 
multiple loop exits and that request is being cancelled.

The problem is I was looking at changes in the loop_father as a proxy 
for crossing loop headers.  That was utterly dumb as we can test 
directly for crossing a loop header.  Anyway, we saw the changes in the 
loop structure, figured we were threading through too mean headers and 
truncated the jump thread.  Dumb.

Fixing that happens to clean up the code ever-so-slightly, which is good.

Bootstrapped and regression tested on x86_64-unknown-linux-gnu and 
installed on the trunk.
PR rtl-optimization/59446
	* tree-ssa-threadupdate.c (mark_threaded_blocks): Properly
	test for crossing a loop header.
diff mbox

Patch

diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 6f978e2..af8fd85 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -1449,44 +1449,32 @@  mark_threaded_blocks (bitmap threaded_blocks)
 	    {
 	      vec<jump_thread_edge *> *path = THREAD_PATH (e);
 
-	      /* Basically we're looking for a situation where we can see
-	  	 3 or more loop structures on a jump threading path.  */
-
-	      struct loop *first_father = (*path)[0]->e->src->loop_father;
-	      struct loop *second_father = NULL;
-	      for (unsigned int i = 0; i < path->length (); i++)
+	      for (unsigned int i = 0, crossed_headers = 0;
+		   i < path->length ();
+		   i++)
 		{
-		  /* See if this is a loop father we have not seen before.  */
-		  if ((*path)[i]->e->dest->loop_father != first_father
-		      && (*path)[i]->e->dest->loop_father != second_father)
+		  basic_block dest = (*path)[i]->e->dest;
+		  crossed_headers += (dest == dest->loop_father->header);
+		  if (crossed_headers > 1)
 		    {
-		      /* We've already seen two loop fathers, so we
-			 need to trim this jump threading path.  */
-		      if (second_father != NULL)
-			{
-			  /* Trim from entry I onwards.  */
-			  for (unsigned int j = i; j < path->length (); j++)
-			    delete (*path)[j];
-			  path->truncate (i);
-
-			  /* Now that we've truncated the path, make sure
-			     what's left is still valid.   We need at least
-			     two edges on the path and the last edge can not
-			     be a joiner.  This should never happen, but let's
-			     be safe.  */
-			  if (path->length () < 2
-			      || (path->last ()->type
-				  == EDGE_COPY_SRC_JOINER_BLOCK))
-			    {
-			      delete_jump_thread_path (path);
-			      e->aux = NULL;
-			    }
-			  break;
-			}
-		      else
+		      /* Trim from entry I onwards.  */
+		      for (unsigned int j = i; j < path->length (); j++)
+			delete (*path)[j];
+		      path->truncate (i);
+
+		      /* Now that we've truncated the path, make sure
+			 what's left is still valid.   We need at least
+			 two edges on the path and the last edge can not
+			 be a joiner.  This should never happen, but let's
+			 be safe.  */
+		      if (path->length () < 2
+			  || (path->last ()->type
+			      == EDGE_COPY_SRC_JOINER_BLOCK))
 			{
-			  second_father = (*path)[i]->e->dest->loop_father;
+			  delete_jump_thread_path (path);
+			  e->aux = NULL;
 			}
+		      break;
 		    }
 		}
 	    }