aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgcleanup.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2010-05-17 17:18:24 +0000
committerJakub Jelinek <jakub@redhat.com>2010-05-17 17:18:24 +0000
commit7057f5f7ae462a4a9bb6b3072834a3b49525e75e (patch)
tree853ebe1e37eec54e09a73297268d1cf4b6fd5c1c /gcc/cfgcleanup.c
parent38e07dd5691eb90ba5bd07454bf5633f474181f8 (diff)
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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@159495 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgcleanup.c')
-rw-r--r--gcc/cfgcleanup.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 75f56519a26..7139e3a7bce 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -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))