tree-ssa-threadedge.c (thread_around_empty_block): Remove checks for the number of...
authorJeff Law <law@redhat.com>
Wed, 28 Aug 2013 15:07:45 +0000 (09:07 -0600)
committerJeff Law <law@gcc.gnu.org>
Wed, 28 Aug 2013 15:07:45 +0000 (09:07 -0600)
        * tree-ssa-threadedge.c (thread_around_empty_block): Remove
        checks for the number of predecessors and successors allowed.
        * tree-ssa-threadupdate.c (mark_threaded_blocks): Ignore requests
        which require copying a joiner block if there is a request which
        is a subpath that requires no joiner block copying.

From-SVN: r202054

gcc/ChangeLog
gcc/tree-ssa-threadedge.c
gcc/tree-ssa-threadupdate.c

index a19826b..3d87dbb 100644 (file)
@@ -1,3 +1,11 @@
+2013-08-28  Jeff Law  <law@redhat.com>
+
+       * tree-ssa-threadedge.c (thread_around_empty_block): Remove
+       checks for the number of predecessors and successors allowed.
+       * tree-ssa-threadupdate.c (mark_threaded_blocks): Ignore requests
+       which require copying a joiner block if there is a request which
+       is a subpath that requires no joiner block copying.
+
 2013-08-28  Jan Hubicka  <jh@suse.cz>
 
        * lto-streamer-out.c (DFS_write_tree_body): Drop
index 320dec5..fc33647 100644 (file)
@@ -761,14 +761,6 @@ thread_around_empty_block (edge taken_edge,
   gimple stmt;
   tree cond;
 
-  /* This block must have a single predecessor (E->dest).  */
-  if (!single_pred_p (bb))
-    return NULL;
-
-  /* This block must have more than one successor.  */
-  if (single_succ_p (bb))
-    return NULL;
-
   /* This block can have no PHI nodes.  This is overly conservative.  */
   if (!gsi_end_p (gsi_start_phis (bb)))
     return NULL;
index 259a691..8a872a3 100644 (file)
@@ -1146,17 +1146,56 @@ mark_threaded_blocks (bitmap threaded_blocks)
   edge e;
   edge_iterator ei;
 
+  /* It is possible to have jump threads in which one is a subpath
+     of the other.  ie, (A, B), (B, C), (C, D) where B is a joiner
+     block and (B, C), (C, D) where no joiner block exists.
+
+     When this occurs ignore the jump thread request with the joiner
+     block.  It's totally subsumed by the simpler jump thread request.
+
+     This results in less block copying, simpler CFGs.  More improtantly,
+     when we duplicate the joiner block, B, in this case we will create
+     a new threading opportunity that we wouldn't be able to optimize
+     until the next jump threading iteration. 
+
+     So first convert the jump thread requests which do not require a
+     joiner block.  */
   for (i = 0; i < threaded_edges.length (); i += 3)
     {
       edge e = threaded_edges[i];
-      edge *x = XNEWVEC (edge, 2);
 
-      e->aux = x;
-      THREAD_TARGET (e) = threaded_edges[i + 1];
-      THREAD_TARGET2 (e) = threaded_edges[i + 2];
-      bitmap_set_bit (tmp, e->dest->index);
+      if (threaded_edges[i + 2] == NULL)
+       {
+         edge *x = XNEWVEC (edge, 2);
+
+         e->aux = x;
+         THREAD_TARGET (e) = threaded_edges[i + 1];
+         THREAD_TARGET2 (e) = NULL;
+         bitmap_set_bit (tmp, e->dest->index);
+       }
     }
 
+
+  /* Now iterate again, converting cases where we threaded through
+     a joiner block, but ignoring those where we have already
+     threaded through the joiner block.  */
+  for (i = 0; i < threaded_edges.length (); i += 3)
+    {
+      edge e = threaded_edges[i];
+
+      if (threaded_edges[i + 2] != NULL
+         && threaded_edges[i + 1]->aux == NULL)
+       {
+         edge *x = XNEWVEC (edge, 2);
+
+         e->aux = x;
+         THREAD_TARGET (e) = threaded_edges[i + 1];
+         THREAD_TARGET2 (e) = threaded_edges[i + 2];
+         bitmap_set_bit (tmp, e->dest->index);
+       }
+    }
+
+
   /* If optimizing for size, only thread through block if we don't have
      to duplicate it or it's an otherwise empty redirection block.  */
   if (optimize_function_for_size_p (cfun))