+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
/* 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;
}
}
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)); )
{
/* 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);