diff options
author | Richard Biener <rguenther@suse.de> | 2014-02-28 13:14:23 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-02-28 13:14:23 +0000 |
commit | fba7c56424a5ffc8e098c7b4638c19f2545ef2be (patch) | |
tree | 0023e9b450aa8229d6be88c990e0dbfb8631eb19 /gcc | |
parent | 0618dee54e14e37e88ab4cf47e7372da8f333719 (diff) | |
download | gcc-fba7c56424a5ffc8e098c7b4638c19f2545ef2be.zip gcc-fba7c56424a5ffc8e098c7b4638c19f2545ef2be.tar.gz gcc-fba7c56424a5ffc8e098c7b4638c19f2545ef2be.tar.bz2 |
re PR tree-optimization/60280 (gcc.target/arm/ivopts.c and gcc.target/arm/ivopts-2.c failed caused by preserving loop structure.)
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.
From-SVN: r208222
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/tree-cfgcleanup.c | 29 |
2 files changed, 30 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f90cc91..3d33ce0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +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 diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index b5c384b..926d300 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); |