2013-02-11 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Feb 2013 15:07:40 +0000 (15:07 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 11 Feb 2013 15:07:40 +0000 (15:07 +0000)
PR tree-optimization/56264
* cfgloop.h (fix_loop_structure): Adjust prototype.
* loop-init.c (fix_loop_structure): Return the number of
newly discovered loops.
* tree-cfgcleanup.c (repair_loop_structures): When new loops
are discovered, do a full loop-closed SSA rewrite.

* gcc.dg/torture/pr56264.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@195941 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfgloop.h
gcc/loop-init.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr56264.c [new file with mode: 0644]
gcc/tree-cfgcleanup.c

index 4c69a8d..0cdcc3c 100644 (file)
@@ -1,5 +1,14 @@
 2013-02-11  Richard Biener  <rguenther@suse.de>
 
+       PR tree-optimization/56264
+       * cfgloop.h (fix_loop_structure): Adjust prototype.
+       * loop-init.c (fix_loop_structure): Return the number of
+       newly discovered loops.
+       * tree-cfgcleanup.c (repair_loop_structures): When new loops
+       are discovered, do a full loop-closed SSA rewrite.
+
+2013-02-11  Richard Biener  <rguenther@suse.de>
+
        PR tree-optimization/56273
        * tree-vrp.c (simplify_cond_using_ranges): Disable for the
        first VRP run.
index 7506ac5..0b2af72 100644 (file)
@@ -216,7 +216,7 @@ extern void flow_loop_dump (const struct loop *, FILE *,
 struct loop *alloc_loop (void);
 extern void flow_loop_free (struct loop *);
 int flow_loop_nodes_find (basic_block, struct loop *);
-void fix_loop_structure (bitmap changed_bbs);
+unsigned fix_loop_structure (bitmap changed_bbs);
 bool mark_irreducible_loops (void);
 void release_recorded_exits (void);
 void record_loop_exits (void);
index d64c110..5b3fd63 100644 (file)
@@ -171,16 +171,19 @@ loop_fini_done:
    the latch, and loops did not get new subloops (new loops might possibly
    get created, but we are not interested in them).  Fix up the mess.
 
-   If CHANGED_BBS is not NULL, basic blocks whose loop has changed are
-   marked in it.  */
+   If CHANGED_BBS is not NULL, basic blocks whose loop depth has changed are
+   marked in it.
 
-void
+   Returns the number of new discovered loops.  */
+
+unsigned
 fix_loop_structure (bitmap changed_bbs)
 {
   basic_block bb;
   int record_exits = 0;
   loop_iterator li;
   struct loop *loop;
+  unsigned old_nloops;
 
   timevar_push (TV_LOOP_INIT);
 
@@ -228,6 +231,10 @@ fix_loop_structure (bitmap changed_bbs)
       delete_loop (loop);
     }
 
+  /* Remember the number of loops so we can return how many new loops
+     flow_loops_find discovered.  */
+  old_nloops = number_of_loops ();
+
   /* Re-compute loop structure in-place.  */
   flow_loops_find (current_loops);
 
@@ -253,6 +260,8 @@ fix_loop_structure (bitmap changed_bbs)
 #endif
 
   timevar_pop (TV_LOOP_INIT);
+
+  return number_of_loops () - old_nloops;
 }
 \f
 /* Gate for the RTL loop superpass.  The actual passes are subpasses.
index e21dbf7..f5ada1c 100644 (file)
@@ -1,5 +1,10 @@
 2013-02-11  Richard Biener  <rguenther@suse.de>
 
+       PR tree-optimization/56264
+       * gcc.dg/torture/pr56264.c: New testcase.
+
+2013-02-11  Richard Biener  <rguenther@suse.de>
+
        PR tree-optimization/56273
        * g++.dg/warn/Warray-bounds-6.C: New testcase.
        * gcc.dg/tree-ssa/pr21559.c: Adjust.
diff --git a/gcc/testsuite/gcc.dg/torture/pr56264.c b/gcc/testsuite/gcc.dg/torture/pr56264.c
new file mode 100644 (file)
index 0000000..ca5eb47
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do compile } */\r
+/* { dg-options "-funswitch-loops" } */\r
+\r
+int a, b, c;\r
+\r
+void f(void)\r
+{\r
+  if(b)\r
+    {\r
+      for(a = 0; a < 1; a++)\r
+       lbl:\r
+           c = c && b ? : 0;\r
+\r
+      c = 0;\r
+      goto lbl;\r
+    }\r
+\r
+  if(a)\r
+    goto lbl;\r
+}\r
index b26281d..94e616b 100644 (file)
@@ -707,18 +707,22 @@ static void
 repair_loop_structures (void)
 {
   bitmap changed_bbs;
+  unsigned n_new_loops;
 
   calculate_dominance_info (CDI_DOMINATORS);
 
   timevar_push (TV_REPAIR_LOOPS);
   changed_bbs = BITMAP_ALLOC (NULL);
-  fix_loop_structure (changed_bbs);
+  n_new_loops = fix_loop_structure (changed_bbs);
 
   /* This usually does nothing.  But sometimes parts of cfg that originally
      were inside a loop get out of it due to edge removal (since they
-     become unreachable by back edges from latch).  */
+     become unreachable by back edges from latch).  Also a former
+     irreducible loop can become reducible - in this case force a full
+     rewrite into loop-closed SSA form.  */
   if (loops_state_satisfies_p (LOOP_CLOSED_SSA))
-    rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
+    rewrite_into_loop_closed_ssa (n_new_loops ? NULL : changed_bbs,
+                                 TODO_update_ssa);
 
   BITMAP_FREE (changed_bbs);