http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54146
--- Comment #28 from Steven Bosscher <steven at gcc dot gnu.org> 2012-08-07 19:58:00 UTC --- To illustrate the rewrite_into_closed_loop_ssa problem, consider this test case: extern void use1 (int); extern void use2 (int); extern int confuse_loop (void); void foo (void) { int i, j, k; for (i = 0; i < 100; i++) { for (j = 0; j < 100; j++) { k = i + j; if (j > 2) use1 (k); if (confuse_loop ()) break; } use2 (k); } } The only PHI needed for loop-closed SSA is one for k before "use2(k)". One problem is that GCC ends up inserting two PHI nodes (one on the exit after confuse_loop(), which is wasteful if the exit block is empty. So problem 1 is that too many PHIs are inserted. The second problem is that with multiple loop exits, a large part of the CFG is walked in compute_global_livein. The CFG for the test case (compiled with -fno-tree-ch) looks like this: +---<------------ 14 ------<-----+ E / \ E N / \ X T -> 2 - 9 --> 3 --> 4 --> 5 -> 11 ----------> 7 -> 8 -> I R / \ / \ / T Y / +-> 10 -+ +-> 6 -> 13 ->--+ \ / +----<-- 12 --<---+ And the following blocks are visited (with a patch I will attach in a minute -- without the patch even more blocks are visited). Block 3 is the block containing the def, so the CFG walk ends there. XXX visiting block 7 XXX visiting block 13 XXX visiting block 6 XXX visiting block 5 XXX visiting block 4 XXX visiting block 10 XXX visiting block 11 ;; Created LCSSA PHI: k_4 = PHI <k_14(5)> ;; Created LCSSA PHI: k_8 = PHI <k_14(6)> ;; Resulting GIMPLE function IR: foo () { int k; int j; int i; int D.1727; <bb 2>: goto <bb 9>; <bb 12>: <bb 3>: # j_29 = PHI <j_18(12), 0(9)> k_14 = i_28 + j_29; if (j_29 > 2) goto <bb 4>; else goto <bb 10>; <bb 10>: goto <bb 5>; <bb 4>: use1 (k_14); <bb 5>: D.1727_17 = confuse_loop (); if (D.1727_17 != 0) goto <bb 11>; else goto <bb 6>; <bb 11>: # k_4 = PHI <k_14(5)> goto <bb 7>; <bb 6>: j_18 = j_29 + 1; if (j_18 <= 99) goto <bb 12>; else goto <bb 13>; <bb 13>: # k_8 = PHI <k_14(6)> <bb 7>: # k_21 = PHI <k_4(11), k_8(13)> use2 (k_21); i_20 = i_28 + 1; if (i_20 <= 99) goto <bb 14>; else goto <bb 8>; <bb 8>: return; <bb 14>: <bb 9>: # i_28 = PHI <i_20(14), 0(2)> goto <bb 3>; }