On Fri, 9 Jan 2015, Jakub Jelinek wrote: > On Fri, Jan 09, 2015 at 11:59:44AM +0100, Richard Biener wrote: > > > If you want, I can try instead of disabling it for tablejumps > > > just move the label. > > > > Yeah, I'd prefer that - it can't be too difficult, no? > > So like this (tested just on the testcase, fully bootstrap/regtest > will follow)?
Yeah. > > > Still, I think we should be able to optimize it somewhere else too > > > (we can remove the tablejumps not just if all jump_table_data > > > entries point to next_bb, but even when they point to some > > > completely different bb, as long as it is a single_succ_p). And > > > ideally also optimize it at GIMPLE, but guess that is GCC 6 > > > material. > > > > cfgcleanup material, similar for GIMPLE I guess. > > You mean that cfgcleanup changes are GCC 6 material too? Well, you have until the end of next week ;) For GIMPLE this is a switch with all cases going to the same basic-block, right? I think we optimize that in cleanup_control_expr_graph via the single_succ_p case? Thanks, Richard. > 2015-01-09 Jakub Jelinek <ja...@redhat.com> > > PR rtl-optimization/64536 > * cfgrtl.c (rtl_tidy_fallthru_edge): Handle removal of degenerate > tablejumps. > > * gcc.dg/pr64536.c: New test. > > --- gcc/cfgrtl.c.jj 2015-01-08 18:10:23.616598916 +0100 > +++ gcc/cfgrtl.c 2015-01-09 14:47:26.637855477 +0100 > @@ -1791,6 +1791,24 @@ rtl_tidy_fallthru_edge (edge e) > && (any_uncondjump_p (q) > || single_succ_p (b))) > { > + rtx label; > + rtx_jump_table_data *table; > + > + if (tablejump_p (q, &label, &table)) > + { > + /* The label is likely mentioned in some instruction before > + the tablejump and might not be DCEd, so turn it into > + a note instead and move before the tablejump that is going to > + be deleted. */ > + const char *name = LABEL_NAME (label); > + PUT_CODE (label, NOTE); > + NOTE_KIND (label) = NOTE_INSN_DELETED_LABEL; > + NOTE_DELETED_LABEL_NAME (label) = name; > + rtx_insn *lab = safe_as_a <rtx_insn *> (label); > + reorder_insns (lab, lab, PREV_INSN (q)); > + delete_insn (table); > + } > + > #ifdef HAVE_cc0 > /* If this was a conditional jump, we need to also delete > the insn that set cc0. */ > --- gcc/testsuite/gcc.dg/pr64536.c.jj 2015-01-09 13:55:53.035267213 +0100 > +++ gcc/testsuite/gcc.dg/pr64536.c 2015-01-09 13:55:53.035267213 +0100 > @@ -0,0 +1,67 @@ > +/* PR rtl-optimization/64536 */ > +/* { dg-do link } */ > +/* { dg-options "-O2" } */ > +/* { dg-additional-options "-fPIC" { target fpic } } */ > + > +struct S { long q; } *h; > +long a, b, g, j, k, *c, *d, *e, *f, *i; > +long *baz (void) > +{ > + asm volatile ("" : : : "memory"); > + return e; > +} > + > +void > +bar (int x) > +{ > + int y; > + for (y = 0; y < x; y++) > + { > + switch (b) > + { > + case 0: > + case 2: > + a++; > + break; > + case 3: > + a++; > + break; > + case 1: > + a++; > + } > + if (d) > + { > + f = baz (); > + g = k++; > + if (&h->q) > + { > + j = *f; > + h->q = *f; > + } > + else > + i = (long *) (h->q = *f); > + *c++ = (long) f; > + e += 6; > + } > + else > + { > + f = baz (); > + g = k++; > + if (&h->q) > + { > + j = *f; > + h->q = *f; > + } > + else > + i = (long *) (h->q = *f); > + *c++ = (long) f; > + e += 6; > + } > + } > +} > + > +int > +main () > +{ > + return 0; > +} > > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild, Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)