diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-02-13 11:42:04 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-02-13 11:42:04 +0000 |
commit | 51f707cea6e96917153e28f00ba0aaec4410329f (patch) | |
tree | 3a095d13c848a658690fb0f5f21604a2e0184c40 | |
parent | 7da89e8076fc3bc8b0eb22721afdce421d225d71 (diff) | |
download | gcc-51f707cea6e96917153e28f00ba0aaec4410329f.tar.gz |
2013-02-13 Richard Biener <rguenther@suse.de>
* loop-init.c (loop_optimizer_init): Clear loop state when
re-initializing preserved loops.
* loop-unswitch.c (unswitch_single_loop): Return whether
we unswitched the loop. Do not verify loop state here.
(unswitch_loops): When we unswitched a loop discover new
loops.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196010 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/loop-init.c | 3 | ||||
-rw-r--r-- | gcc/loop-unswitch.c | 38 |
3 files changed, 35 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8dff131c7ee..38339d0def7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2013-02-13 Richard Biener <rguenther@suse.de> + + * loop-init.c (loop_optimizer_init): Clear loop state when + re-initializing preserved loops. + * loop-unswitch.c (unswitch_single_loop): Return whether + we unswitched the loop. Do not verify loop state here. + (unswitch_loops): When we unswitched a loop discover new + loops. + 2013-02-13 Kostya Serebryany <kcc@google.com> * config/i386/i386.c: Use 0x7fff8000 as asan_shadow_offset on x86_64 diff --git a/gcc/loop-init.c b/gcc/loop-init.c index 5b3fd63b2e8..b1954ca484f 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -99,6 +99,9 @@ loop_optimizer_init (unsigned flags) #ifdef ENABLE_CHECKING verify_loop_structure (); #endif + + /* Clear all flags. */ + loops_state_clear (~0U); } /* Apply flags to loops. */ diff --git a/gcc/loop-unswitch.c b/gcc/loop-unswitch.c index ded0aed3e0e..6a12952cc99 100644 --- a/gcc/loop-unswitch.c +++ b/gcc/loop-unswitch.c @@ -78,7 +78,7 @@ along with GCC; see the file COPYING3. If not see with handling this case. */ static struct loop *unswitch_loop (struct loop *, basic_block, rtx, rtx); -static void unswitch_single_loop (struct loop *, rtx, int); +static bool unswitch_single_loop (struct loop *, rtx, int); static rtx may_unswitch_on (basic_block, struct loop *, rtx *); /* Prepare a sequence comparing OP0 with OP1 using COMP and jumping to LABEL if @@ -140,13 +140,22 @@ unswitch_loops (void) { loop_iterator li; struct loop *loop; + bool changed = false; /* Go through inner loops (only original ones). */ FOR_EACH_LOOP (li, loop, LI_ONLY_INNERMOST) - unswitch_single_loop (loop, NULL_RTX, 0); + changed |= unswitch_single_loop (loop, NULL_RTX, 0); iv_analysis_done (); + + /* If we unswitched any loop discover new loops that are eventually + exposed by making irreducible regions reducible. */ + if (changed) + { + calculate_dominance_info (CDI_DOMINATORS); + fix_loop_structure (NULL); + } } /* Checks whether we can unswitch LOOP on condition at end of BB -- one of its @@ -241,8 +250,9 @@ reversed_condition (rtx cond) /* Unswitch single LOOP. COND_CHECKED holds list of conditions we already unswitched on and are therefore known to be true in this LOOP. NUM is number of unswitchings done; do not allow it to grow too much, it is too - easy to create example on that the code would grow exponentially. */ -static void + easy to create example on that the code would grow exponentially. + Returns true LOOP was unswitched. */ +static bool unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) { basic_block *bbs; @@ -258,7 +268,7 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) { if (dump_file) fprintf (dump_file, ";; Not unswitching anymore, hit max level\n"); - return; + return false; } /* Only unswitch innermost loops. */ @@ -266,7 +276,7 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) { if (dump_file) fprintf (dump_file, ";; Not unswitching, not innermost loop\n"); - return; + return false; } /* We must be able to duplicate loop body. */ @@ -274,7 +284,7 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) { if (dump_file) fprintf (dump_file, ";; Not unswitching, can't duplicate loop\n"); - return; + return false; } /* The loop should not be too large, to limit code growth. */ @@ -282,7 +292,7 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) { if (dump_file) fprintf (dump_file, ";; Not unswitching, loop too big\n"); - return; + return false; } /* Do not unswitch in cold areas. */ @@ -290,7 +300,7 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) { if (dump_file) fprintf (dump_file, ";; Not unswitching, not hot area\n"); - return; + return false; } /* Nor if the loop usually does not roll. */ @@ -299,7 +309,7 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) { if (dump_file) fprintf (dump_file, ";; Not unswitching, loop iterations < 1\n"); - return; + return false; } do @@ -317,7 +327,7 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) if (i == loop->num_nodes) { free (bbs); - return; + return false; } if (cond != const0_rtx @@ -364,10 +374,6 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) nloop = unswitch_loop (loop, bbs[i], copy_rtx_if_shared (cond), cinsn); gcc_assert (nloop); -#ifdef ENABLE_CHECKING - verify_loop_structure (); -#endif - /* Invoke itself on modified loops. */ unswitch_single_loop (nloop, rconds, num + 1); unswitch_single_loop (loop, conds, num + 1); @@ -377,6 +383,8 @@ unswitch_single_loop (struct loop *loop, rtx cond_checked, int num) free_EXPR_LIST_node (rconds); free (bbs); + + return true; } /* Unswitch a LOOP w.r. to given basic block UNSWITCH_ON. We only support |