This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Restrict and fix the PR60280 fix


This narrows down the effect of the PR60280 fix (removing more
forwarder blocks during cfg-cleanup when loops are present) to
only remove forwarders how loop_optimizer_init would create
them.  It also fixes the loop latch updating in remove_forwarder_block
(though that doesn't have any immediate effect as we fixup loops
anywya) - it was set to the wrong loop.  Which also made me
figure that we don't honor !LOOPS_MAY_HAVE_MULTIPLE_LATCHES
properly (also fixed).

Maybe any of the above will fix the gromacs miscompare HJ is seeing
(can't reproduce it).

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

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.

Index: gcc/tree-cfgcleanup.c
===================================================================
--- gcc/tree-cfgcleanup.c	(revision 208216)
+++ gcc/tree-cfgcleanup.c	(working copy)
@@ -316,13 +316,22 @@ tree_forwarder_block_p (basic_block bb,
       /* 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]