OSDN Git Service

2013-02-13 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Feb 2013 11:42:04 +0000 (11:42 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 13 Feb 2013 11:42:04 +0000 (11:42 +0000)
* 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

gcc/ChangeLog
gcc/loop-init.c
gcc/loop-unswitch.c

index 8dff131..38339d0 100644 (file)
@@ -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
index 5b3fd63..b1954ca 100644 (file)
@@ -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.  */
index ded0aed..6a12952 100644 (file)
@@ -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