re PR tree-optimization/60280 (gcc.target/arm/ivopts.c and gcc.target/arm/ivopts...
authorRichard Biener <rguenther@suse.de>
Fri, 28 Feb 2014 13:14:23 +0000 (13:14 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 28 Feb 2014 13:14:23 +0000 (13:14 +0000)
2014-02-28  Richard Biener  <rguenther@suse.de>

PR target/60280
* tree-cfgcleanup.c (tree_forwarder_block_p): Restrict
previous fix and only allow to remove trivial pre-headers
and latches.  Also honor LOOPS_MAY_HAVE_MULTIPLE_LATCHES.
(remove_forwarder_block): Properly update the latch of
a loop.

From-SVN: r208222

gcc/ChangeLog
gcc/tree-cfgcleanup.c

index f90cc91371bccaf4f4dacdffd78a4f9ce358e348..3d33ce004e9b0fe56e183a72df765b03b6553fbd 100644 (file)
@@ -1,3 +1,12 @@
+2014-02-28  Richard Biener  <rguenther@suse.de>
+
+       PR target/60280
+       * tree-cfgcleanup.c (tree_forwarder_block_p): Restrict
+       previous fix and only allow to remove trivial pre-headers
+       and latches.  Also honor LOOPS_MAY_HAVE_MULTIPLE_LATCHES.
+       (remove_forwarder_block): Properly update the latch of
+       a loop.
+
 2014-02-28  Alexandre Oliva <aoliva@redhat.com>
 
        PR debug/59992
index b5c384b902ca37566dd6c95d3ee69b678fd7995e..926d3000dc51884125c7cad0a885557758550551 100644 (file)
@@ -316,13 +316,22 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted)
       /* Protect loop preheaders and latches if requested.  */
       if (dest->loop_father->header == dest)
        {
-         if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS)
-             && bb->loop_father->header != dest)
-           return false;
-
-         if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)
-             && bb->loop_father->header == dest)
-           return false;
+         if (bb->loop_father == dest->loop_father)
+           {
+             if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES))
+               return false;
+             /* If bb doesn't have a single predecessor we'd make this
+                loop have multiple latches.  Don't do that if that
+                would in turn require disambiguating them.  */
+             return (single_pred_p (bb)
+                     || loops_state_satisfies_p
+                          (LOOPS_MAY_HAVE_MULTIPLE_LATCHES));
+           }
+         else if (bb->loop_father == loop_outer (dest->loop_father))
+           return !loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS);
+         /* Always preserve other edges into loop headers that are
+            not simple latches or preheaders.  */
+         return false;
        }
     }
 
@@ -417,6 +426,10 @@ remove_forwarder_block (basic_block bb)
 
   can_move_debug_stmts = MAY_HAVE_DEBUG_STMTS && single_pred_p (dest);
 
+  basic_block pred = NULL;
+  if (single_pred_p (bb))
+    pred = single_pred (bb);
+
   /* Redirect the edges.  */
   for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
     {
@@ -510,7 +523,7 @@ remove_forwarder_block (basic_block bb)
   /* Adjust latch infomation of BB's parent loop as otherwise
      the cfg hook has a hard time not to kill the loop.  */
   if (current_loops && bb->loop_father->latch == bb)
-    bb->loop_father->latch = dest;
+    bb->loop_father->latch = pred;
 
   /* And kill the forwarder block.  */
   delete_basic_block (bb);