This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix removal of trivially empty bb's even in CFGRTL mode (PR middle-end/44102)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Guenther <rguenther at suse dot de>, Richard Henderson <rth at redhat dot com>, Jan Hubicka <jh at suse dot cz>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 13 May 2010 15:59:46 +0200
- Subject: Re: [PATCH] Fix removal of trivially empty bb's even in CFGRTL mode (PR middle-end/44102)
- References: <20100513104444.GZ2817@tyan-ft48-01.lab.bos.redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On Thu, May 13, 2010 at 12:44:44PM +0200, Jakub Jelinek wrote:
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.5?
Honza mentioned on IRC that there might be multiple EDGE_FALLTHRU
predecessors, so this patch attempts to handle all of them, not just the
first one.
2010-05-13 Jakub Jelinek <jakub@redhat.com>
PR middle-end/44102
* cfgcleanup.c (try_optimize_cfg): When removing trivially empty
bb with no successors, move footer whenever in IR_RTL_CFGLAYOUT
mode, not just when CLEANUP_CFGLAYOUT, and when in IR_RTL_CFGRTL
add BARRIER after previous bb if needed.
* g++.dg/ext/asmgoto1.C: New test.
--- gcc/cfgcleanup.c.jj 2010-05-13 12:39:54.000000000 +0200
+++ gcc/cfgcleanup.c 2010-05-13 15:57:40.000000000 +0200
@@ -1999,24 +1999,40 @@ try_optimize_cfg (int mode)
&& single_succ_edge (ENTRY_BLOCK_PTR)->dest != b))
{
c = b->prev_bb;
- if ((mode & CLEANUP_CFGLAYOUT)
- && EDGE_COUNT (b->preds) > 0
- && b->il.rtl->footer
- && BARRIER_P (b->il.rtl->footer))
+ if (EDGE_COUNT (b->preds) > 0)
{
edge e;
edge_iterator ei;
- FOR_EACH_EDGE (e, ei, b->preds)
- if (e->flags & EDGE_FALLTHRU)
- {
- if (e->src->il.rtl->footer == NULL)
- {
- e->src->il.rtl->footer = b->il.rtl->footer;
- b->il.rtl->footer = NULL;
- }
- break;
- }
+ if (current_ir_type () == IR_RTL_CFGLAYOUT)
+ {
+ if (b->il.rtl->footer
+ && BARRIER_P (b->il.rtl->footer))
+ FOR_EACH_EDGE (e, ei, b->preds)
+ if ((e->flags & EDGE_FALLTHRU)
+ && e->src->il.rtl->footer == NULL)
+ {
+ if (b->il.rtl->footer)
+ {
+ e->src->il.rtl->footer = b->il.rtl->footer;
+ b->il.rtl->footer = NULL;
+ }
+ else
+ {
+ start_sequence ();
+ e->src->il.rtl->footer = emit_barrier ();
+ end_sequence ();
+ }
+ }
+ }
+ else
+ {
+ rtx last = get_last_bb_insn (b);
+ if (last && BARRIER_P (last))
+ FOR_EACH_EDGE (e, ei, b->preds)
+ if ((e->flags & EDGE_FALLTHRU))
+ emit_barrier_after (BB_END (e->src));
+ }
}
delete_basic_block (b);
if (!(mode & CLEANUP_CFGLAYOUT))
--- gcc/testsuite/g++.dg/ext/asmgoto1.C.jj 2010-05-13 15:36:49.000000000 +0200
+++ gcc/testsuite/g++.dg/ext/asmgoto1.C 2010-05-13 15:36:49.000000000 +0200
@@ -0,0 +1,32 @@
+// PR middle-end/44102
+// { dg-do compile }
+// { dg-options "-O2" }
+
+void baz (void);
+struct A { A (); ~A (); };
+
+static inline int
+foo (void)
+{
+ asm goto ("" : : : : l1, l2);
+ __builtin_unreachable ();
+ l1:
+ return 1;
+ l2:
+ return 0;
+}
+
+int
+bar (int x)
+{
+ if (x == 5)
+ {
+ A a, b;
+ baz ();
+ }
+ if (foo () || x == 6)
+ x = 1;
+ else
+ x = 2;
+ return x;
+}
Jakub