aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r--gcc/gcse.c104
1 files changed, 70 insertions, 34 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c
index daac742b8c6..1370be1c349 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -3400,7 +3400,7 @@ find_implicit_sets (void)
count = 0;
FOR_EACH_BB (bb)
/* Check for more than one successor. */
- if (bb->succ && bb->succ->succ_next)
+ if (EDGE_COUNT (bb->succs) > 1)
{
cond = fis_get_condition (BB_END (bb));
@@ -3413,7 +3413,7 @@ find_implicit_sets (void)
dest = GET_CODE (cond) == EQ ? BRANCH_EDGE (bb)->dest
: FALLTHRU_EDGE (bb)->dest;
- if (dest && ! dest->pred->pred_next
+ if (dest && EDGE_COUNT (dest->preds) == 1
&& dest != EXIT_BLOCK_PTR)
{
new = gen_rtx_SET (VOIDmode, XEXP (cond, 0),
@@ -3570,9 +3570,11 @@ static int
bypass_block (basic_block bb, rtx setcc, rtx jump)
{
rtx insn, note;
- edge e, enext, edest;
+ edge e, edest;
int i, change;
int may_be_loop_header;
+ unsigned removed_p;
+ edge_iterator ei;
insn = (setcc != NULL) ? setcc : jump;
@@ -3584,7 +3586,7 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
find_used_regs (&XEXP (note, 0), NULL);
may_be_loop_header = false;
- for (e = bb->pred; e; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, bb->preds)
if (e->flags & EDGE_DFS_BACK)
{
may_be_loop_header = true;
@@ -3592,22 +3594,32 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
}
change = 0;
- for (e = bb->pred; e; e = enext)
+ for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
{
- enext = e->pred_next;
+ removed_p = 0;
+
if (e->flags & EDGE_COMPLEX)
- continue;
+ {
+ ei_next (&ei);
+ continue;
+ }
/* We can't redirect edges from new basic blocks. */
if (e->src->index >= bypass_last_basic_block)
- continue;
+ {
+ ei_next (&ei);
+ continue;
+ }
/* The irreducible loops created by redirecting of edges entering the
loop from outside would decrease effectiveness of some of the following
optimizations, so prevent this. */
if (may_be_loop_header
&& !(e->flags & EDGE_DFS_BACK))
- continue;
+ {
+ ei_next (&ei);
+ continue;
+ }
for (i = 0; i < reg_use_count; i++)
{
@@ -3651,9 +3663,11 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
}
else if (GET_CODE (new) == LABEL_REF)
{
+ edge_iterator ei2;
+
dest = BLOCK_FOR_INSN (XEXP (new, 0));
/* Don't bypass edges containing instructions. */
- for (edest = bb->succ; edest; edest = edest->succ_next)
+ FOR_EACH_EDGE (edest, ei2, bb->succs)
if (edest->dest == dest && edest->insns.r)
{
dest = NULL;
@@ -3670,7 +3684,9 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
if (dest && setcc && !CC0_P (SET_DEST (PATTERN (setcc))))
{
edge e2;
- for (e2 = e->src->succ; e2; e2 = e2->succ_next)
+ edge_iterator ei2;
+
+ FOR_EACH_EDGE (e2, ei2, e->src->succs)
if (e2->dest == dest)
{
dest = NULL;
@@ -3704,9 +3720,12 @@ bypass_block (basic_block bb, rtx setcc, rtx jump)
e->src->index, old_dest->index, dest->index);
}
change = 1;
+ removed_p = 1;
break;
}
}
+ if (!removed_p)
+ ei_next (&ei);
}
return change;
}
@@ -3739,7 +3758,7 @@ bypass_conditional_jumps (void)
EXIT_BLOCK_PTR, next_bb)
{
/* Check for more than one predecessor. */
- if (bb->pred && bb->pred->pred_next)
+ if (EDGE_COUNT (bb->preds) > 1)
{
setcc = NULL_RTX;
for (insn = BB_HEAD (bb);
@@ -3886,12 +3905,13 @@ compute_pre_data (void)
FOR_EACH_BB (bb)
{
edge e;
+ edge_iterator ei;
/* If the current block is the destination of an abnormal edge, we
kill all trapping expressions because we won't be able to properly
place the instruction on the edge. So make them neither
anticipatable nor transparent. This is fairly conservative. */
- for (e = bb->pred; e ; e = e->pred_next)
+ FOR_EACH_EDGE (e, ei, bb->preds)
if (e->flags & EDGE_ABNORMAL)
{
sbitmap_difference (antloc[bb->index], antloc[bb->index], trapping_expr);
@@ -3931,8 +3951,9 @@ static int
pre_expr_reaches_here_p_work (basic_block occr_bb, struct expr *expr, basic_block bb, char *visited)
{
edge pred;
-
- for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (pred, ei, bb->preds)
{
basic_block pred_bb = pred->src;
@@ -4051,7 +4072,8 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
if (JUMP_P (insn)
|| (NONJUMP_INSN_P (insn)
- && (bb->succ->succ_next || (bb->succ->flags & EDGE_ABNORMAL))))
+ && (EDGE_COUNT (bb->succs) > 1
+ || EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL)))
{
#ifdef HAVE_cc0
rtx note;
@@ -4086,13 +4108,13 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
}
#endif
/* FIXME: What if something in cc0/jump uses value set in new insn? */
- new_insn = emit_insn_before (pat, insn);
+ new_insn = emit_insn_before_noloc (pat, insn);
}
/* Likewise if the last insn is a call, as will happen in the presence
of exception handling. */
else if (CALL_P (insn)
- && (bb->succ->succ_next || (bb->succ->flags & EDGE_ABNORMAL)))
+ && (EDGE_COUNT (bb->succs) > 1 || EDGE_SUCC (bb, 0)->flags & EDGE_ABNORMAL))
{
/* Keeping in mind SMALL_REGISTER_CLASSES and parameters in registers,
we search backward and place the instructions before the first
@@ -4124,10 +4146,10 @@ insert_insn_end_bb (struct expr *expr, basic_block bb, int pre)
|| NOTE_INSN_BASIC_BLOCK_P (insn))
insn = NEXT_INSN (insn);
- new_insn = emit_insn_before (pat, insn);
+ new_insn = emit_insn_before_noloc (pat, insn);
}
else
- new_insn = emit_insn_after (pat, insn);
+ new_insn = emit_insn_after_noloc (pat, insn);
while (1)
{
@@ -4810,6 +4832,7 @@ static int
hoist_expr_reaches_here_p (basic_block expr_bb, int expr_index, basic_block bb, char *visited)
{
edge pred;
+ edge_iterator ei;
int visited_allocated_locally = 0;
@@ -4819,7 +4842,7 @@ hoist_expr_reaches_here_p (basic_block expr_bb, int expr_index, basic_block bb,
visited = xcalloc (last_basic_block, 1);
}
- for (pred = bb->pred; pred != NULL; pred = pred->pred_next)
+ FOR_EACH_EDGE (pred, ei, bb->preds)
{
basic_block pred_bb = pred->src;
@@ -6167,7 +6190,7 @@ insert_insn_start_bb (rtx insn, basic_block bb)
before = NEXT_INSN (before);
}
- insn = emit_insn_after (insn, prev);
+ insn = emit_insn_after_noloc (insn, prev);
if (gcse_file)
{
@@ -6188,6 +6211,7 @@ insert_store (struct ls_expr * expr, edge e)
rtx reg, insn;
basic_block bb;
edge tmp;
+ edge_iterator ei;
/* We did all the deleted before this insert, so if we didn't delete a
store, then we haven't set the reaching reg yet either. */
@@ -6204,7 +6228,7 @@ insert_store (struct ls_expr * expr, edge e)
insert it at the start of the BB, and reset the insert bits on the other
edges so we don't try to insert it on the other edges. */
bb = e->dest;
- for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
+ FOR_EACH_EDGE (tmp, ei, e->dest->preds)
if (!(tmp->flags & EDGE_FAKE))
{
int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
@@ -6218,7 +6242,7 @@ insert_store (struct ls_expr * expr, edge e)
insertion vector for these edges, and insert at the start of the BB. */
if (!tmp && bb != EXIT_BLOCK_PTR)
{
- for (tmp = e->dest->pred; tmp ; tmp = tmp->pred_next)
+ FOR_EACH_EDGE (tmp, ei, e->dest->preds)
{
int index = EDGE_INDEX (edge_list, tmp->src, tmp->dest);
RESET_BIT (pre_insert_map[index], expr->index);
@@ -6256,33 +6280,40 @@ insert_store (struct ls_expr * expr, edge e)
static void
remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr)
{
- edge *stack = xmalloc (sizeof (edge) * n_basic_blocks), act;
+ edge_iterator *stack, ei;
+ int sp;
+ edge act;
sbitmap visited = sbitmap_alloc (last_basic_block);
- int stack_top = 0;
rtx last, insn, note;
rtx mem = smexpr->pattern;
+ stack = xmalloc (sizeof (edge_iterator) * n_basic_blocks);
+ sp = 0;
+ ei = ei_start (bb->succs);
+
sbitmap_zero (visited);
- act = bb->succ;
+ act = (EDGE_COUNT (ei.container) > 0 ? EDGE_I (ei.container, 0) : NULL);
while (1)
{
if (!act)
{
- if (!stack_top)
+ if (!sp)
{
free (stack);
sbitmap_free (visited);
return;
}
- act = stack[--stack_top];
+ act = ei_edge (stack[--sp]);
}
bb = act->dest;
if (bb == EXIT_BLOCK_PTR
|| TEST_BIT (visited, bb->index))
{
- act = act->succ_next;
+ if (!ei_end_p (ei))
+ ei_next (&ei);
+ act = (! ei_end_p (ei)) ? ei_edge (ei) : NULL;
continue;
}
SET_BIT (visited, bb->index);
@@ -6310,12 +6341,17 @@ remove_reachable_equiv_notes (basic_block bb, struct ls_expr *smexpr)
INSN_UID (insn));
remove_note (insn, note);
}
- act = act->succ_next;
- if (bb->succ)
+
+ if (!ei_end_p (ei))
+ ei_next (&ei);
+ act = (! ei_end_p (ei)) ? ei_edge (ei) : NULL;
+
+ if (EDGE_COUNT (bb->succs) > 0)
{
if (act)
- stack[stack_top++] = act;
- act = bb->succ;
+ stack[sp++] = ei;
+ ei = ei_start (bb->succs);
+ act = (EDGE_COUNT (ei.container) > 0 ? EDGE_I (ei.container, 0) : NULL);
}
}
}