flow.c (try_simplify_condjump): Avoid duplicated edges.
* flow.c (try_simplify_condjump): Avoid duplicated edges. (verify_flow_info): Check for duplicated edges; clarify error reporting. * flow.c (block_label): Update basic_block_for_insn. (commit_edge_insertions): Call compute_bb_for_insn. * flow.c (purge_dead_edges): Handle conditional jumps and conditional returns too. * flow.c (redirect_edge_and_branch, try_optimize_cfg): Use redirect_edge_succ_nodup (redirect_edge_succ_nodup): New. * basic_block.h (redirect_edge_succ_nodup): Declare. * toplev.c (rest_of_compilation): Rebuild CFG before cfg_cleanup after gcse. From-SVN: r44320
This commit is contained in:
parent
40fc4e6a9f
commit
ca9fef16af
@ -1,3 +1,23 @@
|
||||
Wed Jul 25 01:41:27 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* flow.c (try_simplify_condjump): Avoid duplicated edges.
|
||||
(verify_flow_info): Check for duplicated edges; clarify
|
||||
error reporting.
|
||||
|
||||
* flow.c (block_label): Update basic_block_for_insn.
|
||||
(commit_edge_insertions): Call compute_bb_for_insn.
|
||||
|
||||
* flow.c (purge_dead_edges): Handle conditional jumps and conditional
|
||||
returns too.
|
||||
|
||||
* flow.c (redirect_edge_and_branch,
|
||||
try_optimize_cfg): Use redirect_edge_succ_nodup
|
||||
(redirect_edge_succ_nodup): New.
|
||||
* basic_block.h (redirect_edge_succ_nodup): Declare.
|
||||
|
||||
* toplev.c (rest_of_compilation): Rebuild CFG before cfg_cleanup
|
||||
after gcse.
|
||||
|
||||
Wed Jul 25 00:32:49 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* flow.c (try_forward_edges): Accept fallthru edge; Update comment.
|
||||
|
@ -296,6 +296,7 @@ extern void make_edge PARAMS ((sbitmap *, basic_block,
|
||||
basic_block, int));
|
||||
extern void remove_edge PARAMS ((edge));
|
||||
extern void redirect_edge_succ PARAMS ((edge, basic_block));
|
||||
extern void redirect_edge_succ_nodup PARAMS ((edge, basic_block));
|
||||
extern void redirect_edge_pred PARAMS ((edge, basic_block));
|
||||
extern void create_basic_block PARAMS ((int, rtx, rtx, rtx));
|
||||
extern int flow_delete_block PARAMS ((basic_block));
|
||||
|
124
gcc/flow.c
124
gcc/flow.c
@ -1592,7 +1592,11 @@ block_label (block)
|
||||
if (block == EXIT_BLOCK_PTR)
|
||||
return NULL_RTX;
|
||||
if (GET_CODE (block->head) != CODE_LABEL)
|
||||
block->head = emit_label_before (gen_label_rtx (), block->head);
|
||||
{
|
||||
block->head = emit_label_before (gen_label_rtx (), block->head);
|
||||
if (basic_block_for_insn)
|
||||
set_block_for_insn (block->head, block);
|
||||
}
|
||||
return block->head;
|
||||
}
|
||||
|
||||
@ -1834,22 +1838,7 @@ redirect_edge_and_branch (e, target)
|
||||
fprintf (rtl_dump_file, "Edge %i->%i redirected to %i\n",
|
||||
e->src->index, e->dest->index, target->index);
|
||||
if (e->dest != target)
|
||||
{
|
||||
edge s;
|
||||
/* Check whether the edge is already present. */
|
||||
for (s = src->succ; s; s=s->succ_next)
|
||||
if (s->dest == target)
|
||||
break;
|
||||
if (s)
|
||||
{
|
||||
s->flags |= e->flags;
|
||||
s->probability += e->probability;
|
||||
s->count += e->count;
|
||||
remove_edge (e);
|
||||
}
|
||||
else
|
||||
redirect_edge_succ (e, target);
|
||||
}
|
||||
redirect_edge_succ_nodup (e, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2293,6 +2282,7 @@ commit_edge_insertions ()
|
||||
{
|
||||
int i;
|
||||
basic_block bb;
|
||||
compute_bb_for_insn (get_max_uid ());
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
verify_flow_info ();
|
||||
@ -3076,8 +3066,8 @@ try_simplify_condjump (cbranch_block)
|
||||
/* Success. Update the CFG to match. Note that after this point
|
||||
the edge variable names appear backwards; the redirection is done
|
||||
this way to preserve edge profile data. */
|
||||
redirect_edge_succ (cbranch_jump_edge, cbranch_dest_block);
|
||||
redirect_edge_succ (cbranch_fallthru_edge, jump_dest_block);
|
||||
redirect_edge_succ_nodup (cbranch_jump_edge, cbranch_dest_block);
|
||||
redirect_edge_succ_nodup (cbranch_fallthru_edge, jump_dest_block);
|
||||
cbranch_jump_edge->flags |= EDGE_FALLTHRU;
|
||||
cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
|
||||
|
||||
@ -3820,7 +3810,7 @@ try_optimize_cfg (mode)
|
||||
fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
|
||||
b->index);
|
||||
c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
|
||||
redirect_edge_succ (b->pred, b->succ->dest);
|
||||
redirect_edge_succ_nodup (b->pred, b->succ->dest);
|
||||
flow_delete_block (b);
|
||||
changed = true;
|
||||
b = c;
|
||||
@ -7979,11 +7969,13 @@ verify_flow_info ()
|
||||
const int max_uid = get_max_uid ();
|
||||
const rtx rtx_first = get_insns ();
|
||||
rtx last_head = get_last_insn ();
|
||||
basic_block *bb_info;
|
||||
basic_block *bb_info, *last_visited;
|
||||
rtx x;
|
||||
int i, last_bb_num_seen, num_bb_notes, err = 0;
|
||||
|
||||
bb_info = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
|
||||
last_visited = (basic_block *) xcalloc (n_basic_blocks + 2,
|
||||
sizeof (basic_block));
|
||||
|
||||
for (i = n_basic_blocks - 1; i >= 0; i--)
|
||||
{
|
||||
@ -8040,6 +8032,14 @@ verify_flow_info ()
|
||||
e = bb->succ;
|
||||
while (e)
|
||||
{
|
||||
if (last_visited [e->dest->index + 2] == bb)
|
||||
{
|
||||
error ("verify_flow_info: Duplicate edge %i->%i",
|
||||
e->src->index, e->dest->index);
|
||||
err = 1;
|
||||
}
|
||||
last_visited [e->dest->index + 2] = bb;
|
||||
|
||||
if ((e->flags & EDGE_FALLTHRU)
|
||||
&& e->src != ENTRY_BLOCK_PTR
|
||||
&& e->dest != EXIT_BLOCK_PTR
|
||||
@ -8166,8 +8166,7 @@ verify_flow_info ()
|
||||
basic_block bb = NOTE_BASIC_BLOCK (x);
|
||||
num_bb_notes++;
|
||||
if (bb->index != last_bb_num_seen + 1)
|
||||
/* Basic blocks not numbered consecutively. */
|
||||
abort ();
|
||||
internal_error ("Basic blocks not numbered consecutively.");
|
||||
|
||||
last_bb_num_seen = bb->index;
|
||||
}
|
||||
@ -8213,10 +8212,11 @@ verify_flow_info ()
|
||||
num_bb_notes, n_basic_blocks);
|
||||
|
||||
if (err)
|
||||
abort ();
|
||||
internal_error ("verify_flow_info failed.");
|
||||
|
||||
/* Clean up. */
|
||||
free (bb_info);
|
||||
free (last_visited);
|
||||
}
|
||||
|
||||
/* Functions to access an edge list with a vector representation.
|
||||
@ -8629,6 +8629,29 @@ redirect_edge_succ (e, new_succ)
|
||||
e->dest = new_succ;
|
||||
}
|
||||
|
||||
/* Like previous but avoid possible dupplicate edge. */
|
||||
|
||||
void
|
||||
redirect_edge_succ_nodup (e, new_succ)
|
||||
edge e;
|
||||
basic_block new_succ;
|
||||
{
|
||||
edge s;
|
||||
/* Check whether the edge is already present. */
|
||||
for (s = e->src->succ; s; s = s->succ_next)
|
||||
if (s->dest == new_succ && s != e)
|
||||
break;
|
||||
if (s)
|
||||
{
|
||||
s->flags |= e->flags;
|
||||
s->probability += e->probability;
|
||||
s->count += e->count;
|
||||
remove_edge (e);
|
||||
}
|
||||
else
|
||||
redirect_edge_succ (e, new_succ);
|
||||
}
|
||||
|
||||
/* Redirect an edge's predecessor from one block to another. */
|
||||
|
||||
void
|
||||
@ -9794,21 +9817,56 @@ purge_dead_edges (bb)
|
||||
return;
|
||||
if (GET_CODE (insn) == JUMP_INSN)
|
||||
{
|
||||
int removed = 0;
|
||||
rtx note;
|
||||
edge b,f;
|
||||
/* We do care only about conditional jumps and simplejumps. */
|
||||
if (!any_condjump_p (insn)
|
||||
&& !returnjump_p (insn)
|
||||
&& !simplejump_p (insn))
|
||||
return;
|
||||
for (e = bb->succ; e; e = next)
|
||||
{
|
||||
next = e->succ_next;
|
||||
if (e->dest == EXIT_BLOCK_PTR || e->dest->head != JUMP_LABEL (insn))
|
||||
remove_edge (e);
|
||||
}
|
||||
if (bb->succ && bb->succ->succ_next)
|
||||
abort ();
|
||||
if (!bb->succ)
|
||||
return;
|
||||
bb->succ->probability = REG_BR_PROB_BASE;
|
||||
bb->succ->count = bb->count;
|
||||
|
||||
/* Check purposes we can have edge. */
|
||||
if ((e->flags & EDGE_FALLTHRU)
|
||||
&& any_condjump_p (insn))
|
||||
continue;
|
||||
if (e->dest != EXIT_BLOCK_PTR
|
||||
&& e->dest->head == JUMP_LABEL (insn))
|
||||
continue;
|
||||
if (e->dest == EXIT_BLOCK_PTR
|
||||
&& returnjump_p (insn))
|
||||
continue;
|
||||
removed = 1;
|
||||
remove_edge (e);
|
||||
}
|
||||
if (!bb->succ || !removed)
|
||||
return;
|
||||
if (rtl_dump_file)
|
||||
fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
|
||||
if (!optimize)
|
||||
return;
|
||||
|
||||
/* Redistribute probabilities. */
|
||||
if (!bb->succ->succ_next)
|
||||
{
|
||||
bb->succ->probability = REG_BR_PROB_BASE;
|
||||
bb->succ->count = bb->count;
|
||||
}
|
||||
else
|
||||
{
|
||||
note = find_reg_note (insn, REG_BR_PROB, NULL);
|
||||
if (!note)
|
||||
return;
|
||||
b = BRANCH_EDGE (bb);
|
||||
f = FALLTHRU_EDGE (bb);
|
||||
b->probability = INTVAL (XEXP (note, 0));
|
||||
f->probability = REG_BR_PROB_BASE - b->probability;
|
||||
b->count = bb->count * b->probability / REG_BR_PROB_BASE;
|
||||
f->count = bb->count * f->probability / REG_BR_PROB_BASE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* If we don't see a jump insn, we don't know exactly why the block would
|
||||
|
@ -3060,6 +3060,8 @@ rest_of_compilation (decl)
|
||||
tem = tem2 = 0;
|
||||
timevar_push (TV_JUMP);
|
||||
rebuild_jump_labels (insns);
|
||||
delete_trivially_dead_insns (insns, max_reg_num (), 0);
|
||||
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
|
||||
cleanup_cfg (CLEANUP_EXPENSIVE);
|
||||
timevar_pop (TV_JUMP);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user