This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Restrict and fix the PR60280 fix
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: bin dot cheng at arm dot com
- Date: Fri, 28 Feb 2014 13:42:01 +0100 (CET)
- Subject: [PATCH] Restrict and fix the PR60280 fix
- Authentication-results: sourceware.org; auth=none
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);