summaryrefslogtreecommitdiff
path: root/gcc/tree-cfgcleanup.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-28 13:14:23 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2014-02-28 13:14:23 +0000
commit0ab3f60312b3864458f772842fbeeaf3a3a1ad64 (patch)
tree0023e9b450aa8229d6be88c990e0dbfb8631eb19 /gcc/tree-cfgcleanup.c
parent7168cc342e96f1b0a2cd2aaaf4500ea2b17fd4f5 (diff)
downloadgcc-0ab3f60312b3864458f772842fbeeaf3a3a1ad64.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208222 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-cfgcleanup.c')
-rw-r--r--gcc/tree-cfgcleanup.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index b5c384b902c..926d3000dc5 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -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);