Insert new exit block only when needed in transform_to_exit_first_loop_alt
authorTom de Vries <tom@codesourcery.com>
Wed, 11 Nov 2015 20:22:12 +0000 (20:22 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Wed, 11 Nov 2015 20:22:12 +0000 (20:22 +0000)
2015-11-11  Tom de Vries  <tom@codesourcery.com>

* tree-parloops.c (transform_to_exit_first_loop_alt): Insert new exit
block only when needed.

From-SVN: r230188

gcc/ChangeLog
gcc/tree-parloops.c

index c37cf78627a92397cd223d08b0424ee211095ed4..8d6833017f5fcb08fb21c0217a52c77fe09901fe 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-11  Tom de Vries  <tom@codesourcery.com>
+
+       * tree-parloops.c (transform_to_exit_first_loop_alt): Insert new exit
+       block only when needed.
+
 2015-11-11  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/alpha/alpha-protos.h (print_operand): Remove.
index 3d41275c4d35182ca140a928ffd133274c7dc823..6a49aa9688da718b3a29f516f8f9ff8d9b106862 100644 (file)
@@ -1695,10 +1695,15 @@ transform_to_exit_first_loop_alt (struct loop *loop,
   /* Set the latch arguments of the new phis to ivtmp/sum_b.  */
   flush_pending_stmts (post_inc_edge);
 
-  /* Create a new empty exit block, inbetween the new loop header and the old
-     exit block.  The function separate_decls_in_region needs this block to
-     insert code that is active on loop exit, but not any other path.  */
-  basic_block new_exit_block = split_edge (exit);
+
+  basic_block new_exit_block = NULL;
+  if (!single_pred_p (exit->dest))
+    {
+      /* Create a new empty exit block, inbetween the new loop header and the
+        old exit block.  The function separate_decls_in_region needs this block
+        to insert code that is active on loop exit, but not any other path.  */
+      new_exit_block = split_edge (exit);
+    }
 
   /* Insert and register the reduction exit phis.  */
   for (gphi_iterator gsi = gsi_start_phis (exit_block);
@@ -1706,17 +1711,24 @@ transform_to_exit_first_loop_alt (struct loop *loop,
        gsi_next (&gsi))
     {
       gphi *phi = gsi.phi ();
+      gphi *nphi = NULL;
       tree res_z = PHI_RESULT (phi);
+      tree res_c;
 
-      /* Now that we have a new exit block, duplicate the phi of the old exit
-        block in the new exit block to preserve loop-closed ssa.  */
-      edge succ_new_exit_block = single_succ_edge (new_exit_block);
-      edge pred_new_exit_block = single_pred_edge (new_exit_block);
-      tree res_y = copy_ssa_name (res_z, phi);
-      gphi *nphi = create_phi_node (res_y, new_exit_block);
-      tree res_c = PHI_ARG_DEF_FROM_EDGE (phi, succ_new_exit_block);
-      add_phi_arg (nphi, res_c, pred_new_exit_block, UNKNOWN_LOCATION);
-      add_phi_arg (phi, res_y, succ_new_exit_block, UNKNOWN_LOCATION);
+      if (new_exit_block != NULL)
+       {
+         /* Now that we have a new exit block, duplicate the phi of the old
+            exit block in the new exit block to preserve loop-closed ssa.  */
+         edge succ_new_exit_block = single_succ_edge (new_exit_block);
+         edge pred_new_exit_block = single_pred_edge (new_exit_block);
+         tree res_y = copy_ssa_name (res_z, phi);
+         nphi = create_phi_node (res_y, new_exit_block);
+         res_c = PHI_ARG_DEF_FROM_EDGE (phi, succ_new_exit_block);
+         add_phi_arg (nphi, res_c, pred_new_exit_block, UNKNOWN_LOCATION);
+         add_phi_arg (phi, res_y, succ_new_exit_block, UNKNOWN_LOCATION);
+       }
+      else
+       res_c = PHI_ARG_DEF_FROM_EDGE (phi, exit);
 
       if (virtual_operand_p (res_z))
        continue;
@@ -1724,7 +1736,9 @@ transform_to_exit_first_loop_alt (struct loop *loop,
       gimple *reduc_phi = SSA_NAME_DEF_STMT (res_c);
       struct reduction_info *red = reduction_phi (reduction_list, reduc_phi);
       if (red != NULL)
-       red->keep_res = nphi;
+       red->keep_res = (nphi != NULL
+                        ? nphi
+                        : phi);
     }
 
   /* We're going to cancel the loop at the end of gen_parallel_loop, but until