#include "insn-config.h"
#include "flags.h"
#include "recog.h"
-#include "toplev.h"
+#include "diagnostic-core.h"
#include "cselib.h"
#include "params.h"
#include "tm_p.h"
{
/* When not optimizing, ensure that edges or forwarder
blocks with different locus are not optimized out. */
- int locus = single_succ_edge (target)->goto_locus;
+ int new_locus = single_succ_edge (target)->goto_locus;
+ int locus = goto_locus;
- if (locus && goto_locus && !locator_eq (locus, goto_locus))
- counter = n_basic_blocks;
- else if (locus)
- goto_locus = locus;
-
- if (INSN_P (BB_END (target)))
+ if (new_locus && locus && !locator_eq (new_locus, locus))
+ new_target = NULL;
+ else
{
- locus = INSN_LOCATOR (BB_END (target));
+ if (new_locus)
+ locus = new_locus;
- if (locus && goto_locus
- && !locator_eq (locus, goto_locus))
- counter = n_basic_blocks;
- else if (locus)
- goto_locus = locus;
+ new_locus = INSN_P (BB_END (target))
+ ? INSN_LOCATOR (BB_END (target)) : 0;
+
+ if (new_locus && locus && !locator_eq (new_locus, locus))
+ new_target = NULL;
+ else
+ {
+ if (new_locus)
+ locus = new_locus;
+
+ goto_locus = locus;
+ }
}
}
}
edge tmp_edge, b_fallthru_edge;
bool c_has_outgoing_fallthru;
bool b_has_incoming_fallthru;
- edge_iterator ei;
/* Avoid overactive code motion, as the forwarder blocks should be
eliminated by edge redirection instead. One exception might have
and loop notes. This is done by squeezing out all the notes
and leaving them there to lie. Not ideal, but functional. */
- FOR_EACH_EDGE (tmp_edge, ei, c->succs)
- if (tmp_edge->flags & EDGE_FALLTHRU)
- break;
-
+ tmp_edge = find_fallthru_edge (c->succs);
c_has_outgoing_fallthru = (tmp_edge != NULL);
- FOR_EACH_EDGE (tmp_edge, ei, b->preds)
- if (tmp_edge->flags & EDGE_FALLTHRU)
- break;
-
+ tmp_edge = find_fallthru_edge (b->preds);
b_has_incoming_fallthru = (tmp_edge != NULL);
b_fallthru_edge = tmp_edge;
next = b->prev_bb;
while (true)
{
-
/* Ignore notes. */
while (!NONDEBUG_INSN_P (i1) && i1 != BB_END (bb1))
i1 = NEXT_INSN (i1);
while (!NONDEBUG_INSN_P (i2) && i2 != BB_END (bb2))
i2 = NEXT_INSN (i2);
+ if ((i1 == BB_END (bb1) && !NONDEBUG_INSN_P (i1))
+ || (i2 == BB_END (bb2) && !NONDEBUG_INSN_P (i2)))
+ break;
+
if (NOTE_P (i1) || NOTE_P (i2)
|| JUMP_P (i1) || JUMP_P (i2))
break;
bool changed;
unsigned max, ix, ix2;
basic_block ev, ev2;
- edge_iterator ei;
/* Nothing to do if there is not at least two incoming edges. */
if (EDGE_COUNT (bb->preds) < 2)
if (EDGE_COUNT (bb->preds) > max)
return false;
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- if (e->flags & EDGE_FALLTHRU)
- {
- fallthru = e;
- break;
- }
- }
+ fallthru = find_fallthru_edge (bb->preds);
changed = false;
for (ix = 0, ev = bb; ix < EDGE_COUNT (ev->preds); )
&& single_succ_edge (ENTRY_BLOCK_PTR)->dest != b))
{
c = b->prev_bb;
+ if (EDGE_COUNT (b->preds) > 0)
+ {
+ edge e;
+ edge_iterator ei;
+
+ 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))
changed = true;
continue;
}
+ /* Merge B with its single successor, if any. */
if (single_succ_p (b)
&& (s = single_succ_edge (b))
&& !(s->flags & EDGE_COMPLEX)