aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-02-13 11:42:04 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-02-13 11:42:04 +0000
commitc1874a876fe3c66e40e84862a0b79a4951f7476b (patch)
tree3a095d13c848a658690fb0f5f21604a2e0184c40
parentb4ab7d34f5ee89e23f75cb25585bc851c7f713b3 (diff)
loop-init.c (loop_optimizer_init): Clear loop state when re-initializing preserved loops.
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. From-SVN: r196010
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/loop-init.c3
-rw-r--r--gcc/loop-unswitch.c38
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