+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
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);
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);
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);
#endif
timevar_pop (TV_LOOP_INIT);
+
+ return number_of_loops () - old_nloops;
}
\f
/* Gate for the RTL loop superpass. The actual passes are subpasses.
+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
--- /dev/null
+/* { 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
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);