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:
Jan Hubicka 2001-07-25 01:42:40 +02:00 committed by Jan Hubicka
parent 40fc4e6a9f
commit ca9fef16af
4 changed files with 114 additions and 33 deletions

View File

@ -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.

View File

@ -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));

View File

@ -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

View File

@ -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);