#include "flags.h"
#include "output.h"
#include "function.h"
-#include "except.h"
#include "toplev.h"
#include "recog.h"
-#include "insn-flags.h"
#include "expr.h"
#include "obstack.h"
For top-level functions, this is temporary_obstack.
Separate obstacks are made for nested functions. */
-extern struct obstack *function_obstack;
+extern struct obstack flow_obstack;
/* Structure to hold information about lexical scopes. */
taken = probability > REG_BR_PROB_BASE / 2;
/* Find the normal taken edge and the normal fallthru edge.
- Note that there may in fact be other edges due to
- asynchronous_exceptions. */
+
+ Note, conditional jumps with other side effects may not
+ be fully optimized. In this case it is possible for
+ the conditional jump to branch to the same location as
+ the fallthru path.
+
+ We should probably work to improve optimization of that
+ case; however, it seems silly not to also deal with such
+ problems here if they happen to occur. */
e_taken = e_fall = NULL;
for (e = bb->succ; e ; e = e->succ_next)
- if (e->flags & EDGE_FALLTHRU)
- e_fall = e;
- else if (! (e->flags & EDGE_EH))
- e_taken = e;
+ {
+ if (e->flags & EDGE_FALLTHRU)
+ e_fall = e;
+ if (! (e->flags & EDGE_EH))
+ e_taken = e;
+ }
next = (taken ? e_taken : e_fall)->dest;
}
for (bb = BASIC_BLOCK (0); bb ; bb = RBI (bb)->next)
{
edge e_fall, e_taken, e;
- rtx jump_insn, barrier_insn;
+ rtx jump_insn, barrier_insn, bb_end_insn;
basic_block nb;
if (bb->succ == NULL)
else if (! (e->flags & EDGE_EH))
e_taken = e;
- if (GET_CODE (bb->end) == JUMP_INSN)
+ bb_end_insn = bb->end;
+ if (GET_CODE (bb_end_insn) == JUMP_INSN)
{
- if (any_uncondjump_p (bb->end))
+ if (any_uncondjump_p (bb_end_insn))
{
/* If the destination is still not next, nothing to do. */
if (RBI (bb)->index + 1 != RBI (e_taken->dest)->index)
bb->index, RBI (bb)->index);
continue;
}
- else if (any_condjump_p (bb->end))
+ else if (any_condjump_p (bb_end_insn))
{
/* If the old fallthru is still next, nothing to do. */
if (RBI (bb)->index + 1 == RBI (e_fall->dest)->index
edge based on known or assumed probability. */
if (RBI (bb)->index + 1 != RBI (e_taken->dest)->index)
{
- rtx note = find_reg_note (bb->end, REG_BR_PROB, 0);
+ rtx note = find_reg_note (bb_end_insn, REG_BR_PROB, 0);
if (note
&& INTVAL (XEXP (note, 0)) < REG_BR_PROB_BASE / 2
- && invert_jump (bb->end, label_for_bb (e_fall->dest), 0))
+ && invert_jump (bb_end_insn,
+ label_for_bb (e_fall->dest), 0))
{
e_fall->flags &= ~EDGE_FALLTHRU;
e_taken->flags |= EDGE_FALLTHRU;
/* Otherwise we can try to invert the jump. This will
basically never fail, however, keep up the pretense. */
- else if (invert_jump (bb->end, label_for_bb (e_fall->dest), 0))
+ else if (invert_jump (bb_end_insn,
+ label_for_bb (e_fall->dest), 0))
{
e_fall->flags &= ~EDGE_FALLTHRU;
e_taken->flags |= EDGE_FALLTHRU;
continue;
}
}
- else if (returnjump_p (bb->end))
+ else if (returnjump_p (bb_end_insn))
continue;
else
{
tablejump, the fallthru block should not have moved. */
if (RBI (bb)->index + 1 == RBI (e_fall->dest)->index)
continue;
-#endif
+ bb_end_insn = skip_insns_after_block (bb);
+#else
abort ();
+#endif
}
}
else
{
e_fall->flags &= ~EDGE_FALLTHRU;
- jump_insn = emit_jump_to_block_after (e_fall->dest, bb->end);
+ jump_insn = emit_jump_to_block_after (e_fall->dest, bb_end_insn);
bb->end = jump_insn;
barrier_insn = emit_barrier_after (jump_insn);
RBI (bb)->eff_end = barrier_insn;
/* We got here if we need to add a new jump insn in a new block
across the edge e_fall. */
- jump_insn = emit_jump_to_block_after (e_fall->dest, bb->end);
+ jump_insn = emit_jump_to_block_after (e_fall->dest, bb_end_insn);
barrier_insn = emit_barrier_after (jump_insn);
VARRAY_GROW (basic_block_info, ++n_basic_blocks);
create_basic_block (n_basic_blocks - 1, jump_insn, jump_insn, NULL);
nb = BASIC_BLOCK (n_basic_blocks - 1);
- nb->global_live_at_start = OBSTACK_ALLOC_REG_SET (function_obstack);
- nb->global_live_at_end = OBSTACK_ALLOC_REG_SET (function_obstack);
+ nb->global_live_at_start = OBSTACK_ALLOC_REG_SET (&flow_obstack);
+ nb->global_live_at_end = OBSTACK_ALLOC_REG_SET (&flow_obstack);
nb->local_set = 0;
COPY_REG_SET (nb->global_live_at_start, bb->global_live_at_start);
{
while (x)
{
- if (GET_CODE (x) == NOTE
- && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
+ if (NOTE_INSN_BASIC_BLOCK_P (x))
return x;
x = NEXT_INSN (x);
}
{
while (x)
{
- if (GET_CODE (x) == NOTE
- && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
+ if (NOTE_INSN_BASIC_BLOCK_P (x))
return x;
x = PREV_INSN (x);
}
rtx x;
int level, bbi, i;
basic_block curr_bb;
- scope root, curr_scope;
+ scope root, curr_scope = 0;
forest->num_trees = 0;
forest->trees = NULL;
for (x = get_insns (); x; x = next)
{
next = NEXT_INSN (x);
- if (GET_CODE (x) == NOTE
- && NOTE_LINE_NUMBER (x) == NOTE_INSN_BASIC_BLOCK)
+ if (NOTE_INSN_BASIC_BLOCK_P (x))
currbb = NOTE_BASIC_BLOCK (x);
if (GET_CODE (x) == NOTE
fprintf (stderr, "%*s", indent, "");
fprintf (stderr, "{ level %d (block %p)\n", s->level,
- NOTE_BLOCK (s->note_beg));
+ (PTR) NOTE_BLOCK (s->note_beg));
fprintf (stderr, "%*s%s", indent, "", "bbs:");
for (i = 0; i < s->num_bbs; i++)
if (n_basic_blocks <= 1)
return;
- /* We do not currently handle correct re-placement of EH notes. */
- for (i = 0; i < n_basic_blocks; i++)
- {
- edge e;
- for (e = BASIC_BLOCK (i)->succ; e ; e = e->succ_next)
- if (e->flags & EDGE_EH)
- return;
- }
-
for (i = 0; i < n_basic_blocks; i++)
BASIC_BLOCK (i)->aux = xcalloc (1, sizeof (struct reorder_block_def));
+ EXIT_BLOCK_PTR->aux = xcalloc (1, sizeof (struct reorder_block_def));
+
build_scope_forest (&forest);
remove_scope_notes ();
for (i = 0; i < n_basic_blocks; i++)
free (BASIC_BLOCK (i)->aux);
+ free (EXIT_BLOCK_PTR->aux);
+
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif