------- Comment #5 from amonakov at gcc dot gnu dot org 2009-12-28 14:23 ------- (In reply to comment #4) > Re. comment #3 - do you have an example of when/how this can happen? Perhaps > you can add it to the comment. >
Here, we are scheduling a loop that looks like this: +---+ | 4 |<--+ +-+-+ | | | v | +---+ | | 5 +-+ | +-+-+ | | | | | v | | +---+ | | exit<-+ 6 | | | +---+ | | | | | v | | +---+ | | +-+ 7 | | | | +---+ | | | | | | | | | +---+ | | | | 8 |<+ | | +-+-+ | | | | | v | | +---+ | ->| 9 +---+ +---+ The order of blocks as given by prev_bb/next_bb corresponds to the figure, but in rev_top_order_index BB8 goes before BB6 (which is OK since they are topologically independent). When BB8 becomes empty in the process of scheduling, in the preparation to delete it we redirect BB7->BB9 branch to BB8 (essentially eliminating a now unneeded jump instruction in the end of BB7). The corresponding comment reads in sel-sched-ir.c reads: /* Check if there is an unnecessary jump in previous basic block leading to next basic block left after removing INSN from stream. If it is so, remove that jump and redirect edge to current basic block (where there was INSN before deletion). This way when NOP will be deleted several instructions later with its basic block we will not get a jump to next instruction, which can be harmful. */ This makes BB6 and BB8 topologically dependent. We then merge BB7 and BB8, creating BB6->BB8 branch, which appears to be a backedge (since topological order has not been recomputed). Since the explanation is quite lengthy, we'd prefer to just leave a reference to this PR in the comment. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42245