On 02/12/11 11:40, Richard Sandiford wrote: > Tom de Vries <tom_devr...@mentor.com> writes: >> On 27/11/11 23:59, Eric Botcazou wrote: >>>> No, DELETED_LABEL notes still work just fine. It depends on how you >>>> remove the label and replace it with a note, and Tom isn't showing >>>> what he did, so... >>> >>> I agree that there is no obvious reason why just calling delete_insn would >>> not >>> work, so this should be investigated first. >>> >> >> The reason it didn't work, is because after turning a label into a >> NOTE_INSN_DELETED_LABEL, one needs to move it to after the >> NOTE_INSN_BASIC_BLOCK >> as in cfgcleanup.c:try_optimize_cfg(): >> ... >> delete_insn_chain (label, label, false); >> /* If the case label is undeletable, move it after the >> BASIC_BLOCK note. */ >> if (NOTE_KIND (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL) >> { >> rtx bb_note = NEXT_INSN (BB_HEAD (b)); >> >> reorder_insns_nobb (label, label, bb_note); >> BB_HEAD (b) = bb_note; >> if (BB_END (b) == bb_note) >> BB_END (b) = label; >> } >> ... >> >> Attached patch factors out this piece of code and reuses it in >> fixup_reorder_chain. > > But isn't... > >> @@ -2637,15 +2658,7 @@ try_optimize_cfg (int mode) >> delete_insn_chain (label, label, false); >> /* If the case label is undeletable, move it after the >> BASIC_BLOCK note. */ >> - if (NOTE_KIND (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL) >> - { >> - rtx bb_note = NEXT_INSN (BB_HEAD (b)); >> - >> - reorder_insns_nobb (label, label, bb_note); >> - BB_HEAD (b) = bb_note; >> - if (BB_END (b) == bb_note) >> - BB_END (b) = label; >> - } >> + fixup_deleted_label (b); > > ...this "delete_insn_chain (label, label, false);" call equivalent > to "delete_insn (label)"?
Indeed, it is. > Splitting the operation in two here and: > >> Index: gcc/cfglayout.c >> =================================================================== >> --- gcc/cfglayout.c (revision 181652) >> +++ gcc/cfglayout.c (working copy) >> @@ -857,6 +857,12 @@ fixup_reorder_chain (void) >> (e_taken->src, e_taken->dest)); >> e_taken->flags |= EDGE_FALLTHRU; >> update_br_prob_note (bb); >> + if (LABEL_NUSES (ret_label) == 0 >> + && single_pred_p (e_taken->dest)) >> + { >> + delete_insn (ret_label); >> + fixup_deleted_label (e_taken->dest); >> + } > > ...here seems a little odd. > > Richard OK, factored out delete_label now. Bootstrapped and reg-tested on x86_64. Ok for next stage1? Thanks, - Tom 2011-12-03 Tom de Vries <t...@codesourcery.com> * cfgcleanup.c (delete_label): New function, factored out of ... (try_optimize_cfg): Use deleted_label. * basic-block.h (delete_label): Declare. * cfglayout.c (fixup_reorder_chain): Delete unused label using delete_label. * gcc.dg/superblock.c: New test.
Index: gcc/cfgcleanup.c =================================================================== --- gcc/cfgcleanup.c (revision 181172) +++ gcc/cfgcleanup.c (working copy) @@ -2518,6 +2518,39 @@ trivially_empty_bb_p (basic_block bb) } } +/* Delete the label at the head of BB, and if that results in a DELETED_LABEL + note, move it after the BASIC_BLOCK note of BB. */ + +void +delete_label (basic_block bb) +{ + rtx label = BB_HEAD (bb), deleted_label, bb_note; + gcc_assert (LABEL_P (label)); + + /* Delete the label. */ + delete_insn (label); + if (dump_file) + fprintf (dump_file, "Deleted label in block %i.\n", + bb->index); + + /* Find the DELETED_LABEL note. */ + deleted_label = BB_HEAD (bb); + if (deleted_label == NULL_RTX + || !NOTE_P (deleted_label) + || NOTE_KIND (deleted_label) != NOTE_INSN_DELETED_LABEL) + return; + + /* Find the BASIC_BLOCK note. */ + bb_note = NEXT_INSN (deleted_label); + gcc_assert (bb_note != NULL_RTX && NOTE_INSN_BASIC_BLOCK_P (bb_note)); + + /* Move the DELETED_LABEL note after the BASIC_BLOCK note. */ + reorder_insns_nobb (deleted_label, deleted_label, bb_note); + BB_HEAD (bb) = bb_note; + if (BB_END (bb) == bb_note) + BB_END (bb) = deleted_label; +} + /* Do simple CFG optimizations - basic block merging, simplifying of jump instructions etc. Return nonzero if changes were made. */ @@ -2631,25 +2664,7 @@ try_optimize_cfg (int mode) || !JUMP_P (BB_END (single_pred (b))) || ! label_is_jump_target_p (BB_HEAD (b), BB_END (single_pred (b))))) - { - rtx label = BB_HEAD (b); - - delete_insn_chain (label, label, false); - /* If the case label is undeletable, move it after the - BASIC_BLOCK note. */ - if (NOTE_KIND (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL) - { - rtx bb_note = NEXT_INSN (BB_HEAD (b)); - - reorder_insns_nobb (label, label, bb_note); - BB_HEAD (b) = bb_note; - if (BB_END (b) == bb_note) - BB_END (b) = label; - } - if (dump_file) - fprintf (dump_file, "Deleted label in block %i.\n", - b->index); - } + delete_label (b); /* If we fall through an empty block, we can remove it. */ if (!(mode & CLEANUP_CFGLAYOUT) Index: gcc/cfglayout.c =================================================================== --- gcc/cfglayout.c (revision 181172) +++ gcc/cfglayout.c (working copy) @@ -857,6 +857,9 @@ fixup_reorder_chain (void) (e_taken->src, e_taken->dest)); e_taken->flags |= EDGE_FALLTHRU; update_br_prob_note (bb); + if (LABEL_NUSES (ret_label) == 0 + && single_pred_p (e_taken->dest)) + delete_label (e_taken->dest); continue; } } Index: gcc/basic-block.h =================================================================== --- gcc/basic-block.h (revision 181172) +++ gcc/basic-block.h (working copy) @@ -813,6 +813,7 @@ extern void rtl_make_eh_edge (sbitmap, b enum replace_direction { dir_none, dir_forward, dir_backward, dir_both }; /* In cfgcleanup.c. */ +extern void delete_label (basic_block); extern bool cleanup_cfg (int); extern int flow_find_cross_jump (basic_block, basic_block, rtx *, rtx *, enum replace_direction*); Index: gcc/testsuite/gcc.dg/superblock.c =================================================================== --- /dev/null (new file) +++ gcc/testsuite/gcc.dg/superblock.c (revision 0) @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-asynchronous-unwind-tables -fsched2-use-superblocks -fdump-rtl-sched2 -fdump-rtl-bbro" } */ + +typedef int aligned __attribute__ ((aligned (64))); +extern void abort (void); + +int bar (void *p); + +void +foo (void) +{ + char *p = __builtin_alloca (13); + aligned i; + + if (bar (p) || bar (&i)) + abort (); +} + +/* { dg-final { scan-rtl-dump-times "0 uses" 0 "bbro"} } */ +/* { dg-final { scan-rtl-dump-times "ADVANCING TO" 2 "sched2"} } */ +/* { dg-final { cleanup-rtl-dump "bbro" } } */ +/* { dg-final { cleanup-rtl-dump "sched2" } } */ +