------- Comment #4 from abel at gcc dot gnu dot org 2010-01-11 14:35 ------- (In reply to comment #2)
This is the other bug in our region walk iterator that happens when pipelining outer loops. When looking for loop exits from an inner loop that is contained in the outer loop currently being pipelined, we need to work harder to skip several consecutive inner loops if needed. The iterator assumes that all preheaders of inner loops are available, so when skipping an inner loop, it expects to find a block of an outer loop (which is possibly the preheader of the next inner loop). When we are removing empty blocks in the region body, this is not the case, and we are immediately hitting the header of the next inner loop. Fortunately, the bug is rather easily fixed by using the already implemented infrastructure as below. * sel-sched-ir.h (get_all_loop_exits): Include exits from inner loops. diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h index 06082ac..317258c 100644 --- a/gcc/sel-sched-ir.h +++ b/gcc/sel-sched-ir.h @@ -1147,7 +1147,8 @@ get_all_loop_exits (basic_block bb) /* Traverse all loop headers. */ for (i = 0; VEC_iterate (edge, exits, i, e); i++) - if (in_current_region_p (e->dest)) + if (in_current_region_p (e->dest) + || inner_loop_header_p (e->dest)) { VEC(edge, heap) *next_exits = get_all_loop_exits (e->dest); -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42246